今回は、外部変数を無期限でメタトレーダー内に保存して再利用する方法を紹介します。
答えは簡単です。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を再起動しても、きちんとバーの始値でのみエントリーしてくれます。
関西人k (月曜日, 29 4月 2024 13:00)
はじめまして、こんにちは。
PC再起動で変数の値が変わってしまう問題でアレコレ頭を悩ませていたときにこのサイト記事に出会い、Wow!と感動。このようなニッチな問題を扱って解説いただける貴サイト本当に素晴らしいです!
さてこのFile()関数でcsv保存を試行していますが、先週土曜日PCシャットダウンし日曜に立ち上げるとcsvファイルにデータはあるのですが、あるべき数値ではなく0ばかりとなっていました。
EAを稼働状態のままMT4を強制的に閉じPCを再起動する場合でもOnDeinit関数やOnInit関数が正常に作動してFile書き込み呼び戻しがなされるのでしょうか?
EA作成代行 (火曜日, 30 4月 2024 09:45)
>関西人kさん
10年も前に書いた記事なので、どうやって実験をしたか覚えていません。
①MT4を稼働したままEAのみを削除する。
②EAを稼働したままMT4自体を終了する。
③EAを稼働したままパソコンをシャットダウンする。
恐らく、上記①②③のいずれであっても、Fileの書き込みや呼び出しは正常に実行されると思います。
この記事のままそっくりプログラムしたEAを使って、ご自身で①②③で実験してみください。いずれでも正常に稼働するのに、お手持ちのEAでは正常に稼働しないのであれば、お手持ちのEAのどこかにプログラムミスがある、ということになります。
関西人k (火曜日, 30 4月 2024 21:01)
やってみました。
①②はOK、③はダメ。
これは当方の過去起きた事象と合致する結果でした。
OnDeinit関数が作動する間もなくPCが終了してしまうという感じですかね。
停電とかの場合もうまくいかないことになります。
取り急ぎご報告まで。
EA作成代行 (水曜日, 01 5月 2024 00:29)
>関西人kさん
貴重な情報ありがとうございます。
>OnDeinit関数が作動する間もなくPCが終了してしまうという感じですかね。停電とかの場合もうまくいかないことになります。
どうやら、そういうことになりそうですね。もしそうだとしたら、GlobalVariableGet()関数を使ってもダメだということになりますね(これもOnDeinit関数を利用するため)。
そうすると、記憶変数を一切使わないプログラムにするか、もしくはVPSを利用して停電トラブルを避けるしかないですね。ただ、VPSも時々トラブルがあるようです。
まあ、メタトレーダーなんて所詮ロシア製のガラクタですから、許してあげてください。
困った困った…汗
関西人k (水曜日, 01 5月 2024 11:48)
ちなみにGlobalVariableGet()関数でも同時にテストしましたが同じくダメでした。
>メタトレーダーなんて所詮ロシア製のガラクタ
ええーそうなんですかあ?
結構しっかりできてるなと常日頃感心しきりでしたが。。。