今回の記事は、MQL4のPrint()関数についての記事になります。
以前から申し上げておりますが、私はMQL4プログラミングスクールに入会しています。
そのスクールのグループチャットをチェックしていると、「あ、これいいかも!」と思えることも多々あります。
自分が思った「これいいかも!」の中から、Print()関数を紹介します。
この、Print()関数を利用すると、変数の値や、プログラムの流れが確認できるので、プログラミングの理解が深まり、様々な問題解決に役立ちます。
以下から、使用方法や活用法、注意点などを説明していきます。
*パソコンに関する内容はWindows10の場合です。
●関連記事
MQL4のPrint関数でログ出力!問題解決の方法を解説!(2)はこちらです。
MQL4のPrint関数でログ出力!問題解決の方法を解説!(3)はこちらです。
☑MQL4の変数の中身を知りたい
☑MQL4の動作エラーの原因を探りたい
☑MQL4のインジケータやEAの動作確認方法が知りたい
☑MQL4の理解を深めたい
☑MQL4のコードの動きや意味を知りたい
☑MQL4のif文やfor文が思った通りに動いているか確認したい
目次
MQL4のPrint()関数とは
MQL4の関数で、Print() と記述します。()の中に記述したものを、MT4の「操作履歴タグ」に表示させたり、パソコンの「logファイル」に保存されます。
この結果を確認して、プログラムの動きや変数の状態などを確認することが出来ます。
操作履歴タグ
Print()関数の使用方法
Print()の()の中に引数を入れて使用します。例えば、下記のように使用します。
Print("【MQL Print()関数】で問題解決!");
ダブルクォーテーション「"」で左右を囲むと文字が出力されます。
Print(a);
ダブルクォーテーション「"」で左右を囲まないとき(上記の場合)は、変数aの値が出力されます。
Print("変数aの値は ",a,"です。");
カンマ「,」で区切ると文字や変数を結合して出力することが出来ます。
Print(1+1);
上記の様に入力すると、計算も出来ます。
Print("1+1= ",1+1);
分かりやすく、計算式も出力出来ます。
Print()関数の出力練習
前述の説明だけではイメージが出来ないと思いますので、実際にどの様に出力されるか練習してみましょう。
①メタエディターでEAの新規作成をします。
「ファイル」→「新規作成」→「エキスパートアドバイザー」→任意の名前を入力→「次へ」→「次へ」→「完了」で新規のプログラムを作成します。
②デフォルトのプログラムコードは全て削除して下記の様に入力します。(コピペして下さい。)
int a=0;
int OnInit()
{
Print("【MQL Print()関数】で問題解決!");
Print(a);
Print("変数aの値= ",a);
Print("変数aの値は ",a,"です。");
Print(1+1);
Print("1+1= ",1+1);
return(INIT_SUCCEEDED);
}
③「コンパイル」をして下さい。
④MT4で任意の設定をして、バックテストして下さい。(下の画像は例です)
次は、どの様に出力されたか確認してみましょう。
Print()関数で出力されたのデータ確認方法
前述しましたが、Print()関数は、操作履歴タグとパソコンデータのlogで確認することが出来ます。
ここでは、もう少し詳しく説明します。
操作履歴タグでの確認
まずは、操作履歴から確認してみましょう。
下の画像のように、MT4の「テスター」にある「操作履歴」タブをクリックしてください。
先ほど入力したPrint()関数は、この様に出力されます。
下から古い順番に表示されます。
ログファイルでの確認
簡単な確認は操作履歴タグでも良いのですが、詳しく確認したい場合は、パソコン内で作成される「ログファイル」で確認した方が良いと思います。
ファイルの保存場所は、MT4から「ファイル」→「データフォルダを開く}→「tester」フォルダ→「logs」フォルダの中に下図のファイルがあります。
ログファイルをダブルクリックしますと、通常の設定でしたら、Windowsの「メモ帳」が起動して開くことが出来ます。
ログファイル
●不明の場合は次の画像を参考にして下さい。
①MT4の「ファイル」から「データフォルダ」をクリックします。
②開いたフォルダの中に「tester」フォルダがありますので、そこをダブルクリックして下さい。
③開いたフォルダの中に「logs」フォルダがありますので、そこをダブルクリックして下さい。その中に先ほどの「logファイル」があります。
④ログファイルをダブルクリック
「ログファイルをダブルクリック」しますと、通常の設定でしたら、Windowsの「メモ帳」が起動して開くことが出来ます。
MQL4のPrint()関数の使用例
ここでは、プログラムの動きや、変数の値を確認するために、どこにPrint()関数を入れるのか、使用例を見てみます。
Print()関数を使用したサンプルコード
まずは、サンプルコードです。Print()関数の確認用ですので、細かいことは気にしないで下さい。
「出力練習」のときと同じように、コピペして下さい。
2021.11.04 分かりにくいところがありましたので、若干変更しました。(以前のコードでも問題ございません)
//+------------------------------------------------------------------+
//| MA-Print-Test.mq4 |
//| |
//| https://mql-creation.com/ |
//+------------------------------------------------------------------+
#property copyright ""
#property link "https://mql-creation.com/"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//|変数設定 |
//+------------------------------------------------------------------+
bool Closed, Ticket = false;
extern int magicnum = 2021;//マジックナンバー
extern double Lots=0.01; // スタートロット数
bool BUY = true;
bool SELL = true;
extern int mas=50;//エントリーのMA短期
extern int mal=100;//エントリーのMA長期
extern int masc=10;//決済のMA短期
extern int malc=20;//決済のMA長期
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
Print("~~~OnTick()開始~~~");
//+------------------------------------------------------------------+
//決済条件
Print("~~~決済条件開始~~~");
double mac_1,mac_2;
double mac_1a,mac_2a;
//一つ前の決済用短期線
mac_1 = iMA(NULL,0,masc,0,MODE_SMA,PRICE_CLOSE,1);
//一つ前の決済用長期線
mac_2 = iMA(NULL,0,malc,0,MODE_SMA,PRICE_CLOSE,1);
//現在の決済用短期線
mac_1a = iMA(NULL,0,masc,0,MODE_SMA,PRICE_CLOSE,0);
//現在の決済用長期線
mac_2a = iMA(NULL,0,malc,0,MODE_SMA,PRICE_CLOSE,0);
Print("~~~~~決済用MA条件~~~~~");
Print("mac_1= ",mac_1);
Print("mac_2= ",mac_2);
Print("mac_1a= ",mac_1a);
Print("mac_2a= ",mac_2a);
Print("( mac_1 > mac_2 && mac_1a <= mac_2a)= ",( mac_1 > mac_2 && mac_1a <= mac_2a));
Print("( mac_1 < mac_2 && mac_1a >= mac_2a) = ",( mac_1 < mac_2 && mac_1a >= mac_2a) );
Print("決済のOrdersTotal()= ",OrdersTotal());
for(int i = OrdersTotal()-1; i>=0; i--)
{
Print("変数【i】の値= ",i);
Print("if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true)= ",(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true));
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true)
{
Print("if(OrderSymbol() == Symbol() && OrderMagicNumber() == magicnum)= ",(OrderSymbol() == Symbol() && OrderMagicNumber() == magicnum));
if(OrderSymbol() == Symbol() && OrderMagicNumber() == magicnum)
{
Print("if(OrderType()==OP_BUY)= ",(OrderType()==OP_BUY));
if(OrderType()==OP_BUY)
{
//決済の短期線が上から下に決済の長期線をクロスしたら
if( mac_1 > mac_2 && mac_1a <= mac_2a)
{
Closed = OrderClose(OrderTicket(),OrderLots(), Bid, 30,White);
}
}
else
if(OrderType()==OP_SELL)
{
//決済の短期線が下から上に決済の長期線をクロスしたら
if( mac_1 < mac_2 && mac_1a >= mac_2a)
{
Closed = OrderClose(OrderTicket(),OrderLots(), Bid, 30,White);
}
}
}
}
}///決済条件 for(int i = OrdersTotal()-1; i>=0; i--)
//+------------------------------------------------------------------+
//エントリー条件
Print("~~~エントリー条件開始~~~");
//変数
double ma_1,ma_2;
double ma_1a,ma_2a;
//一つ前のエントリー用短期線
ma_1 = iMA(NULL,0,mas,0,MODE_SMA,PRICE_CLOSE,1);
//一つ前のエントリー用長期線
ma_2 = iMA(NULL,0,mal,0,MODE_SMA,PRICE_CLOSE,1);
//現在のエントリー用短期線
ma_1a = iMA(NULL,0,mas,0,MODE_SMA,PRICE_CLOSE,0);
//現在のエントリー用長期線
ma_2a = iMA(NULL,0,mal,0,MODE_SMA,PRICE_CLOSE,0);
Print("~~~~~エントリー用MA条件~~~~~");
Print("ma_1= ",ma_1);
Print("ma_2= ",ma_2);
Print("ma_1a= ",ma_1a);
Print("ma_2a= ",ma_2a);
Print("( ma_1 < ma_2 && ma_1a >= ma_2a) = ",( ma_1 < ma_2 && ma_1a >= ma_2a) );
Print("( ma_1 > ma_2 && ma_1a <= ma_2a)= ",( ma_1 > ma_2 && ma_1a <= ma_2a));
Print("エントリーのOrdersTotal()= ",OrdersTotal());
Print("BUY= ",BUY);
Print("SELL= ",SELL);
if(BUY == true && OrdersTotal()==0)
{
//エントリー用短期線が下から上にエントリー用長期線をクロスしたら
if( ma_1 < ma_2 && ma_1a >= ma_2a)
{
Ticket = OrderSend(NULL,OP_BUY,Lots,Ask,30,0,0,NULL,magicnum,0,White);
}
}
if(SELL == true && OrdersTotal()==0)
{
//エントリー用短期線が上から下にエントリー用長期線をクロスしたら
if( ma_1 > ma_2 && ma_1a <= ma_2a)
{
Ticket = OrderSend(NULL,OP_SELL,Lots,Bid,30,0,0,NULL,magicnum,0,White);
}
}
} //void OnTick()
//+------------------------------------------------------------------+
各Print()の説明
Print("~~~OnTick()開始~~~");
一番最初の「 Print("~~~OnTick()開始~~~"); 」は、void OnTick()が実行された場合に一番最初に出力されます。
ですから、今回のコードでは、「プログラムのスタート」と思って下さい。
Print("~~~決済条件開始~~~");
決済条件コードの「実行開始」がされたことを出力させます。
Print("~~~~~決済用MA条件~~~~~");
Print("mac_1= ",mac_1);
Print("mac_2= ",mac_2);
Print("mac_1a= ",mac_1a);
Print("mac_2a= ",mac_2a);
Print("( mac_1 > mac_2 && mac_1a <= mac_2a)= ",( mac_1 > mac_2 && mac_1a <= mac_2a));
Print("( mac_1 < mac_2 && mac_1a >= mac_2a) = ",( mac_1 < mac_2 && mac_1a >= mac_2a) );
決済用条件に使用されている、「変数の値」や「引数の状態」を出力させます。
出力結果から、計算や条件に間違いがないか確認が出来ます。
Print("決済のOrdersTotal()= ",OrdersTotal());
この後にある、for(int i = OrdersTotal()-1; i>=0; i--)で使用される「OrdersTotal()」の値を出力させます。
「OrdersTotal()」の値がわかると、計算が合っているか?などの確認が出来ます。
どこのOrdersTotal()か分からなくなるので、今回は「決済の」と付けています。
Print("変数【i】の値= ",i);
Print("if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true)= ",(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == true));
この前にある、for(int i = OrdersTotal()-1; i>=0; i--)で使用される、変数【i】の値と条件の結果を出力させます。
Print("if(OrderSymbol() == Symbol() && OrderMagicNumber() == magicnum)= ",(OrderSymbol() == Symbol() && OrderMagicNumber() == magicnum));
この後にある、if(OrderSymbol() == Symbol() && OrderMagicNumber() == magicnum)の結果を出力させます。
Print("if(OrderType()==OP_BUY) ",(OrderType()==OP_BUY));
Print("f(OrderType() ",OrderType());
この後にある、if(OrderType()==OP_BUY)の結果とOrderType()の値を出力させます。
Print("~~~エントリー条件開始~~~");
エントリー条件コードの「実行開始」がされたことを出力させます。
Print("~~~~~エントリー用MA条件~~~~~");
Print("ma_1= ",ma_1);
Print("ma_2= ",ma_2);
Print("ma_1a= ",ma_1a);
Print("ma_2a= ",ma_2a);
Print("( ma_1 < ma_2 && ma_1a >= ma_2a) = ",( ma_1 < ma_2 && ma_1a >= ma_2a) );
Print("( ma_1 > ma_2 && ma_1a <= ma_2a)= ",( ma_1 > ma_2 && ma_1a <= ma_2a));
エントリー条件に使用されている、「変数の値」や「引数の状態」を出力させます。
出力結果から、計算や条件に間違いがないか確認が出来ます。
Print("エントリーのOrdersTotal()= ",OrdersTotal());
Print("BUY= ",BUY);
Print("SELL= ",SELL);
この後にある、if(BUY == true && OrdersTotal()==0)のOrdersTotal()の値と「BUY」の状態と、さらに後にあるif(SELL == true && OrdersTotal()==0)の「SELL」の状態を出力させます。
どこのOrdersTotal()か分からなくなるので、今回は「エントリーの」と付けています。
Print()関数の出力方法
それでは、Print()関数で結果を出力させてみましょう。
①コンパイル
先ほどのサンプルコードを「コンパイル」して下さい。
②ログの削除
削除しなくても大丈夫なのですが、出力結果が分かりにくくなるので、今回は削除します。
まず、TM4が起動していますと、削除できませんので、起動している場合は終了させて下さい。
次に「ログファイルの確認」のところで説明した、logsフォルダにある本日の日付のログファイルを削除して下さい。無い場合は何もしなくて大丈夫です。
③バックテスト
それでは、MT4を起動させて、期間を1~2日程度にして、バックテストを実行して下さい。
バックテスト入力例
④ログファイルを開く
logsフォルダに新たにログファイルが作成されていると思います。そのログファイルをダブルクリックして開いてください。
基本的には、Windows標準の「メモ帳」で開くと思います。
一部ですが、この様に出力されたと思います。
この出力結果を確認して、「プログラムの動」きや、「変数の値」をチェック出来ます。
今回のPrint()関数説明のは、ここまでにします。
次回は、出力結果の「プログラム」の動きや「変数」の変化を補足説明していきます。
Print関数でログ出力!問題解決方法のまとめ
今回は、スクールのグループチャットで見つけた、Print()関数の使用方法を説明いたしました。
Print()関数は、プログラムの流れやエラーの確認に本当に便利です。
使い方次第で今まで理解出来なかったことが、「パッ」と晴れる様に理解出来たときもあります。
あなたも、いろいろと試してみて下さい。