はじめに
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になっていない箇所を探し当てていく感じです。
さいごに
以上が、『コンパイルできたのに1回もエントリーしてくれない時の対処法』です。
プログラム初心者のうちは、どこが間違っているのかを探し出すのにかなり苦労すると思います。大体、コンパイルが通っているのにうまくエントリーされないのはif文やfor文絡みの事が多いので、まずはそこを疑うようにしてみてください。
慣れてくると大体『Print();』を2,3個入れるだけでどのif文がうまくいってないのかが分かってきたりします。
※ EAのサンプルソースを一覧表にまとめました
※オンラインレッスンやってます
コメント