プログラム実行

スクリプト及びエキスパートアドバイザーはそれぞれ独自のスレッドで実行されます。1 つのシンボルに基づいて計算される全ての指標は、別々のチャートに接続されている場合でも同じスレッドで動作します。従って、1 つのシンボルの指標全てが1 つのスレッドのリソースを共有します。

ティック処理や履歴同期のような他の全てのシンボルに関連するアクションは、一貫して指標と同じスレッドで実行されます。これは、指標で無限のアクションが実行されている場合は、そのシンボルに関連した他のイベントは一切行われないことを意味します。

エキスパートアドバイザーを実行する際には、それが実際の取引環境を持ち、必要な銘柄と期間の履歴にアクセスでき、端末とサーバのデータ同期が出来ることをご確認ください。これら全ての手順の終了に、端末は、エキスパートアドバイザーが使用可能なデータで開始されるまでのわずか 5 秒の開始遅延を提供します。そのため、サーバへの接続がない場合、エキスパートアドバイザーの開始の遅れが発生する可能性があります。

以下の表には、MQL5 プログラムの概要が含まれています。

プログラム

実行

注意事項

スクリプト

別々のスレッド。スクリプトのスレッド数は、スクリプトの数に等しいです。

反復したスクリプトの実行は、他のプログラムの実行を妨げることは出来ません。

エキスパートアドバイザー

別々のスレッド。エキスパートアドバイザーのスレッド数は、エキスパートアドバイザーの数に等しいです。

反復したエキスパートアドバイザーの実行は、他のプログラムの実行を妨げることが出来ません。

指標。

シンボルの全ての指標に 1 つのスレッド。スレッド数は指標とシンボルの数に等しいです。

1 つの指標での無限ループはこのシンボルの他の全ての指標を停止します。

指標は、プログラムがチャートに装着された直後、グローバル変数が初期化されるとともにクライアント端末のメモリにアップロードされます。クラス型のグローバル変数がコンストラクタを持つ場合、コンストラクタはグローバル変数の初期化中に呼ばれます。

その後プログラムはクライアント端末からのイベントを待機します。MQL5 プログラムには少なくとも 1 つのイベントハンドラがあるべきです。さもないと読み込まれたプログラムが実行されません。イベントハンドラは事前定義された名称、パラメータ、及び戻し型を持っています。

Type

関数名

パラメータ

アプリケーション

コメント

int

OnInit

なし

エキスパートアドバイザーと指標

Init イベントハンドラ。void 戻り値が使用出来ます。

void

OnDeinit

const int reason

エキスパートアドバイザーと指標

Deinit イベントハンドラ。

void

OnStart

なし

スクリプト

Start イベントハンドラ。

int

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 &TickVolume[],

const long &Volume[],

const int &Spread[]

指標

全価格のイベントハンドラを計算します。

int

OnCalculate

const int rates_total,

const int prev_calculated,

const int begin,

const double &price[]

指標

単一データ配列のイベントハンドラを計算します。

指標は 2 つのイベントハンドラを同時に持つことは出来ません。

この場合、唯一のイベントハンドラがデータ配列上で動作します。

void

OnTick

なし

エキスパートアドバイザー

NewTick イベントハンドラ。新しいティックの受け取りイベントが処理されている場合、他の同型のイベントは受ケ入れられません。

void

OnTimer

なし

エキスパートアドバイザーと指標

Timer イベントハンドラ。

void

OnTrade

なし

エキスパートアドバイザー

Trade イベントハンドラ。

double

OnTester

なし

エキスパートアドバイザー

Tester イベントハンドラ。

void

OnChartEvent

const int id,

const long &lparam,

const double &dparam,

const string &sparam

エキスパートアドバイザーと指標

ChartEvent イベントハンドラ。

void

OnBookEvent

const string &symbol_name

エキスパートアドバイザーと指標

BookEvent イベントハンドラ。

クライアント端末は、対応するオープンチャートに新しいイベントを送信します。イベントはチャート(チャートイベント)または MQL5 プログラム(カスタムイベント)によっても生成出来ます。チャート上のグラフィカルオブジェクトの作成または削除のイベントの生成は CHART_EVENT_OBJECT_CREATE 及び CHART_EVENT_OBJECT_DELETE チャートプロパティによって有効または無効に出来ます。それぞれの MQL5 プログラムとチャートは、全ての新しい受信イベントが追加される独自のイベントキューを持っています。

プログラムは、それが動作しているチャートからのイベントのみを受け取ります。全てのイベントは、受信された順に次々に処理されます。キューにすでに NewTick イベントがある場合、またはこのイベントが現在処理中の場合、新しい NewTick イベントは MQL5 プログラムのキューには追加されません。似たように ChartEvent がすでにキューに存在する場合、またはこのイベントが現在処理中の場合、同じ型のイベントはキューには追加されません。timer イベントも同じように扱われ、Timer イベントがキューに存在するか処理中の場合、新しい timer イベントはキューに追加されません。

イベントキューは限られてはいますが充分な大きさを持っています。よく書かれたプログラムでのキューのオーバーフローは起こりにくいです。オーバーフローの場合、新しいイベントはキューに追加されずに廃棄されます。

無限ループを使用してのイベント処理は推奨されません。単一の Start イベントのみを処理するスクリプトは例外です。

ライブラリはイベントを処理しません。

 

指標及びエキスパートアドバイザーで使用出来ない関数

指標、スクリプトとエキスパートアドバイザーは MQL5 で書かれた実行可能なプログラムです。これらは、タスクの種類ごとに設計されています。従って、プログラムの種類によって関数の使用に制限が見られます。下記の関数は指標では使用出来ません。

 

指標用に設計された関数の全ては、エキスパートアドバイザーやスクリプトでは使用出来ません。

ライブラリは独立したプログラムではなく、それを呼び出した MQL5 プログラム(スクリプト、指標またはエキスパートアドバイザー)のコンテキストで実行されます。従って、上記の制限は呼ばれたライブラリにも適用されます。

 

指標のロードとアンロード

指標は、次の場合に読み込まれます。

  • 指標のチャートへの接続
  • 端末の開始(指標が端末のシャットダウン前にチャートに接続された場合)
  • テンプレートの読み込み(チャートに接続されている指標がテンプレートで指定されている場合)
  • プロファイルの変更(指標がプロファイルチャートに接続されている場合)
  • 指標が接続されたチャートのシンボル及び/または時間軸の変更
  • 指標の再コンパイルの成功(指標がチャートに接続されている場合)
  • 端末が接続された口座への接続
  • 指標の入力パラメータの変更

 

指標は、次のような場合にアンロードされます。

  • 指標のチャートからの取り外し
  • 端末のシャットダウン(指標がチャートに接続されている場合)
  • テンプレートの読み込み(チャートに接続されている指標がテンプレートで指定されている場合)
  • 指標が接続されたチャートの閉鎖
  • プロファイルの変更(指標がプロファイルチャートに接続されている場合)
  • 端末が接続された口座への接続
  • 指標が接続されたチャートのシンボル及び/または時間軸の変更

 

エキスパートアドバイザーのロードとアンロード

エキスパートアドバイザーは、次の場合に読み込まれます。

  • エキスパートアドバイザーのチャートへの接続
  • 端末の開始(エキスパートアドバイザーが端末のシャットダウン前にチャートに接続された場合)
  • テンプレートの読み込み(チャートに接続されているエキスパートアドバイザーがテンプレートで指定されている場合)
  • プロファイルの変更(エキスパートアドバイザーがプロファイルチャートに接続されている場合)
  • 口座への接続(口座番号が同一の場合も含む、エキスパートアドバイザーがサーバ上の端末の許可前にチャートに接続された場合)
     

エキスパートアドバイザーは、次の場合にアンロードされます。

  • エキスパートアドバイザーのチャートからの取り外し
  • 新しいエキスパートアドバイザーのチャートへの接続(他のエキスパートアドバイザーが既に接続されている場合、このエキスパートアドバイザーはアンロードされます)
  • 端末のシャットダウン(エキスパートアドバイザーがチャートに接続されている場合)
  • テンプレートの読み込み(チャートに接続されているエキスパートアドバイザーがテンプレートで指定されている場合)
  • 指標が接続されたチャートの閉鎖
  • プロファイルの変更(エキスパートアドバイザーがプロファイルチャートに接続されている場合)
  • 端末が接続された口座への接続(エキスパートアドバイザーがサーバ上の端末の許可前にチャートに接続された場合)

エキスパートアドバイザーが接続されているチャートのシンボルや時間軸が変更した場合、エキスパートアドバイザーはロードやアンロードされません。この場合、クライアント端末が古い銘柄/時間軸で OnDeinit() ハンドラを呼び、新しい銘柄/時間軸が存在する場合はその値で OnInit() を呼びます。グローバル変数及び静的変数の値はリセットされません。初期化の前にエキスパートアドバイザーのために受信された全てのイベントは完了します(OnInit() 関数は抜かされます)。

 

スクリプトのロードとアンロード

スクリプトは、チャートへの取り付けの直後に読み込みられ、操作を完了した直後にアンロードされます。OnInit() 及び OnDeinit() はスクリプトでは呼ばれません。

クライアント端末はプログラムアンロード(チャートからの削除)時にグローバル変数の初期化解除を行い、イベントキューを削除します。この場合、初期化解除とは、全ての string 型変数のリセット、動的配列オブジェクトの 割り当て解除、及び存在する場合はデストラクタの呼び出しです。

エキスパートアドバイザー操作をより良く理解するために、以下のエキスパートアドバイザーのコードをコンパイルし、ロード/アンロード、テンプレートの変更、シンボルの変更、時間軸の変更などのアクションを実行することをお勧めします。

例:

//+------------------------------------------------------------------+
//|                                                   TestExpert.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                             https://www.MQL5.com |
//+------------------------------------------------------------------+
#property copyright "2009, MetaQuotes Software Corp."
#property link     "https://www.mql5.com"
#property version   "1.00"
 
class CTestClass
 {
public:  
  CTestClass() { Print("CTestClass constructor"); }
  ~CTestClass() { Print("CTestClass destructor"); }
 };
CTestClass global;
//+------------------------------------------------------------------+
//| エキスパート初期化に使用される関数                                        |
//+------------------------------------------------------------------+
int OnInit()
 {
//---
  Print("Initialization");
//---
  return(INIT_SUCCEEDED);
 }
//+------------------------------------------------------------------+
//| エキスパート初期化解除に使用される関数                                    |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
 {
//---
  Print("Deinitialization with reason",reason);
 }
//+------------------------------------------------------------------+
//| エキスパートティック関数                                                 |
//+------------------------------------------------------------------+
void OnTick()
 {
//---
 
 }
//+------------------------------------------------------------------+

参照

クライアント端末イベントイベントハンドラ