はじめに
EAを作成した際、いざEAをバックテストで動かしてみると『自分が思った所でエントリーしていない!』となった事はないでしょうか?
※この問題、私もよく起きます
今回はこの問題について、プログラミング初心者でもわかるような解決方法をご紹介します。
何が悪いのか
まず、思った所でエントリーしてくれないという事はプログラムが悪い場合がほぼほぼ99%です。
1%は環境による問題ですが、大体以下2点です。
- バックテストデータが無い・壊れている
- 初期証拠金の金額が少なすぎる
この問題がなければもうプログラムが悪いですね。
プログラムは書いた通りに忠実に動いてくれるため、自分が書いたプログラムを疑う事が大事です。(自分が頑張って書いたプログラムを疑うのは少し抵抗がありますがプログラマーが必ず通る道です)
素直にプログラムの悪い部分を探していく事が大事です。
プログラムの悪い部分を見つける方法
では、本題のプログラムの悪い部分を見つける方法について記載していきます。
条件分岐を探る
基本的に思い通りにエントリーしない時って、条件分岐(if文)が自分の思ったものと違うことになっています。
ですので、まずはif文が自分の思った通りに通っているかを探っていきましょう。
以下のプログラムはif文が合計3つありますが、各if文の下の行に以下のPrint()を記載しています。これが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);
}
こんなんで解決できるの?と思われるかもしれませんが解決できます!
では、Print()を使う事でどうなるのかバックテストで確認してみましょう。
バックテスト中に赤枠の部分、操作履歴をクリックしてみると「a」がずっと表示されています。
if文が『true』となっているか(どこまで実行されているのか)を操作履歴で確認できるようにしたわけです。1つ目のif文の下に書いたPrint(“a”);が実行されているので1つ目のif文は『true』となっていますがPrint(“b”);以降が表示されていないので『if(int_b == int_c)』は『false』となりエントリー処理までたどり着けていないことがわかります。
※” “で囲ってその中に表示したい文字を書く感じです
こんな感じで、自分のソースコードにも同様にif文の下にPrint()を付け加えて確認してみましょう。どこのif文が通っていないかがすぐに分かるはずです。
悪い部分を修正しよう
先ほどの続きになります。Print(“a”);は表示されていましたが、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(“a”)等の調査用Print()は削除しましょう。
ただし、必要なPrint()であればそのまま残しておいてかまいません。
以下にPrint()関数の別の使用例も記載します。
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()関数は是非覚えておきましょう。
さいごに
以上が、『作ったEAが思った所でエントリーしてくれない時の対処法』です。
プログラム初心者のうちは、どこが間違っているのかを探し出すのにかなり苦労すると思います。今回はif文で説明しましたが、for文やWhile文等の条件分岐で私たちが意図しないプログラムの通り方をしており思った通りにエントリーしない事はよくあるので、まずはそこを疑うようにしてみてください。
慣れてくると大体『Print();』を2,3個入れるだけでどの条件分岐でうまくいってないのかが分かってきたりします。
※ EAのサンプルソースを一覧表にまとめました
※オンラインレッスンやってます
コメント