この連載は研究用です。 読み物として楽しんでもらえれば。番外編なので読まなくてよいw
前回のおさらい
第5回の①同時両建て型は、線に触れるたびに買いと売りを両方建てる型でした。勝った側をすぐ利食いするので、一方向に走ると負けた側だけが残り、含み損込みの資産は 5,925 USD まで沈みました。
番外編の2つ目は ③段階ヘッジ型 です。最初は片側だけで入り、ナンピンしていって、決まった本数になったら反対の玉を足します。
第6回:決まった本数で、反対の玉を足す
| 項目 | 設定 |
|---|---|
| 最初の1本 | 第1回と同じ ADX(1分足と30分足で ADX(14)≥22、DI の向きがそろったらその向き。0.01ロット) |
| 足す | 最初の1本から 5ドル逆行するごとに、同じ向き・同じロットで1本。最大 10本 |
| 反対の玉 | 同じ向きの玉が 5本目と 7本目になったところで、反対向きを1本ずつ(0.01ロット) |
| 反対の玉の決済 | 建てた線から 5ドル戻ったら決済(ほぼ −5ドル)。また線まで来たら建て直す |
| まとめて決済 | そのサイクルの決済済みの損益と、残っている玉の含み損益(スワップ込み)の合計が +5ドル以上で全部決済 |
第2回のロックや第4回のサブ玉と違うのは、反対の玉を「本数」で決めて足すところです。

反対の玉は、逆行が続いている間は含み損の増え方を抑えます。でも、価格が戻るとその玉が損を出して決済され、また逆行すると建て直されます。
結果:55回中54回はプラス、1回が最後まで終わらなかった
条件は第0回の表のとおりです(XAUUSD、2025-01-01〜2026-07-01、リアルティック、0.01ロット、初期証拠金 50,000 USD)。
| 項目 | 第5回(同時両建て型) | 第6回(段階ヘッジ型) |
|---|---|---|
| 1サイクル(始めてから全部決済まで) | 28回 | 55回 |
| うちプラスで終わったサイクル | 27回(合計 +142 USD) | 54回(合計 +283 USD) |
| 決済した回数 | 964回(勝率 89%) | 138回(勝率 64%) |
| 損益合計 | −11,973 USD | −10,055 USD |
| 最大DD(含み損込み) | −46,647 USD | −23,087 USD |
| 含み損込みの一番低いところ | 5,925 USD(2026-01-29) | 27,192 USD(2026-01-29) |
| 同時に持った玉 | 最大20本・0.20ロット | 最大12本・0.12ロット |
| 試行回数 N | 27 | 28 |
| DSR | 0.006(N=100 換算 0.001) | 0.002(N=100 換算 0.000) |

確定した残高(黒)は、最初の3週間で少し増えたあとは、テスト終了までほとんど動いていません。止まっていたからです。含み損込み(灰色)は2025年1月から下がり始め、2026年1月29日に 27,192 USD まで沈みました。テスト終了で残った玉を強制決済すると、残高は 50,265 USD から 39,945 USD に落ちました。
第5回の図と形がよく似ていますが、別モノです。どちらも2025年の初めから売りの玉を抱えたまま最後まで終わらず、含み損込みの資産が「Goldの値動きの裏返し」になったので、同じ形になりました(一番低かった日も同じ2026年1月29日)。抱えていた売りの量が、第5回は差し引き0.20ロット、今回は0.08ロットだったので、振れ幅は第5回の半分以下です。縦軸の目盛りが違うので、見比べるときは注意してください。
何が起きたか:1月20日に始まって、21日に止まった
最初の3週間で54回のサイクルが +5ドル前後で終わりました。玉が9本まで増えたサイクルも2回ありましたが、どちらも戻ってきてプラスで終わっています。
55回目のサイクルは、2025-01-20 の深夜に 売り(2,693.57)で始まりました。ここからGoldが上がり始めます。
| 時点 | 起きたこと |
|---|---|
| 1月20日 | 5ドルごとに売りを足し、5本目(2,713台)で反対の買いを1本 |
| 1月20〜21日 | 価格が戻るたびに買いが −5.6〜−6.1ドルで決済され、上がるとまた建て直す |
| 1月21日 | 7本目で2本目の買い。売りは 2,738.57 で10本目に到達 |
| 1月21日 16:59 | 最後の約定。ここから先、このサイクルでは何も起きない |
10本の上限に届き、反対の買いも2本とも持ったままなので、新しく建てる条件も決済する条件も来ません。このまま1年5か月、テスト終了まで止まっていました。その間にGoldは 2,700ドル台から 4,000ドル前後まで上がっています。
最後に残っていたのは、売り10本と買い2本、差し引き 売り0.08ロット です。
| 強制決済した玉 | 損益 | うちスワップ |
|---|---|---|
| 売り10本 | −12,915 USD | +736 USD |
| 買い2本 | +2,575 USD | −716 USD |
| このサイクルの合計 | −10,338 USD |
(スワップの向きと大きさは業者や時期で変わるので、ここは割り引いて見てください。)
反対の買いは、全期間で14回建てて、途中で決済した12回の合計が −66 USD でした。最後まで残った2本は +2,575 USD を稼いでいますが、売り10本の損を埋めるには、本数が足りませんでした。
第5回と比べると
含み損込みの一番低いところは、第5回の 5,925 USD に対して 27,192 USD。沈み方は半分ほどです。違いは本数の上限で、同じ向きの玉が10本、反対の玉が2本までなので、差し引きで持てる量は最大 0.08ロットに抑えられています。
ただ、損益合計はほぼ同じ −10,000 USD 前後です。そして、どちらも1月〜2月の上げの入り口で始まったサイクルが1本、最後まで終わらなかったことが損のほぼすべてです。止まった理由は違っても(第5回は上限20本の売り、今回は上限10本の売りと反対の買い2本)、結果の形は同じでした。
第6回のまとめ
- 段階ヘッジ型は、決まった本数(5本目と7本目)で反対の玉を足す。逆行中は含み損の増え方を抑えるが、戻ると反対の玉が損切りされる
- 今回の期間では、2025年1月20日に売りで始まったサイクルが、翌日に上限の10本に届いて止まり、最後まで終わらなかった
- 上限があるので、沈み方は第5回の半分ほど。でも損益合計はほぼ同じだった
- 上限は損の深さを決めるが、損が出るかどうかは決めない
次回
番外編の3つ目は、④挟み直し型です。上下に逆指値を置いて価格を挟み、負けた側の玉を少しずつ削っていく型です。
試行回数について
今回は N=28 です。第5回(N=27)の続きで数えています。
ソースコード
研究用です。リアル口座では使わないでください。ログ出力の hg_log.mqh は第1回と同じです。ファイル名の番号(HG09)は作った順の通し番号で、回の番号とはずれています。
HG09_Staged.mq5
//+------------------------------------------------------------------+
//| HG09_Staged.mq5 |
//| Hedged Grid series, chapter 8 (extra): type 3, staged hedge |
//| Entry : same as HG01 (ADX on M1 and M30, DI direction agrees) |
//| Adds : every InpStep against the first position, add one more in |
//| the same direction (same lot), up to InpMaxMain positions. |
//| Hedge : when the InpHedgeAt1-th (InpHedgeAt2-th) add level is hit,|
//| open one opposite position of the same lot. Close it when |
//| price comes back InpStep from its trigger level (it may |
//| open again later). |
//| Exit : close everything when the cycle result (closed profit of |
//| this cycle + floating profit incl. swap) reaches |
//| InpBasketTarget. |
//| Research code for the fxwolf2.com blog. Not for live trading. |
//+------------------------------------------------------------------+
#property copyright "fxwolf2.com"
#property version "1.00"
#property strict
#include <Trade\Trade.mqh>
#include "hg_log.mqh"
input double InpLot = 0.01; // Lot size
input int InpAdxPeriodM1 = 14; // ADX period (M1)
input double InpAdxLevelM1 = 22.0; // ADX threshold (M1)
input int InpAdxPeriodHTF = 14; // ADX period (higher timeframe)
input double InpAdxLevelHTF = 22.0; // ADX threshold (higher timeframe)
input ENUM_TIMEFRAMES InpHTF = PERIOD_M30; // Higher timeframe
input double InpStep = 5.0; // Distance between adds (USD)
input int InpMaxMain = 10; // Max positions in the entry direction
input int InpHedgeAt1 = 5; // First hedge at this many main positions
input int InpHedgeAt2 = 7; // Second hedge at this many main positions
input double InpBasketTarget = 5.0; // Close all when the cycle result reaches this (USD)
input long InpMagic = 260809; // Magic number
input string InpTag = "ch08"; // Log file tag
CTrade trade;
int hAdxM1 = INVALID_HANDLE, hAdxHTF = INVALID_HANDLE;
datetime lastEntryBar = 0;
int dir = 0, nMain = 0; // cycle direction (1=buy, -1=sell) and main positions opened
double anchor = 0, bal0 = 0;
ulong hedge[2] = {0, 0};
int OnInit()
{
hAdxM1 = iADX(_Symbol, PERIOD_M1, InpAdxPeriodM1);
hAdxHTF = iADX(_Symbol, InpHTF, InpAdxPeriodHTF);
if(hAdxM1 == INVALID_HANDLE || hAdxHTF == INVALID_HANDLE) return INIT_FAILED;
trade.SetExpertMagicNumber(InpMagic);
trade.SetTypeFillingBySymbol(_Symbol);
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason)
{
HGLog_Deinit(InpTag);
}
int AdxSide(const int handle, const double level)
{
double adx[1], plus[1], minus[1];
if(CopyBuffer(handle, 0, 1, 1, adx) != 1) return 0;
if(CopyBuffer(handle, 1, 1, 1, plus) != 1) return 0;
if(CopyBuffer(handle, 2, 1, 1, minus) != 1) return 0;
if(adx[0] < level) return 0;
if(plus[0] > minus[0]) return 1;
if(minus[0] > plus[0]) return -1;
return 0;
}
int Scan(double &floating)
{
int n = 0;
floating = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong t = PositionGetTicket(i);
if(t == 0 || PositionGetString(POSITION_SYMBOL) != _Symbol
|| PositionGetInteger(POSITION_MAGIC) != InpMagic) continue;
n++;
floating += PositionGetDouble(POSITION_PROFIT) + PositionGetDouble(POSITION_SWAP);
}
return n;
}
void CloseAll()
{
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong t = PositionGetTicket(i);
if(t > 0 && PositionGetString(POSITION_SYMBOL) == _Symbol
&& PositionGetInteger(POSITION_MAGIC) == InpMagic) trade.PositionClose(t);
}
}
bool Open(const int side, const MqlTick &tick, const string what)
{
string c = StringFormat("HG09 %s sp=%.2f", what, tick.ask - tick.bid);
if(side == 1) return trade.Buy(InpLot, _Symbol, tick.ask, 0, 0, c);
return trade.Sell(InpLot, _Symbol, tick.bid, 0, 0, c);
}
void OnTick()
{
HGLog_OnTick();
MqlTick tick;
if(!SymbolInfoTick(_Symbol, tick)) return;
double p = tick.bid;
double floating;
int n = Scan(floating);
if(n > 0)
{
if(AccountInfoDouble(ACCOUNT_BALANCE) - bal0 + floating >= InpBasketTarget)
{
CloseAll();
return;
}
// Adds in the entry direction, against the move
if(nMain < InpMaxMain)
{
double lvl = anchor - dir * nMain * InpStep;
if((dir == 1 && p <= lvl) || (dir == -1 && p >= lvl))
if(Open(dir, tick, StringFormat("add%d", nMain + 1))) nMain++;
}
// Staged hedges
int at[2];
at[0] = InpHedgeAt1; at[1] = InpHedgeAt2;
for(int i = 0; i < 2; i++)
{
double trig = anchor - dir * (at[i] - 1) * InpStep;
if(hedge[i] == 0)
{
if(nMain >= at[i] && ((dir == 1 && p <= trig) || (dir == -1 && p >= trig)))
if(Open(-dir, tick, StringFormat("hedge%d", i + 1))) hedge[i] = trade.ResultOrder();
}
else
{
double stop = trig + dir * InpStep;
if((dir == 1 && p >= stop) || (dir == -1 && p <= stop))
if(trade.PositionClose(hedge[i])) hedge[i] = 0;
}
}
return;
}
// Flat: at most one new entry per M1 bar
datetime bar = iTime(_Symbol, PERIOD_M1, 0);
if(bar == lastEntryBar) return;
int side = AdxSide(hAdxM1, InpAdxLevelM1);
if(side == 0 || AdxSide(hAdxHTF, InpAdxLevelHTF) != side) return;
bal0 = AccountInfoDouble(ACCOUNT_BALANCE);
if(Open(side, tick, "entry"))
{
lastEntryBar = bar;
dir = side; nMain = 1; hedge[0] = 0; hedge[1] = 0;
anchor = p;
}
}

コメント