
この記事では
といった悩みや疑問を抱えている人に向けて、
- ナンピンマーチンとは何か
- ナンピンマーチン手法の紹介
- Wナンピンマーチン手法のバックテスト結果公開
- ナンピンマーチン手法のコードとEAを無料でプレゼント
を解説します。
平均取得価格をポジションを増やすことで引き下げる手法
例えば、ドル円を150円で購入した後、価格が148円に下落した際にさらに購入することで、平均取得価格を149円に引き下げることができます。
148円でナンピン買いを行わなかった場合は、平均取得単価は150円のままなので価格が150円以下では損益はマイナスです。
一方で、ナンピンによって平均取得単価が149円にすれば、150円に比べて損益がプラスになるハードルを低くすることができるだけでなく、リターンが大きくなります。
ナンピンは、短期・長期の値動きを狙うトレーダー両方に向いていますが、無計画にナンピンを続けると、資金が枯渇する危険性があるため、リスク管理が不可欠です。
事前に損切りラインを決めて、計画的にナンピンを行うことが重要です。
負けたときに次の取引で賭け金を倍にすることで、最初の負けを一回で取り戻そうとする手法
この手法はもともとカジノで使われていたものですが、FX取引でも広く利用されています。
具体的には、最初に1ロットで取引して負けた場合、次は2ロット、さらに負ければ4ロットと倍々に取引量を増やしていきます。
マーチンゲールは、特に短期的なトレードで利用されることが多いです。
相場が一定の範囲内で上下動を繰り返すレンジ相場の場合に威力を発揮する資金管理法です。
項目 | ダランベール法 | モンテカルロ法 | 逆マーチンゲール(パーレー法) | ピラミッディング |
---|---|---|---|---|
手法 | 勝ったときに賭け金を減らし、負けたときに賭け金を増やす | 勝ち負けの結果に基づいて賭け金を調整する | 勝ったときに賭け金を倍にする | ポジションに含み益が発生した際に追加ポジションを取る |
特徴 | リスク管理が容易で、負けが続いても賭け金の増加が緩やか | 連敗時に賭け金を増やすことで損失を取り戻すことを目指すが、連勝時には賭け金を減らす | 連勝が続くと利益が急増するが、負けた場合の損失は限定的 | 利益が出ているときのみ追加ポジションを持つため、利益の最大化が図れる |
具体例 | 最初に1ロットを賭けて150円でドル円を買いエントリー。149円に下落して損切。148円に下落したので2ロットエントリー。149円に上昇して決済。149円から1ロット売りエントリー、148円でポジション決済。 | 基本的にはダランベール法と同じように損切でロットを増やし、利確でロットを少なくする。詳細は後述します。 | 最初に1ロットを150円でドル円を買いエントリー。151円に上昇した場合、次は2ロットを追加。152円に上昇した場合、さらに4ロットを追加。価格が153円に上昇した際に全ポジション決済 | 最初に1ロットを150円でドル円を買いエントリー。151円に上昇した場合に1ロット追加。152円に上昇した場合にさらに1ロット追加。価格が153円に上昇した際に全ポジション決済 |
モンテカルロ法は[1,2,3]という数列から始まります。
取引するロットは両端を足した数字です。この場合は4ということになります。
(※必ず4ロットである必要はありません。例えば最初は1ロットにしたい場合はモンテカルロ法によって計算される値を1/4すれば大丈夫です。)
そして、取引で「勝てば数列の両端を消す・負ければ賭け金額を数列に追加する」を繰り返し、数列がなくなるか1個になるまで賭けを続けます。
数列が1個以下になった段階では多くの場合で利益が出る資金管理法です。
勝率は50%だが、トータル +0.75(=-1-1.25+1.5+1.5)ロット分プラス収支になる
相場が逆行した際に追加購入を行うことで、平均取得価格を下げることが最大のメリットです。
これにより、相場が少し戻っただけでも利益を出しやすくなります。
例えば、ドル円を110円で購入した後、価格が109円に下落した際にナンピンを行うと、平均取得価格は109.5円となり、価格が109.5円を超えた時点で利益を得ることができます。
比較的短期的な値動きに対する対応に向いています。
ナンピンマーチンは、短期的な値動きに強いという特長があります。
市場は日々変動し、短期的な上下動を繰り返しながら均衡価格に近づきます。
上下動の繰り返しを利用して、逆行した際にナンピンを行い、その後の反発で利益を確定するという戦略が取れます。これによって、長期的な投資戦略に比べて迅速に利益を得るチャンスが多くなります。
ナンピンマーチンの最大のデメリットは、一度の損失が大きくなりやすいことです。
相場が逆行するたびにポジションを追加するため、さらに逆行した場合、損失が雪だるま式に増えていきます。最悪の場合には資金が枯渇し、大きな損失が発生するリスクが高いです。
損失を最小限に抑えるためには、事前に明確な損切りラインを設定し、相場が設定したラインに達した場合には冷静に損切りを行うことが重要です。
無理な追加ポジションを避け、リスク管理を徹底することが求められます。
計画的なトレードを行い、感情に左右されないことが成功の鍵です。
ナンピンマーチンで利益が出だすと、「ナンピンすればいいからとりあえずロング」と根拠のないエントリーが増え、エントリーした結果、含み損が増え「次こそ反転する」、「これで最後」と無限にナンピンを繰り返し、全損する人が多いです。
このような計画性のないトレードを避けるために、「ナンピンは計画的に」を心に刻んでトレードしましょう。
事前に明確なトレードルールを設定し、それに従って厳格にトレードを行うことが必要です。
相場が一定の割合で下落した際にのみナンピンを行う、あるいは損切りラインを設定してそこに達した場合には必ず損切りを行うといったルールを設け、計画性のないトレードをしないことが重要です。
まずナンピンマーチンのロジックを作るために、エントリー条件とエグジット条件を設定します。
ここではシンプルに移動平均線を利用したロジックにしたいと思います。
検証ロジック
①4時間足の20SMAと75SMAのゴールデンクロス・デッドクロスでエントリー・イグジット
②ポジションを保有したら-30pipsごとに2倍のロットでナンピンマーチン
※最大ポジション数 20 (現実にはロットと証拠金の関係上、15ポジションが限度)
ナンピンマーチンのロジックを実装するためのmql4コードは以下の通りです。
//mql4
input int MAGIC = 2024; // 基本マジックナンバー(複数稼働する場合は各々違う番号を指定)
input double SlippagePips = 10; // 許容スリッページ(pips)
input double Lots = 1; // 売買ロット数
input double MartingaleMultiplier = 2.0; // ナンピン時のロット倍率
input double MartingaleStepPips = 30; // ナンピンの間隔(pips)
input int MaxPositions = 10; // 最大ポジション数
double PipPoint;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit() {
cal_PipPoint();
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick() {
static datetime lastOrderTime = 0;
if (TimeCurrent() - lastOrderTime < 60) return; // 1分ごとにチェック
double sma20 = iMA(NULL, PERIOD_H4, 20, 0, MODE_SMA, PRICE_CLOSE, 0);
double sma75 = iMA(NULL, PERIOD_H4, 75, 0, MODE_SMA, PRICE_CLOSE, 0);
int currentPosition = OpendOrderCheck();
if (currentPosition == 0) {
if (sma20 > sma75) {
position_entry(OP_BUY, Lots);
} else if (sma20 < sma75) {
position_entry(OP_SELL, Lots);
}
} else {
manage_positions(sma20, sma75, currentPosition);
}
lastOrderTime = TimeCurrent();
}
//+------------------------------------------------------------------+
//| Position entry function |
//+------------------------------------------------------------------+
void position_entry(int orderType, double lots) {
double price = (orderType == OP_BUY) ? Ask : Bid;
double slippage = SlippagePips * PipPoint;
double tp_price = 0;
double sl_price = 0;
if (OrderSend(Symbol(), orderType, lots, price, slippage, sl_price, tp_price, "", MAGIC, 0, clrBlue) > 0) {
Print("Entry successful: ", orderType == OP_BUY ? "Buy" : "Sell");
} else {
Print("Entry failed: ");
}
}
//+------------------------------------------------------------------+
//| Manage positions function |
//+------------------------------------------------------------------+
void manage_positions(double sma20, double sma75, int currentPosition) {
int totalPositions = OrdersTotal();
double price = (currentPosition == 1) ? Ask : Bid;
double slippage = SlippagePips * PipPoint;
double lastEntryPrice = 0;
for (int i = totalPositions - 1; i >= 0; i--) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MAGIC) {
lastEntryPrice = OrderOpenPrice();
break;
}
}
if (currentPosition == 1 && sma20 < sma75) {
All_settle();
} else if (currentPosition == -1 && sma20 > sma75) {
All_settle();
} else if (totalPositions < MaxPositions) {
double distance = (currentPosition == 1) ? (lastEntryPrice - price) / PipPoint:(price - lastEntryPrice) / PipPoint;
if (distance >= MartingaleStepPips) {
double lots = OrderLots() * MartingaleMultiplier;
position_entry(currentPosition == 1 ? OP_BUY : OP_SELL, lots);
}
}
}
//+------------------------------------------------------------------+
//| Close all positions function |
//+------------------------------------------------------------------+
void All_settle() {
int totalPositions = OrdersTotal();
for (int i = totalPositions - 1; i >= 0; i--) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES) && OrderMagicNumber() == MAGIC) {
double close_price = (OrderType() == OP_BUY) ? Bid : Ask;
if (!OrderClose(OrderTicket(), OrderLots(), close_price, SlippagePips * PipPoint, clrRed)) {
Print("Failed to close position: ");
}
}
}
}
//+------------------------------------------------------------------+
//| Opened order check function |
//+------------------------------------------------------------------+
int OpendOrderCheck() {
int totalPositions = OrdersTotal();
int buy = 0, sell = 0;
for (int i = totalPositions - 1; i >= 0; i--) {
if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
if (OrderType() == OP_BUY && OrderSymbol() == Symbol() && OrderMagicNumber() == MAGIC) {
buy++;
}
if (OrderType() == OP_SELL && OrderSymbol() == Symbol() && OrderMagicNumber() == MAGIC) {
sell++;
}
}
}
if (buy > 0 && sell == 0) return 1;
if (sell > 0 && buy == 0) return -1;
return 0;
}
//+------------------------------------------------------------------+
//| Calculate pip point function |
//+------------------------------------------------------------------+
void cal_PipPoint() {
if (Digits == 2 || Digits == 4) PipPoint = Point;
if (Digits == 3 || Digits == 5) PipPoint = Point * 10;
}
実際にEAを使用してナンピンマーチンのバックテスト(2020~2023、ドル円)を検証を行った結果、最大のポジション数は12、初期ロットを0.01として検証したため、最大ロットは20.48Lotとなりました。資金管理次第では超単純なロジックでもナンピンマーチンを組み込めばそれなりになんとかなる可能性があります。
さらに損切などのロジックを組み込んでリスクを限定すれば、十分実運用できるものができそうです。
ナンピンマーチンは、一度のトレードで大きな損失が発生するリスクがある一方でうまく活用すれば資金を効率よく増やせる手段の一つです。
ロット(掛け額)の掛け方はマーチンゲール法のほかにもダランベール法やモンテカルロ法など面白そうな方法があります。
実際にゴトー日のロジックにモンテカルロ法によるロット管理を組み込んだEAを作成しましたので、興味がある方は以下からダウンロードしてみてください。
最後に繰り返しになりますが、ナンピンは計画性のないトレードになりやすいため、明確なルール設定とリスク管理を忘れずにトレードしましょう。