MT5でBTCUSDの買い下がりEAを作って検証してみた ③ 結果 爆死
前回の記事はこちら。
前回はBTCUSDの買い下がりEAを、決済の方法をいろいろ変えながら検証しました。
価格に対する%幅であったり、Lotを変動させるなどすることでそれなりに右肩上がりの資産曲線を描くことができました。
で、いざFXGTのmini口座で実行しようと考えていたのですが、ExnessでさらにLotが小さいセント口座が、通常と同じスプレッドで扱っていると聞き、そっちで検証してみることにしました。
さらにBTCUSDより過去データの長いXAUUSD(ゴールド)でやってみた方がよいのではとのことで、「MT5でBTCUSDの買い下がりEA」あらため「MT4でXAUUSDのナンピンEA」に変更して検証をはじめました。
結論から言いますと、爆死しました。やはりナンピンは難しいです。
爆死したEAの供養と、爆死した原因の考察も含め、以下に書いていこうと思います。
*コードコピーされて、損失を被ったとしても責任は負いません
検証環境
Exnessのスタンダードセント口座(MT4)
XAUUSD
2021年1月1日~2022年10月9日
1時間足(モデル:1分足OHLC)
証拠金1000ドル
EAの中身
ざっくりとしたEAの中身の説明です。
void OnTick()
{
if(lastBar!=Bars)
{
CheckForOpen();
lastBar = Bars;
}
}
まず、lastBar!=Barsでローソク足の切り替わりでしか動かないようにしています。これしていないとtickごとに無限にエントリーオーダーとか決済オーダー走るので。。。
double LaveP = 0;
double LsumLots = 0;
double SaveP = 0;
double SsumLots = 0;
int Lnum = 0;
int Snum = 0;
double Lri = 0;
double Sri = 0;
double MA1 = iMA(_Symbol,PERIOD_CURRENT,maperiod,0,MODE_SMA,PRICE_CLOSE,1);
if(OrdersTotal()>0)
{
for(i=OrdersTotal()-1; i>=0; i--)
{
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderType()==ORDER_TYPE_BUY)
{
LaveP += OrderOpenPrice()*OrderLots();
LsumLots += OrderLots();
Lri += OrderProfit();
Lnum += 1;
}
if(OrderType()==ORDER_TYPE_SELL)
{
SaveP += OrderOpenPrice()*OrderLots();
SsumLots += OrderLots();
Sri += OrderProfit();
Snum += 1;
}
}
if(LsumLots!=0) LaveP = LaveP/LsumLots;
if(SsumLots!=0) SaveP = SaveP/SsumLots;
}
で、CheckForOpenの関数で走らせてる部分の説明。
MA1って変数に移動平均線の配列を呼び出し。前回まではロングとショートを同じように走らせていたけれど、相対的に下がった時にロングして、上がった時にエントリーみたいな判定に使おうと思って準備。
ロングとショートの平均建値、ポジションサイズなどを変数に保存。OrderTotalでそのまま判定させると、ロングの決済タイミングでショートもまとめて決済みたいなことが生じるため。
if(Lri>=rieki)
{
for(i=OrdersTotal()-1; i>=0; i--)
{
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderType()==ORDER_TYPE_BUY) OrderClose(OrderTicket(),OrderLots(),SymbolInfoDouble(_Symbol,SYMBOL_BID),Slippage);
}
for(i=OrdersTotal()-1; i>=0; i--)
{
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderType()==ORDER_TYPE_BUY_LIMIT) OrderDelete(OrderTicket());
}
Lnum=0;
}
if(Sri>=rieki)
{
for(i=OrdersTotal()-1; i>=0; i--)
{
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderType()==ORDER_TYPE_SELL) OrderClose(OrderTicket(),OrderLots(),SymbolInfoDouble(_Symbol,SYMBOL_ASK),Slippage);
}
for(i=OrdersTotal()-1; i>=0; i--)
{
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderType()==ORDER_TYPE_SELL_LIMIT) OrderDelete(OrderTicket());
}
Snum=0;
}
ロングポジションの含み益が設定利益額を超えたら決済。ショートも同じ。
if(Lnum==0 && Close[1]>MA1)
{
for(i=OrdersTotal()-1; i>=0; i--)
{
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderType()==ORDER_TYPE_BUY_LIMIT) OrderDelete(OrderTicket());
}
OrderSend(_Symbol,ORDER_TYPE_BUY,Lots,SymbolInfoDouble(_Symbol,SYMBOL_ASK),Slippage,0,0);
lastP = SymbolInfoDouble(_Symbol,SYMBOL_ASK);
for(i=1; i<num; i++)
{
OrderSend(_Symbol,ORDER_TYPE_BUY_LIMIT,LotArr[i],MathRound((lastP-SymbolInfoDouble(_Symbol,SYMBOL_ASK)*haba*MathPow(haba_hiritsu,i))*100)/100,Slippage,0,0);
lastP -= SymbolInfoDouble(_Symbol,SYMBOL_ASK)*haba*MathPow(haba_hiritsu,i);
}
}
if(Snum==0 && Close[1]<MA1)
{
for(i=OrdersTotal()-1; i>=0; i--)
{
OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
if(OrderType()==ORDER_TYPE_SELL_LIMIT) OrderDelete(OrderTicket());
}
OrderSend(_Symbol,ORDER_TYPE_SELL,Lots,SymbolInfoDouble(_Symbol,SYMBOL_BID),Slippage,0,0);
lastP = SymbolInfoDouble(_Symbol,SYMBOL_BID);
for(i=1; i<num; i++)
{
OrderSend(_Symbol,ORDER_TYPE_SELL_LIMIT,LotArr[i],MathRound((lastP+SymbolInfoDouble(_Symbol,SYMBOL_BID)*haba*MathPow(haba_hiritsu,i))*100)/100,Slippage,0,0);
lastP += SymbolInfoDouble(_Symbol,SYMBOL_BID)*haba*MathPow(haba_hiritsu,i);
}
}
ロングポジが0で移動平均より前回終値が上回っていた場合、ロングポジ構築。ショートも同様。移動平均を下回った時のエントリーなら不等号を反対にすればOK。
LotArrの配列はOnInitで設定。前回までは線形増加(1,2,4,8…みたい)にしていたけど、もう少し緩やかにした方が良い結果が得られたので変更。0.01、0.02、0.02、0.03…みたいに変更しました。
habaとhaba_hiritsuは同じ。設定した比率値幅で指値オーダーを撒きます。
ほかに、設定値以上の保有時間で決済したり、土日ロールしない設定だったり細かい設定はいろいろ入れましたが、割愛します。
バックテスト結果
一見良さそうではありますが、爆上げしている部分は、大きくポジションを持った状態で時間切り替わりを迎えた時です。
最適化とかの検証を手抜きしたかったので、tickでは検証せず、始値での検証を行っています。なので、コード自体も時間切り替わり(ローソク足の切り替わり)でしか走らないようにしています。
時間切り替わりの際、変数riekiをOrdrProfitの合計が超えていた場合決済されるのですが、上記の大きく稼いでいる部分はまさにこれです。
テスト結果のチャートを見ても、指値注文が邪魔でよくわからないですよね。
あんまり良さそうには思えませんでしたが、ものは試しと実弾でトレードしてみました。
結果
MT4から取引履歴が消えていたので、エクスネスの履歴をExportしてエクセルにてグラフ化しました。
もう最悪ですね。。。
11月8日の上昇で全部焼かれました。ここを耐えれても11月10日で死んでいたかもしれません。
反省
1000ドルで検証していたが、700ドルしか入れなかった
(円安忘れて10万円入金で1000ドル検証と同じになると思ってたとは口が裂けても言えない。。。)バックテストの結果をうのみにした
ナンピンするには証拠金が少なすぎる
今回のナンピンEAって30個くらい指値置く設定だったんですけど、証拠金不足で最後置けてなかったっぽいです。同じような設定で動かすのであれば、3000ドルとか5000ドルとか証拠金を入れておかないとダメっぽいです。
次にバックテストの妄信が良くなかったですね。さっき示したバックテストって利益で証拠金も膨らんでるので、少々のドローダウンでは死なないんですが、動かしてすぐで証拠金が少ない状態で食らうと死にます。
先ほどのバックテストは2021年1月から開始していますが、2022年10月から開始した場合は証拠金不足で死んでいます。
ちゃんと検証せずに走らせたのが失敗だったなと感じています。
考察
なんかバックテストとかしてるといい感じの右肩上がりが作れるので、ひょっとしたらって思っちゃうんですけど、やっぱりナンピンEAは落とし穴しかないですね。これで稼げてる人はすごいと思います。
やっぱりアノマリーとかの優位性あるトレードしか勝たんなぁとつくづく思いました。
結論
ナンピンは簡単に作ることができるEAで、バックテストも最適化を行えば良い感じの答えを出してくれます。これをうのみにすれば、痛い目を見るってことを身をもって経験できました。
何かのロジックがあった上で、エントリーを分散させるナンピンはありでしょうが、盲目的にナンピン指値を並べるのは無謀ですね。
先日良いアイデアをいただいたので、もう少し改善してみようと思いますが、買い下がりEAのnoteは今回で終了しようと思います。また、いい感じのEAができそうであれば、シェアさせていただきます。
ここまで読んでいただきありがとうございます。
アノマリーEAの宣伝
アノマリーEAとかだと2万円スタートで2週間で98000円なので、利益率390%とかです。
30万円の証拠金で50円稼ぐよりよっぽどリスク小さいですし、効率的だと思います。
キンドルで書いてるので、良かったら読んでください。アンリミテッドなら無料で読めます。
この記事が気に入ったらサポートをしてみませんか?