今回は、外部変数を無期限でメタトレーダー内に保存して再利用する方法を紹介します。
答えは簡単です。File…()関数を利用して、CSVファイルにその数値を保存し、EAを再起動したときに再読み込みすればよいわけです。
プログラムの大まかな流れは、前回のグローバル変数(大域変数)のときと同じで、
①まずは外部変数をスタート関数外で宣言する。
②ティック変動にもかかわらず、その外部変数が以前の数値を記憶しながら変化していく。
③EAが停止する直前に、その最後の数値だけをCSVファイルへ書き込んで保存しておく。
④次にEAを再起動したときに一回だけその数値を読み込んで元の外部変数に返してやる。
となります。
早速、プログラムを見ていきましょう。
スタート関数外に上のように記述します。
int handle; というのは、使用するファイルを特定するための番号を入れる変数で、EAで言えばマジックナンバーのようなものです。
int X,Y,Z; というのは、保存して再利用したい数値を入れる変数です。
string FN = IntegerToString(MAGIC)+Symbol()+".csv"; というのは、グローバル変数(大域変数)と同様、他のEAによって誤って利用されないように、マジックナンバーと通貨ペアを付与したかたちで、使用するファイル名を宣言しています。
いずれも、そのEA中の複数の関数内で使用されるので、外部変数として宣言しています。
次に、スタート関数内にて、
上のように、ティックの変動ごとに、X,Y,Zに「1」を加算して、それをコメント表示させます。
次に、EAが停止した際に一度だけ呼び出される、deinit()関数内に、次のように記述し、X,Y,Zの最後の数値をCSVファイルに書き込みます。
File…()関数を使うときは、いつも、
FileOpen()関数→読み書きの実行→FileClose()関数
という流れになります。
FileOpen()関数は、ファイルを開くための関数で、パラメーターは、(ファイル名,ファイルの種類 | 読み書きの選択) という具合に指定します。
開かれたファイルの番号をhandleという変数に入れて、以後は、このhandle番号でファイルを指定していきます。
FileWrite()関数では、handle番号で指定したファイルに、X,Y,Zを書き込んでいます。最大63個まで、「,」で区切って記述します。それ以上書き込みたいときは、
FileWrite();
FileWrite();
FileWrite();
という具合に、FileWrite()関数を複数回実行すればOKです。
最後は、FileClose()関数でファイルを閉じます。
ところで、書き込まれたCSVファイルはどこに保存されているかというと、「メニュー」→「データフォルダを開く」→「MQL4」→「Files」を開くと、
↑ こんな感じで、保存されています。
前述のように、マジックナンバーと通貨ペア名をファイル名に付与してあるので、このように表示されています。
中を開くと、
上のように、X,Y,Zの最後の数値が保存されていることがわかります。
さて、最後に、EA再起動時に一度だけ呼び出されるinit()関数内にて、
上のように、CSVへ書き込まれた数値を読み込みます。
FileReadNumber()関数によって読み込まれた数値を元の変数へ返します。
あとは、再びスタート関数が実行されるたびに、X,Y,Zそれぞれに、さらに「1」が加算され、結局、X,Y,Zは、いずれも、
1,2,3,4,5,6,7,8,
再起動
9,10,11,12,13…
と連続していきます。
コメントをお書きください
EA太郎 (木曜日, 05 6月 2014 20:25)
ファイル関数なんて、あんまり使い道のないものだと決めつけていましたが、こんな有効活用の方法があるとは…。
easakuseidaiko (金曜日, 06 6月 2014 11:09)
>EA太郎さん
そうですね。これくらいしか使い道は無いですね。(笑)
なお (火曜日, 15 7月 2014 19:26)
はじめまして。
こんにちは!
サヤ取りをEAにしたくて、いろいろ調べていたら本サイトの前のサイトに行き当たりました、☆
EA作成代行などやってらっしゃるんですね!
本サイトにはサヤ取りEAは出て来ないのですが、作成されたりしたのでしょうか(*^^*)?
気になったので、コメントさせていただきました。
easakuseidaiko (水曜日, 16 7月 2014 01:17)
>なおさん
コメントありがとうございます。
FXではあまりサヤ取りはしてないですね。なかなか取れそうなサヤがみつからなくて…。^^;
tanaka (火曜日, 14 5月 2019 12:07)
たとえば、static datetime time1 = Time[0];//新しいバーのときのみ1回だけエントリーさせる
このようなstatic 変数は、
staticをやめて、 datetime time1 = Time[0]
に変えて、それをグローバル変数にいれておけばいいのでしょうか?
EA作成代行 (水曜日, 15 5月 2019 11:10)
バーの始値でのみエントリーするプログラムを組むにはいろんなやり方があります。
①Volume[0]を使う方法
②Barsを使う方法
③Time[0]を使う方法
しかし、
①は、必ずしも「1」からスタートするとは限らず、「2」や「3」からスタートすることが時折あるので、好ましくありません。
②は、チャートの内のバーの数を変えると、それに伴って変化してしまうので、これも好ましくありません。
③が一番よいと思います。
ただ、tanakaさんが言われるように、わざわざグローバル変数に登録して記憶させておく必要はまったくありません。1ティック前のTime[0]の値と現在のTime[0]とを比較して後者の方が大きい数値のときのみにエントリーさせてやればよいのです。
具体的には、
int LOT = 0; ←グローバル領域に記述
int start()
{
int Cot = Time[0];
if(LOT>0 && Cot>LOT)
{
エントリープログラムを記述
}
LOT=Cot;
}
このやり方なら、途中でEAを再起動しても、きちんとバーの始値でのみエントリーしてくれます。