この連載は研究用です。 読み物として楽しんでもらえれば。番外編なので読まなくてよいw
前回のおさらい
第7回の④挟み直し型は、ロットを増やさずに、勝った側の利益で負けた側を少しずつ削る型でした。2025年1月6日に残った売り0.05ロットが初日のうちに削れなくなり、最後まで残りました。
番外編の最後は ⑥ゾーン・リカバリー型 です。挟み直し型とは逆に、負けるたびにロットを大きくします。
第8回:2本の線の間を行き来するたびに、2倍で反対に建てる
| 項目 | 設定 |
|---|---|
| 最初の1本 | 第1回と同じ ADX(1分足と30分足で ADX(14)≥22、DI の向きがそろったらその向き。0.01ロット) |
| 2本の線 | 入った価格が1本目の線。そこから入った向きと逆へ 5ドルのところが2本目の線 |
| 反対に建てる | 価格が反対側の線をまたぐたびに、前の玉の 2倍のロットで、前と反対向きに1本 |
| 上限 | 1サイクル 8本まで(0.01 → 0.02 → 0.04 … → 1.28ロット)。8本建てたら、あとは待つ(損切りはしない) |
| まとめて決済 | そのサイクルの決済済みの損益と、残っている玉の含み損益(スワップ込み)の合計が +5ドル以上で全部決済 |

最後に建てた玉がいちばん大きいので、どちらかの線の外へ抜ければ、その玉の利益でそれまでの負けを埋められる、という考え方です。
結果:3か月半で口座がなくなった
条件は第0回の表のとおりです(XAUUSD、2025-01-01〜2026-07-01、リアルティック、最初のロット 0.01、初期証拠金 50,000 USD)。
| 項目 | 第7回(挟み直し型)0.01ロット換算 | 第8回(ゾーン・リカバリー型) |
|---|---|---|
| 1サイクル(始めてから全部決済まで) | 6回 | 55回 |
| うちプラスで終わったサイクル | 5回(合計 +25 USD) | 54回(合計 +288 USD) |
| 決済した回数 | 482回(勝率 98%) | 133回(勝率 65%) |
| 損益合計 | −407 USD | −50,032 USD |
| 最大DD(含み損込み) | −1,550 USD | −50,312 USD |
| 含み損込みの一番低いところ | 初期証拠金から −456 USD | −39 USD(2025-04-16、口座がなくなった) |
| 同時に持った玉 | 0.02ロット | 最大8本・2.55ロット |
| 試行回数 N | 29 | 30 |
| DSR | 0.000 | 0.000(N=100 換算 0.000) |

最初の3週間で54回のサイクルが +5ドル前後で終わり、残高は 50,267 USD まで増えました。8本目まで建てたサイクルは、それまで1回もありません。7本目まで行ったサイクルは3回ありましたが、どれも抜けて +5ドルで終わっています。
そして55回目のサイクルが、テストを終わらせました。
何が起きたか:1月20日の12時間
2025-01-20 08:46、Goldが2,710.94ドルのところで買いから入りました。2本目の線は5ドル下の2,705.94ドル付近です。この日、Goldはこの2本の線の間を、ちょうど行き来しました。
| 時刻(サーバー時間) | 建てた玉 | 価格 |
|---|---|---|
| 08:46 | 買い 0.01 | 2,710.94 |
| 09:20 | 売り 0.02 | 2,705.53 |
| 13:08 | 買い 0.04 | 2,710.84 |
| 13:33 | 売り 0.08 | 2,705.44 |
| 16:08 | 買い 0.16 | 2,710.97 |
| 17:02 | 売り 0.32 | 2,705.41 |
| 21:00 | 買い 0.64 | 2,711.97 |
| 21:25 | 売り 1.28 | 2,705.47 |
12時間半で8本。最後の玉は 1.28ロットで、最初の玉の128倍です。合わせると、買い0.85ロット・売り1.70ロット、差し引き 売り0.85ロット になりました。
このサイクルを +5ドルで終えるには、Goldが 2,699ドル付近まで下がる必要がありました。2本目の線から、さらに7ドルほど下です。
Goldはそこへは戻りませんでした。1月20日の夜から上がり始め、4月には3,200ドル台に乗ります。売り0.85ロットは、Goldが1ドル上がるごとに 85 USD ずつ損が増えます。3か月で550ドル上がり、含み損込みの資産はゼロに向かって下がり続けました。
2025-04-16 03:01、証拠金が足りなくなって強制ロスカットになり、テストもそこで終わりました。最後の残高は −32 USD です。
| 強制決済した玉 | ロット | 損益(スワップ込み) |
|---|---|---|
| 買い4本 | 0.85 | +41,243 USD |
| 売り4本 | 1.70 | −91,548 USD |
| このサイクルの合計 | −50,320 USD |
(スワップの向きと大きさは業者や時期で変わるので、ここは割り引いて見てください。)
番外編を通して見ると
| 回 | 型 | 損益合計 | 最後まで残ったサイクルの始まり |
|---|---|---|---|
| 第5回 | ①同時両建て型 | −11,973 USD | 2025-02-03 |
| 第6回 | ③段階ヘッジ型 | −10,055 USD | 2025-01-20 |
| 第7回 | ④挟み直し型(0.01ロット換算) | −407 USD | 2025-01-06 |
| 第8回 | ⑥ゾーン・リカバリー型 | −50,032 USD(口座がなくなった) | 2025-01-20 |
4つとも、勝ち方は「小さなサイクルをたくさん」で、負け方は「終わらないサイクル1本」でした。そして4つとも、その1本は2025年1〜2月、Goldが上がり始めた入り口(2,600〜2,900ドル台)で始まっています。
違ったのは、その1本が抱えた量です。ロットを増やさない挟み直し型がいちばん浅く、2倍ずつ増やすゾーン・リカバリー型だけが口座を使い切りました。
第8回のまとめ
- ゾーン・リカバリー型は、2本の線をまたぐたびに2倍のロットで反対に建て、どちらかに抜けたら全体で +5ドルを取る
- 今回の期間では、2025年1月20日にGoldがちょうど5ドルの幅を行き来し、12時間半で8本・2.55ロットまで建った
- 差し引き売り0.85ロットが残り、Goldの上昇で3か月後に口座がなくなった
- ロットを増やす型は、終わらないサイクルが1本来たときの損を、何倍にも大きくする
次回
次回は、ここまでの結果をもう一度ふりかえって、別のやり方と比べます。タイトルは「損切り+再エントリーと比べる」です。
試行回数について
今回は N=30 です。第7回(N=29)の続きで数えています。
ソースコード
研究用です。リアル口座では使わないでください。ログ出力の hg_log.mqh は第1回と同じです。ファイル名の番号(HG11)は作った順の通し番号で、回の番号とはずれています。
HG11_ZoneRecovery.mq5
//+------------------------------------------------------------------+
//| HG11_ZoneRecovery.mq5 |
//| Hedged Grid series, chapter 10 (extra): type 6, zone recovery |
//| Entry : same as HG01 (ADX on M1 and M30, DI direction agrees). |
//| The entry price is one edge of the zone, the other edge |
//| is InpZone against the entry direction. |
//| Zone : each time price crosses to the other edge, open the |
//| opposite direction with the previous lot x InpMult, up to |
//| InpMaxLevels positions (then wait, no stop loss). |
//| 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; // First lot
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 InpZone = 5.0; // Zone width (USD)
input double InpMult = 2.0; // Lot multiplier for each new level
input int InpMaxLevels = 8; // Max positions in a cycle
input double InpBasketTarget = 5.0; // Close all when the cycle result reaches this (USD)
input long InpMagic = 260811; // Magic number
input string InpTag = "ch10"; // Log file tag
CTrade trade;
int hAdxM1 = INVALID_HANDLE, hAdxHTF = INVALID_HANDLE;
datetime lastEntryBar = 0;
int dir = 0, nLevels = 0, lastSide = 0; // cycle direction, positions opened, side of the last one
double anchor = 0, bal0 = 0, lastLot = 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 double lot, const MqlTick &tick, const string what)
{
string c = StringFormat("HG11 %s sp=%.2f", what, tick.ask - tick.bid);
if(side == 1) return trade.Buy(lot, _Symbol, tick.ask, 0, 0, c);
return trade.Sell(lot, _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;
}
if(nLevels >= InpMaxLevels) return;
// The entry edge is anchor, the other edge is InpZone against the entry direction
double other = anchor - dir * InpZone;
bool cross;
if(lastSide == dir) cross = (dir == 1) ? (p <= other) : (p >= other);
else cross = (dir == 1) ? (p >= anchor) : (p <= anchor);
if(!cross) return;
double lot = NormalizeDouble(lastLot * InpMult, 2);
lot = MathMin(lot, SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX));
if(Open(-lastSide, lot, tick, StringFormat("level%d", nLevels + 1)))
{
nLevels++; lastSide = -lastSide; lastLot = lot;
}
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, InpLot, tick, "entry"))
{
lastEntryBar = bar;
dir = side; nLevels = 1; lastSide = side; lastLot = InpLot;
anchor = p;
}
}

コメント