スクリプトとEAはそれぞれ独自の別スレッドで実行されます。
全てのインジケータはグラフィックインターフェーススレッドで動作します。
tickとヒストリーの同期処理はグラフィックインターフェーススレッドで実行されます。
カスタムインジケータはメインインターフェーススレッドで動作します。
カスタムインジケータが
iCustom()関数で呼び出されている場合、このインジケータは呼び出したプログラムのスレッドで動作します。
ライブラリ(インポート)関数も同様に、呼び出し元のプログラムのスレッドで動作します。
EAを実行している時、実際の
トレード環境と通貨ペアと
ヒストリーデータにアクセス出来る事を確認して下さい。
ターミナルとサーバー間でデータの
同期を行います。
これら全ての手順について、
ターミナルはEAが利用可能なデータで開始されるまで5秒の開始遅延が発生します。
サーバーとの接続が無い場合、EA開始遅延に繋がります。
MQL4プログラム概要
プログラム |
実行 |
備考 |
スクリプト |
別スレッドで動作。 スレッド数はスクリプト数に等しい |
処理ループのスクリプトは他プログラム実行をブレイクする事が出来ません |
EA |
別スレッドで動作。 スレッド数はEAの数に等しい |
処理ループのEAは他プログラム実行をブレイクする事が出来ません |
インジケータ |
全インジケータはグラフィックインターフェーススレッドで共有。 |
1つのインジケータの無限ループ処理は、ターミナルが停止します |
チャートに適用されたプログラムは、
適用された直後にグローバル変数は
初期化され、クライアントターミナルメモリにアップロードされます。
コンストラクタを持っているクラス型の
グローバル変数の場合、
このコンストラクタはグローバル変数の初期化中に呼び出されます。
アップロード完了後、プログラムはクライアントターミナルから
イベント待ち状態になります。
各MQL4プログラムは少なくとも1つは
イベントハンドラが必要です。
イベントハンドラが無い場合、ロードされたプログラムは実行されません。
イベントハンドラは、事前に定義された名前・引数・戻り値を持っています。
イベントハンドラ
型 |
関数名 |
引数 |
対象プログラム |
コメント |
int |
OnInit |
無し |
EA インジケータ スクリプト |
Initイベントハンドラ。 戻り値にvoid型を使用する事も出来ます |
void |
OnDeinit |
const int reason |
EA インジケータ スクリプト |
Deinitイベントハンドラ |
void |
OnStart |
無し |
スクリプト |
Startイベントハンドラ |
int (void) |
OnCalculate |
const int rates_total,
const int prev_calculated,
const datetime& time[],
const double& open[],
const double& high[],
const double& low[],
const double& close[],
const long& tick_volume[],
const long& volume[],
const int& spread[]
|
インジケータ |
全価格の為の計算イベントハンドラ |
void |
OnTick |
無し |
EA |
NewTickイベントハンドラ。 NewTickイベント処理が行われている間、 他イベントは受信されません。 |
void |
OnTimer |
無し |
EA インジケータ |
Timerイベントハンドラ |
double |
OnTester |
無し |
EA |
Testerイベントハンドラ |
void |
OnChartEvent |
const int id,
const long &lparam,
const double &dparam,
const string &sparam
|
EA インジケータ |
ChartEventイベントハンドラ |
クライアントターミナルは対応するチャートに新しいイベントを送信します。
イベントはチャート(
チャートイベント)またはMQL4プログラム(
カスタムイベント)で生成する事が出来ます。
チャート上のグラフィカルオブジェクトの作成・削除によって発生するイベントは、
チャートプロパティの
CHART_EVENT_OBJECT_CREATE と
CHART_EVENT_OBJECT_DELETEの設定で有効/無効に出来ます。
各MQL4プログラムと各チャートは、追加された全ての新規イベントの為の独自のキューを持っています。
プログラムは様々なチャートからイベントを受け取ります。
全てのイベントは受信した順に処理されます。
キューに既にtickイベントが有る場合、またはtickイベント処理中の場合は、
新しいtickイベントはMQL4プログラムのキューに格納されません。
同様に、
ChartEventが既にキューに有る場合、又はイベント処理中は、
この種類の新しいイベントはキューに格納されません。
Timerイベントも同じように処理されます。
Timerイベントがキューにあるか処理中の場合、新しいタイマーイベントはキューに格納されません。
イベントキューは上限はありますが、十分な大きさを持っています。
そのためキューのオーバーフローは殆ど発生しません。
キューのオーバーフローが発生した場合、新しいイベントがキューに格納されず破棄されます。
イベント処理で無限ループを使用する事はお勧めしません。
無限ループを使用して良いのは
Startイベントだけを処理するスクリプトだけだと思います。
関数の使用制限
インジケータ・スクリプト・EAはMQLで書かれた実行可能プログラムです。
これらは異なるタスクで設計されています。
その為、
プログラムの種類に応じて、特定の関数の使用にいくつか制限があります。
■インジケータでの使用禁止している関数
・
OrderSend()・
SendFTP()・
Sleep()・
ExpertRemove()・
MessageBox()
■EA・スクリプトでの使用禁止している関数
・
SetIndexBuffer()・
IndicatorSetDouble()・
IndicatorSetInteger()・
IndicatorSetString()
ライブラリは独立したプログラムでは無く、呼び出したMQL4プログラムのコンテキストで実行されます。
従って、上記の関数しよう制限はライブラリにも適用されます。
インジケータのロード・アンロード
■インジケータは以下のケースでロードされます
・インジケータがチャートに適用された時
・ターミナル起動(ターミナルを閉じる前にチャートにインジケータが適用されている場合)
・テンプレートの読み込み(テンプレート設定でチャートにインジケータが適用されている場合)
・プロファイルの変更(プロファイルチャートにインジケータが適用されている場合)
・インジケータが適用されているチャートの通貨ペア・時間軸の変更
・チャートに適用されているインジケータの再コンパイル(コンパイル成功時)
・インジケータの
入力パラメータ変更
■インジケータは以下のケースでアンロードされます
・ターミナルが閉じられた(チャートにインジケータが適用されている場合)
・テンプレートの読み込み(チャートにインジケータが適用されている場合)
・チャートが閉じられた(チャートにインジケータが適用されている場合)
・プロファイルの変更(プロファイルチャートにインジケータが適用されている場合)
・インジケータが適用されているチャートの通貨ペア・時間軸の変更
・インジケータの
入力パラメータ変更
EAのロード・アンロード
■EAは以下のケースでロードされます
・チャートにEAが適用された時
・ターミナル起動(ターミナルを閉じる前にチャートにEAが適用されている場合)
・テンプレートの読み込み(テンプレート設定でチャートにEAが適用されている場合)
・プロファイルの変更(プロファイルチャートにEAが適用されている場合)
・アカウントへの接続時。同じアカウント番号でもロードされます(ターミナルがサーバー接続する前にEAをチャートに適用していた場合)
■EAは以下のケースでアンロードされます
・チャートからEAを削除した時
・他EAが適用されているチャートに、新しいEAを適用した場合、EAがアンロードされます
・ターミナルが閉じられた(チャートにEAが適用されている場合)
・テンプレートの読み込み(テンプレート設定でチャートにEAが適用されている場合)
・EAが適用されたチャートを閉じた時
・プロファイルの変更(プロファイルチャートにEAが適用されている場合)
・アカウントを変更した時
EAが適用されたチャートの通貨ペア・時間軸を変更した場合、
EAはロード・アンロードされません。
この場合、クライアントターミナルは古い通貨ペア・時間軸の
OnDeinit()関数を呼び出した後に、
変更後の通貨ペア・時間軸の
OnInit()関数を呼び出します。
グローバル変数と
静的変数の初期化は行われません。
初期化(OnInit()関数)が完了する前に受信した全てのEA用イベントはスキップされます。
EAの処理をより良く理解する為に、以下サンプルソースをコンパイルし、
テンプレート・通貨ペア・時間軸の変更を行い、動作を確認する事をお勧めします。
サンプルソース(EA用)
static string test_str;
string test_gstr;
void OnInit() {
Print("初期化1:",test_str,test_gstr );
test_str = "静的変数" + Symbol() + ",";
test_gstr = "グローバル変数" + Symbol();
Print("初期化2:",test_str,test_gstr );
}
void OnDeinit(const int reason) {
Print("終了1:",test_str,test_gstr );
test_str = "静的変数" + Symbol() + ",";
test_gstr = "グローバル変数" + Symbol();
Print("終了2:",test_str,test_gstr );
}
スクリプトのロード・アンロード
スクリプトはチャートに適用した後、直ぐにロードされます。
スクリプトの処理が完了した直後にアンロードされます。
プログラムがアンロード(チャートから削除された)された時、
クライアントターミナルは
グローバル変数の初期化を行い、イベントキューを削除します。
これは、全ての
文字列型変数のリセットを意味し、
デストラクタの呼び出しと
動的配列の割り当てが解除されます。
入力パラメータとソースコードのコンパイル
チャート上で起動しているプログラムのソースコードを再コンパイルした場合、
以前のプログラムはチャートから削除され、新しいプログラムが実行されます。
入力パラメータセットは、再コンパイル後に変更されていない場合は、以前指定したパラメータ値が適用されます。
そうでなければデフォルト値が使用されます。
■入力パラメータが変更されるケース
・入力パラメータの数が変更された
・入力パラメータの順序が変更された
・入力パラメータの名称が変更された
・1つ以上の入力パラメータの型が変更された
パラメータのデフォルト値を変更する事は、
入力パラメータセットの変更では無いと認識されます。
入力パラメータセットは、ターミナルの実行システム内のプログラムを明確に識別します。
このセットが変更されていない場合、
実行ファイルの新しいバージョンはプログラムの機能とロジック全体を保持すると見なされます。
入力パラメータセットが変更された場合、
ターミナルは前回チャート上で起動されたプログラムと同様に、互換性の無い新しい実行可能ファイルと見なします。
したがって、入力パラメータを変更したソースコードで再コンパイルされたプログラムはデフォルト値の入力パラメータセットで起動します。
他のケース(パラメータのデフォルト値変更を含む)では、前回指定したパラメータは再コンパイル後に適用されます。
OnInit()関数はコンパイル後に呼び出されます。
その目的は、プログラムの全ての
グローバル変数と
静的変数を正確に初期化する為です。
プログラムの入力パラメータの値はOnInit()イベントハンドラで正しく使用する必要があります。