EAを作成した際、コンパイルはエラー無くできたのにいざEAをバックテストで動かしてみると『1回もエントリーしない』といったことが起きた事はないでしょうか?今回はこの問題についてに解説していきたいと思います。
※全然思った所でエントリーしてくれない・・・といった場合もこの記事を参考にしてみてください
何が悪いのか
まず、何が問題なのかを考えていく必要があります。
コンパイルできたのに1回もエントリーしてくれない事って、EAを作っているとよく?(私はよく)あります!そしてそうなった時、こう思います。MT4の環境が悪いんじゃないか?と・・・。
が、この考えは大体間違っています。(と思う事が大事です)
MT4は特に環境による問題は殆ど起きないので、プログラムが悪い場合がほぼほぼ99%です。
環境による問題も稀にありますが、大体以下2点ぐらいです。
- バックテストデータが無い
- 初期証拠金の金額が少なすぎる
なのでほぼほぼプログラムが悪いです。プログラムは書いた通りに忠実に動いてくれるため、自分が書いたプログラムを疑う事が大事です。(自分が頑張って書いたプログラムを疑うのは少し抵抗がありますがプログラマーが必ず通る道です)
素直にプログラムの悪い部分を探していく事が大事です。
プログラムの悪い部分を見つける方法
プログラムの悪い部分を見つける方法について記載していきます。
//+------------------------------------------------------------------+ //| TEST.mq4 | //| Copyright 2020, mef Software. | //| https://fx-prog.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, mef Software." #property link "https://fx-prog.com/" #property version "1.00" //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ int start() { int int_a = 1,int_b = 2,int_c = 3; double ea_order_stop_price = 0, ea_order_good_price = 0; int_a = OrdersTotal(); int_b = int_b + int_a; if(int_a == 0) { if(int_b == int_c){ if(ea_order_good_price > ea_order_stop_price){ ea_order_stop_price = Ask - 100 * Point; ea_order_good_price = Ask + 100 * Point; //新規注文 int ea_ticket_res = OrderSend(NULL,OP_BUY,1,Ask,20,ea_order_stop_price,ea_order_good_price,"",0,0,clrBlue); } } } return(0); }
上記は、コンパイルしてみるとエラーなくコンパイルできますが1回もエントリーしてくれないソースコードです。(※注 条件等は説明用にデタラメに作っています)
ポジションを1つも持っていない場合、ロングエントリー(利確、損切り10pipsに設定)を1ポジションだけ持つという形で作りましたが、バックテストで確認してみても1回もエントリーしてくれません。
さてどこが悪いのでしょうか・・・。
最初から1行ずつプログラムを見ていくのも手ですが、問題になってそうな部分を予測していく事が素早く悪い部分を見つける近道です。
1番の問題を考える
何でエントリーしてくれないのか・・・、1番の問題を考えましょう。
//新規注文 int ea_ticket_res = OrderSend(NULL,OP_BUY,1,Ask,20,ea_order_stop_price,ea_order_good_price,"",0,0,clrBlue);
そもそも、この部分が実行されたら必ずエントリーするはずです。
という事で・・・、ばっさりif文は全部消してみましょう。
//+------------------------------------------------------------------+ //| TEST.mq4 | //| Copyright 2020, mef Software. | //| https://fx-prog.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, mef Software." #property link "https://fx-prog.com/" #property version "1.00" //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ int start() { int int_a = 1,int_b = 2,int_c = 3; double ea_order_stop_price = 0, ea_order_good_price = 0; int_a = OrdersTotal(); int_b = int_b + int_a; ea_order_stop_price = Ask - 100 * Point; ea_order_good_price = Ask + 100 * Point; //新規注文 int ea_ticket_res = OrderSend(NULL,OP_BUY,1,Ask,20,ea_order_stop_price,ea_order_good_price,"",0,0,clrBlue); return(0);
バックテストで確認してみると・・・、エントリーするようになりましたね!めちゃくちゃエントリーしまくりです。
※これでもエントリーしない場合は環境の問題です
と言うように、問題はif文だった事がわかりました。最初のうちは条件分岐に問題が有る事が殆どです。
ただ、これだと荒治療すぎてどのif文に問題があったのか分からないので今度はif文は残した状態で見ていきましょう。
どのif文が通っていないのかを探る
では実際にどのif文が通っていないのかを探っていきましょう。
//+------------------------------------------------------------------+ //| TEST.mq4 | //| Copyright 2020, mef Software. | //| https://fx-prog.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, mef Software." #property link "https://fx-prog.com/" #property version "1.00" //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ int start() { int int_a = 1,int_b = 2,int_c = 3; double ea_order_stop_price = 0, ea_order_good_price = 0; int_a = OrdersTotal(); int_b = int_b + int_a; if(int_a == 0) { Print("a"); if(int_b == int_c){ Print("b"); if(ea_order_good_price > ea_order_stop_price){ Print("c"); ea_order_stop_price = Ask - 100 * Point; ea_order_good_price = Ask + 100 * Point; //新規注文 int ea_ticket_res = OrderSend(NULL,OP_BUY,1,Ask,20,ea_order_stop_price,ea_order_good_price,"",0,0,clrBlue); } } } return(0); }
上記は、問題のソースコード(if文は戻した状態)ですが少しだけソースコードをつけ足した部分があります。
if文は合計3つありますが、各if文の下の行に以下のPrint()を記載しました。
Print(“a”);
Print(“b”);
Print(“c”);
※” “で囲ってその中に表示したい文字を書く感じです
Print()を使う事でどうなるのかバックテストで確認してみましょう。

バックテスト中に赤枠の部分、操作履歴をクリックしてみると「a」がずっと表示されています。
Print(“a”);とプログラムしたことにより、どこまで実行されているのかを操作履歴で確認できるようにしたわけですね。1つ目のif文の下に書いたPrint(“a”);が実行されているので1つ目のif文は問題ない事がわかります。
ただ、Print(“b”);とPrint(“c”);は表示されていませんね。つまり、

上の画像の通りで、if(int_a == 0)はtrueだけど2つ目のif文のif(int_b == int_c)がfalseになっているこという事がわかります。これでは、エントリーしてくれないですよね。OrderSend()関数が実行されていないんです。
なので、if(int_b == int_c)の条件が正しいのかをしっかりと考えます。正しいのであれば、その前のソースコードが間違っているという事です。今回はその前のソースコードを正しましょう。
21行目あたり「int_b = int_b + 1;」と修正します。
//+------------------------------------------------------------------+ //| TEST.mq4 | //| Copyright 2020, mef Software. | //| https://fx-prog.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, mef Software." #property link "https://fx-prog.com/" #property version "1.00" //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ int start() { int int_a = 1,int_b = 2,int_c = 3; double ea_order_stop_price = 0, ea_order_good_price = 0; int_a = OrdersTotal(); int_b = int_b + 1; if(int_a == 0) { Print("a"); if(int_b == int_c){ Print("b"); if(ea_order_good_price > ea_order_stop_price){ Print("c"); ea_order_stop_price = Ask - 100 * Point; ea_order_good_price = Ask + 100 * Point; //新規注文 int ea_ticket_res = OrderSend(NULL,OP_BUY,1,Ask,20,ea_order_stop_price,ea_order_good_price,"",0,0,clrBlue); } } } return(0); }
これでコンパイルして、バックテストで実行してみると・・・

「a」と「b」が表示されていますね。がそれでもまだ、エントリーはしてくれません。つまり、

上の画像の通りで、3つ目のif文のif(ea_order_good_price > ea_order_stop_price)がfalseになっているこという事がわかります。これでも、エントリーしてくれないですよね。先ほどと同じくOrderSend()関数が実行されていないんです。
なので、if(ea_order_good_price > ea_order_stop_price)の条件が正しいのかをしっかりと考えます。今回は正しくなかったという事で、if文の条件を正しましょう。
今回であれば、if(ea_order_good_price == ea_order_stop_price)と修正します。
//+------------------------------------------------------------------+ //| TEST.mq4 | //| Copyright 2020, mef Software. | //| https://fx-prog.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, mef Software." #property link "https://fx-prog.com/" #property version "1.00" //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ int start() { int int_a = 1,int_b = 2,int_c = 3; double ea_order_stop_price = 0, ea_order_good_price = 0; int_a = OrdersTotal(); int_b = int_b + 1; if(int_a == 0) { Print("a"); if(int_b == int_c){ Print("b"); if(ea_order_good_price == ea_order_stop_price){ Print("c"); ea_order_stop_price = Ask - 100 * Point; ea_order_good_price = Ask + 100 * Point; //新規注文 int ea_ticket_res = OrderSend(NULL,OP_BUY,1,Ask,20,ea_order_stop_price,ea_order_good_price,"",0,0,clrBlue); } } } return(0); }
これでコンパイルして、バックテストで実行してみると・・・

「a」と「b」と「c」が表示されていますね。これでようやく全てのif文が正となりOrderSend()関数が実行されて、ようやくエントリーしてくれるようになりましたね!
こうやって、Print()関数を使ってif文でうまくtrueになっていない箇所を探し当てていく感じです。
Print()関数は超便利
Print()関数ですが、ただ文字を表示するだけではなくこんな使い方もできます。
Print(“指値は[” + ea_order_good_price + “]です”);
これは何をしているのかと言うと、実際の変数をPrintで表示しています。
Print(“文字列” + 変数 + “文字列”);
こんな感じで書く事で、変数を表示させることができます。
//+------------------------------------------------------------------+ //| TEST.mq4 | //| Copyright 2020, mef Software. | //| https://fx-prog.com/ | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, mef Software." #property link "https://fx-prog.com/" #property version "1.00" //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ int start() { int int_a = 1,int_b = 2,int_c = 3; double ea_order_stop_price = 0, ea_order_good_price = 0; int_a = OrdersTotal(); int_b = int_b + 1; if(int_a == 0) { Print("a"); if(int_b == int_c){ Print("b"); if(ea_order_good_price == ea_order_stop_price){ Print("c"); ea_order_stop_price = Ask - 100 * Point; ea_order_good_price = Ask + 100 * Point; Print("指値は[" + ea_order_good_price + "]です"); //新規注文 int ea_ticket_res = OrderSend(NULL,OP_BUY,1,Ask,20,ea_order_stop_price,ea_order_good_price,"",0,0,clrBlue); } } } return(0); }
実際にプログラムして確認してみると、

こんな感じで、変数の値を表示する事ができます。
変数の値が正しいかどうかも、こうやって表示してあげればわかりやすくなるのでPrint()関数は是非覚えておきましょう。
さいごに
以上が、『コンパイルできたのに1回もエントリーしてくれない時の対処法』です。
プログラム初心者のうちは、どこが間違っているのかを探し出すのにかなり苦労すると思います。大体、コンパイルが通っているのにうまくエントリーされないのはif文やfor文絡みの事が多いので、まずはそこを疑うようにしてみてください。
慣れてくると大体『Print();』を2,3個入れるだけでどのif文がうまくいってないのかが分かってきたりします。
※ MT4・EAが使えるFX会社のおすすめ
※ EAのサンプルソースを一覧表にまとめました
コメント