イベント処理の関数

MQL5 言語はいくつかの定義済みイベントの処理を提供します。これらのイベントを処理するための関数は MQL5 プログラムで定義されている必要があります。関数名、戻り値の型、パラメータの組成物(もしあれば)と型は、イベントハンドラ関数の記述に厳格に適合しなければなりません。

クライアント端末のイベントハンドラは、戻り値とパラメータの型によって、各イベントハンドラ関数を識別します。以下の説明に対応していないパラメータが指定された場合、また別の戻り値の型が使用された場合、その関数はイベントハンドラとして使用されません。

OnStart #

OnStart() 関数は Start イベントハンドラでスクリプトの実行のみに自動的に生成されます。この関数はvoid 型でパラメータを持ってはいけません。

void OnStart();

OnStart() 関数では int 型の戻り値を指定することが出来ます。

OnInit #

OnInit() 関数は Init イベントハンドラです。この関数は void または int 型でパラメータを持ちません。

void OnInit();

Initイベントは、エキスパートアドバイザーや指標がダウンロードされた直後に生成されます。このイベントは、スクリプトには生成されません。OnInit() 関数は初期化に使用されます。OnInit() がint 型の戻り値を持つ場合、ゼロ以外のリターンコードは失敗した初期化を意味し初期化解除の理由である REASON_INITFAILED のコードを含む Deinit イベントが生成されます。

INIT_FAILEDを返すと、EAはチャートから強制的にアンロードされます。

INIT_FAILEDを返すと、指標はチャートからアンロードされません。チャート上に残っている指標は動作しません。イベントハンドラは指標内で呼び出されません。

エキスパートアドバイザーの入力パラメータを最適化するためには、リターンコードとして ENUM_INIT_RETCODE 列挙の値を使用することをお勧めします。これらの値は、最適なテストエージェントの選択を含んだ、最適化の過程を整理するために使用されています。テストの開始前に起こるエキスパートアドバイザーの初期化中には TerminalInfoInteger() 関数を使用してエージェントの構成とリソース(コア数、空きメモリの量など)に関する情報を要求することが出来ます。取得された情報に基づいて、エキスパートアドバイザーの最適化の際にこのテストエージェントを使用するかどうかを決めることが出来ます。

ENUM_INIT_RETCODE

識別子

説明

INIT_SUCCEEDED

初期化が成功し、エキスパートアドバイザーのテストを続けることが出来ます。

このコードは NULL 値と同じ意味を持ちます。エキスパートアドバイザーはテスタ内で正常に初期化されています。

INIT_FAILED

初期化に失敗しました。致命的なエラーが起こったのでテストを続ける理由がありません。例えば、エキスパートアドバイザーが機能するのに必要とされる指標の作成に失敗しました。

この戻り値はゼロ以外の値と同じ意味です。 テスタ内でのエキスパートアドバイザーの初期化に失敗しました。

INIT_PARAMETERS_INCORRECT

この値は、入力パラメータの不正確さを意味します。このリターンコードを含む結果文字列は、「一般的な最適化」の表に赤色で強調表示されます。

所定のパラメータセットのエキスパートアドバイザーテストは実行されません。エージェントが新しいタスクを受け取ることが出来ます。

この値を受け取ると、ストラテジーテスターはこのタスクを他のエージェントに再試行のために渡さないことがあります。

INIT_AGENT_NOT_SUITABLE

初期化中にエラーはありませんでしたが、エージェントが何らかの理由でテストに適していません。例えば、メモリ不足、OpenCL サポートの不足などです。

このコードが返された後は、エージェントは この最適化が終了するまでタスクを受信しません。

void型の OnInit() 関数は常時初期化の成功を示します。

OnDeinit #

OnDeinit() 関数は初期化解除中に呼び出され Deinit イベントハンドラでもあります。この関数は void して宣言する必要があり const int 型のパラメータを 1 つ持つ必要があります。このパラメータは 初期化解除の理由のコードです。 違う型が宣言された場合、コンパイラは警告を生成しますが、関数は呼び出されません。スクリプトでは Deinit イベントが生成されないので、OnDeinit() 関数はスクリプトでは使用出来ません。

void OnDeinit(const int reason);

以下の場合 Deinit イベントがエキスパートアドバイザーと指標に生成されます。

  • シンボルまたはチャートの期間の変更に伴う再初期化の前にMQL5 プログラムが接続されている場合
  • プログラムをアンロードする前

OnTick #

NewTick イベントは、エキスパートアドバイザーが接続されたチャートにシンボルの新しいティックが受け取られた時にエキスパートアドバイザのみ に作成されます。カスタム指標またはスクリプトでは NewTick イベントが生成されないので OnTick() 関数を定義するのは無意味です。

Tick イベントは、エキスパートアドバイザーのために生成されますが、エキスパートアドバイザーには NewTick イベントの他に Timer、BookEvent とChartEvent も生成されるので、エキスパートアドバイザーが 必ずしも OnTick() 関数を必要とするわけではありません。この関数は void 型でパラメータを持ちません。

void OnTick();

OnTimer #

OnTimer() 関数は Timer イベントがエキスパートアドバイザーと指標のシステムタイマーによって生成される時に呼ばれます。スクリプトでは利用出来ません。イベントの発生頻度は EventSetTimer() 関数がこのイベントを受け取る通知にサブスクライブする際に設定されます。

特定のエキスパートアドバイザーの timer イベント通知解除にはEventKillTimer() 関数を使用します。この関数は void 型でパラメータを持ちません。

void OnTimer();

OnInit() 関数で EventSetTimer() 関数を一度呼び出すことがお勧めです。また OnDeinit()で EventKillTimer() 関数を一度呼び出すこと も必要です。

エキスパートアドバイザーならびに指標は、全て独自のタイマーで動作しそこからのみイベントを受けとります。MQL5 プログラムが停止した場合、作成されて EventKillTimer() 関数で無効にされていないタイマーは強制的に破壊されます。

OnTrade #

この関数は Trade イベントの発生時に呼ばれます。 このイベントは 出された注文ポジション注文履歴約定履歴の表を変更する時に発生します。取引活動(未決注文を出す、注文を出す、ポジションの決済、ストップ設定、未決注文トリガ)が行われると、注文履歴や約定履歴及びポジションと現在の注文のリストがそれに応じて変更されます。

void OnTrade();

このようなイベントが受け取られた場合(取引ストラテジー条件によって必要な場合)、コード内の取引口座状態を検証するコードを実装する必要があります。OrderSend() 関数の呼び出しが正常に完了し trueが返された場合、取引サーバが注文を実行のためにキューに入れてチケット番号を割り当てたことが意味されます。サーバがこの注文を処理するとすぐに Trade イベントが生成されます。チケット値があれば OnTrade() イベント処理の際にこの値を使用して注文の状態を調べることが出来ます。

OnTradeTransaction #

取引口座にいくつかの明確なアクションを実行すると、状態が変更されます。アクションの例は下記です。

  • クライアント端末内の任意の MQL5 アプリケーションから OrderSendOrderSendAsync 関数を使用して取引リクエストを送信し、取引が実行される。
  • 端末のグラフィカルインターフェースを使用して取引リクエストを送信し、取引が実行される。
  • サーバ上で未決注文と逆指値注文が執行される。
  • 取引サーバ側で操作を行う。

これらのアクションの結果として以下の取引トランザクションが実行されます。

  • 取引リクエストの処理
  • 未執行注文の変更
  • 注文履歴の変更
  • 約定履歴の変更
  • ポジションの変更

例えば、買いの成行注文を送信すると、注文が処理され、買い注文が口座に記録されます。その後注文が実行されオープン注文の表から削除されて注文履歴に追加されます。 約定が履歴に追加され新しいポジションが作成されます。これらのアクションは全て取引トランザクションです。このようなトランザクションの端末への到着が TradeTransaction イベントです。それは OnTradeTransaction ハンドラを呼びます。

void  OnTradeTransaction(
  const MqlTradeTransaction   trans,        // 取引トランザクション構造体
  const MqlTradeRequest&      request,      //リクエスト構造体
  const MqlTradeResult&       result       // 結果構造体
  );

ハンドラには 3 つのパラメータがあります。

  • trans - このパラメータは取引口座に適用される取引トランザクションを記述する MqlTradeTransaction 構造体を取得します。
  • request - このパラメータは取引リクエストを記述する MqlTradeRequest 構造体を取得します。
  • result - このパラメータは取引リクエスト実行の結果を記述する MqlTradeResult 構造体を取得します。

最後の 2 つの requestresult パラメータはTRADE_TRANSACTION_REQUEST 型のトランザクションでのみ値が書き入れられます。トランザクションのデータは trans 変数の type パラメータから受け取られます。この場合 result 変数の request_id フィールドは request 取引リクエストのIDを含んでいます。実行後は trans 変数で記述された 取引トランザクションが終了しています。リクエストIDは実行されるアクション(OrderSend または OrderSendAsync 関数の呼び出し)と OnTradeTransaction() に送られたアクションの結果を関連付けることが出来ます。

手動で端末から送信された、または OrderSend()/OrderSendAsync() 関数によってリクエストされた 1 つの取引リクエストが取引サーバ上で複数の連続したトランザクションを生成することがあります。端末におけるこれらのトランザクションの到着の優先順位は保証されません。よって取引アルゴリズムを開発する際にトランザクション到着の順番を仮定すべきではありません。

  • 全ての取引トランザクションの種類は ENUM_TRADE_TRANSACTION_TYPE 列挙に記述されています。
  • 取引トランザクションを記述する MqlTradeTransaction 構造体はトランザクションの種類によって様々な方法で書き込まれます。例えば TRADE_TRANSACTION_REQUEST 型のトランザクションでは type フィールド(取引トランザクションの種類)の分析のみが必要です。OnTradeTransaction 関数の 1、2 番目のパラメータ( request と result )は追加のデータを得るために分析されなければいけません。詳しくは 取引トランザクション構造体をご覧ください。
  • 取引トランザクションの記述は注文、約定やポジションに関する全ての入手可能な情報の配信を行いません(例えば、コメント)。OrderGet*HistoryOrderGet*HistoryDealGet* また PositionGet* 関数は繊細を取得するために使用されます。

取引トランザクションは、クライアント口座への適用後、端末の取引トランザクションのキューに置かれます。ここから端末への到着順に OnTradeTransaction エントリーポイントに送られます。

OnTradeTransaction ハンドラを使用してエキスパートアドバイザーによって取引トランザクションを取り扱う場合、端末は新たに到着した取引トランザクションの取り扱いを継続します。そのため、取引口座の状態はすでに OnTradeTransaction 動作中に変更することがあります。例えば、MQL5 プログラムが新しい注文を追加するイベントを処理している間に、注文が、実行可能の未執行注文のリストから削除され、履歴に移動されることもあります。更にアプリケーションはこれらのイベントの通知を受けます。

トランザクションキューは 1,024 要素を備えます。OnTradeTransaction が新しいトランザクションを処理するのに長くかかりすぎると、代わりにキュー内の新しいトランザクションが処理されることがあります。

  • 一般的に言って、OnTrade と OnTradeTransaction の呼び出しの数の正確な比率はありません。1 つの OnTrade 呼び出しは 1 つまたは複数の OnTradeTransaction に対応します。
  • OnTrade は当該な OnTradeTransaction の後で呼び出されます。

OnTester #

OnTester() 関数は自動的に選択された区間のエキスパートアドバイザーの履歴テストの後に生成される Tester イベントのハンドラです。この関数は double 型でパラメータを 2 つ持ちます。

double OnTester();

この関数は OnDeinit() 呼び出しの直前に呼び出され、同様に double の戻り値を返します。OnTester() はエキスパートアドバイザーのテストに使用出来ます。この関数の主な目的は入力パラメータの遺伝的最適化におけるカスタム最大基準として使用される特定の値を計算することです。

遺伝的最適化では一世代内の結果に降順のソートが適用されます。すなわち最適化基準の観点からすると、最良の結果は(OnTester 関数によって返されるカスタム最大の最適化基準値が考慮されるので)最大値を有するものです。このようなソートでは最悪値が終わりに配置されるので次の世代の形成に関与しません。

OnTesterInit #

この関数は、 TesterInitイベントが発生してストラテジーテスターでの最適化に先立って必要なアクションが実行されるときに、EAで呼び出されます。この関数の型は 2 つあります。

結果を返すバージョン

int  OnTesterInit(void);

戻り値

int型の値。ゼロは、最適化が開始される前にチャート上で起動されたEAの初期化に成功したことを意味します。

実行結果を返すOnTesterInit() を呼び出すと、プログラムを初期化できるだけでなく、最適化が異常に終了した場合にはエラーコードが返されるため、これを使用することをお勧めします。INIT_SUCCEEDED (0)以外の戻り値はエラーを意味し、最適化は行われません。

結果を返さないバージョンは古いコードとの相互性の為のみに残されています。使用は推奨されません。

void  OnTesterInit(void);

最適化が始まると、エキスパートアドバイザーは OnTesterDeinit() または OnTesterPass() ハンドラと共に自動的にテスタの別の端末チャートに指定された銘柄と期間と読み込み、TesterInit イベントを受けとります。この関数は最適化の開始前にエキスパートアドバイザーの初期化に使用され、更に 最適化の結果の処理をします。

OnTesterPass #

OnTesterPass() 関数は、ストラテジーテスターにおけるエキスパートアドバイザーの最適化の間にフレームが受信された際に自動的に生成されるTesterPass イベントのハンドラです。この関数は void 型で定義される必要があります。パラメータはありません。

void OnTesterPass();

OnTesterPass() ハンドラを持つエキスパートアドバイザーは自動的にテスタの別の端末チャートにテストのために指定された銘柄と期間と読み込まれ、最適化中にフレームが受信された時に TesterPass イベントを受け取ります。この関数は最適化の結果 をその完了を待たずに動的に「その場で」処理するために使用されます。フレームは FrameAdd() 関数を用いて追加されます。この関数は OnTester() ハンドラ—のシングルパスが完了した後で呼ぶことが出来ます。

OnTesterDeinit #

OnTesterDeinit() は ストラテジーテスターでのエキスパートアドバイザーの最適化の終了時に自動的に生成される TesterDeinit イベントのハンドラです。 この関数は void 型で定義される必要があります。パラメータはありません。

void OnTesterDeinit();

TesterDeinit() ハンドラを持つエキスパートアドバイザーは最適化の開始時に自動的にチャートに読み込まれ、終了時にTesterDeinit を受け取ります。この関数は全ての最適化の結果の最終処理のために使用されます。

OnBookEvent #

OnBookEvent() 関数は BookEvent ハンドラです。BookEvent は板情報の変更時にエキスパートアドバイザーと指標のために生成されます。この関数は void 型で、1 つの文字列型のパラメータを持ちます。

void OnBookEvent (const string& symbol);

任意のシンボルの BookEvent イベントを受け取るには MarketBookAdd() 関数を使用して、このシンボルのBookEvent イベント受信を事前に設定する必要があります。特定のシンボルの BookEvent イベントの受け取りを停止するには MarketBookRelease() を呼び出します。

他のイベントとは異なり BookEvent イベントはブロードキャストされます。これは、1 つのエキスパートアドバイザーが MarketBookAdd を使用して BookEvent イベントの受信に加入した場合、OnBookEvent() ハンドラを持っている他のエキスパートアドバイザーの全てがこのイベントを受け取ることを意味します。よってハンドラに const string& symbol パラメータとして渡された銘柄名を分析する必要があります。

OnChartEvent #

OnChartEvent() はChartEvent イベントグループのハンドラです。

  • CHARTEVENT_KEYDOWN — チャートウィンドウがフォーカスされた時のキーストロークのイベント
  • CHARTEVENT_MOUSE_MOVE — マウス移動イベントとマウスクリックイベント(CHART_EVENT_MOUSE_MOVE=true がチャートに設定された場合)
  • CHARTEVENT_OBJECT_CREATE — グラフィックオブジェクトの作成イベント(CHART_EVENT_OBJECT_CREATE=true がチャートに設定された場合)
  • CHARTEVENT_OBJECT_CHANGE — プロパティダイアログを介してのオブジェクトプロパティ変更イベント
  • CHARTEVENT_OBJECT_DELETE — グラフィックオブジェクト削除イベント(CHART_EVENT_OBJECT_DELETE=trueがチャートに設定された場合)
  • CHARTEVENT_CLICK — チャート上でのマウスクリックイベント
  • CHARTEVENT_OBJECT_CLICK — チャートに属するグラフィックオブジェクトでのマウスクリックイベント
  • CHARTEVENT_OBJECT_DRAG — マウスを使用してのグラフィカルオブジェクトの移動イベント
  • CHARTEVENT_OBJECT_ENDEDIT — LabelEditグラフィックオブジェクトの入力ボックスに完成したテキスト編集のイベント
  • CHARTEVENT_CHART_CHANGE  — チャート変更イベント
  • CHARTEVENT_CUSTOM+n — ユーザイベントID( n は0〜65535 )
  • CHARTEVENT_CUSTOM_LAST — カスタムイベントの最大の使用可能なID(CHARTEVENT_CUSTOM +65535)

この関数はエキスパートアドバイザーと指標のみに呼ばれます。この関数は void 型で 4 つのパラメータを持ちます。

void OnChartEvent(const int id,         // イベント識別子
                const long& lparam,   // long 型イベントパラメータ
                const double& dparam, // double 型イベントパラメータ
                const string& sparam // string 型イベントパラメ—タ
 );

OnChartEvent() 関数の入力パラメータはイベントの種類ごとにイベント処理に必要とされる一定の値を有しています。これらのパラメータを使用して渡されたイベントと値は以下の表に記載されています。

イベント

id パラメータ値

lparam パラメータ値

dparam パラメータ値

sparam パラメータ値

キーストロークイベント

CHARTEVENT_KEYDOWN

押されたキーのコード

繰り返し回数(ユーザのキーの長押しがキーストロークの繰り返しとみなされた場合の繰り返し回数)

キーボードボタンの状態を記述するビットマスクの文字列値

マウスイベント CHART_EVENT_MOUSE_MOVE=true がチャートに設定された場合)

CHARTEVENT_MOUSE_MOVE

X 座標

Y 座標

マウスボタンの状態を記述するビットマスクの文字列の値

グラフィックオブジェクトの作成イベント CHART_EVENT_OBJECT_CREATE=true がチャートに設定された場合)

CHARTEVENT_OBJECT_CREATE

作成したグラフィックオブジェクトの名称

プロパティダイアログでのオブジェクトプロパティ変更イベント

CHARTEVENT_OBJECT_CHANGE

変更したグラフィックオブジェクトの名称

グラフィックオブジェクト削除イベント(チャートで CHART_EVENT_OBJECT_DELETE=true の場合)

CHARTEVENT_OBJECT_DELETE

削除したグラフィックオブジェクトの名称

チャート上でのマウスクリックイベント

CHARTEVENT_CLICK

X 座標

Y 座標

チャートに属するグラフィックオブジェクトでのマウスクリックイベント

CHARTEVENT_OBJECT_CLICK

X 座標

Y 座標

イベントが発生したグラフィック•オブジェクトの名称

マウスを使用してグラフィックオブジェクトのドラッグイベント

CHARTEVENT_OBJECT_DRAG

移動したグラフィックオブジェクトの名称

LabelEdit グラフィックオブジェクトの入力ボックスでのテキスト編集完成のイベント

CHARTEVENT_OBJECT_ENDEDIT

テキスト編集が完成した LabelEdit グラフィックオブジェクトの名称

チャート変更イベント

CHARTEVENT_CHART_CHANGE

N 番号を使用したユーザイベントID

CHARTEVENT_CUSTOM+N

EventChartCustom() 関数で設定された値

EventChartCustom() 関数で設定された値

EventChartCustom() 関数で設定された値

OnCalculate #

OnCalculate() 関数は Calculate イベントによって指標値の計算が必要な時にカスタム指標でのみ呼ばれます。これは通常指標が計算されたシンボルの新しいティックが受け取られた時に起こります。この指標はこのシンボルの価格表に接続される必要はありません。

OnCalculate() 関数は int 型の戻り値を持たなければなりません。2 つの定義が可能です。1 つの指標に対してこの関数の両バージョンを使用することは出来ません。

1 番目の定義は単一のデータバッファに基づいて計算することが出来る指標ために意図されています。カスタム平均移動線はこの種類の指標の一例です。

int OnCalculate (const int rates_total,     // price[] 配列のサイズ
                const int prev_calculated, // 以前の呼び出しで処理されたバー
                const int begin,           // 重要データの開始点
                const double& price[]       // 計算対象の配列
  );

price[] 配列のように、時系列またはいくつかの指標の計算されたバッファが渡されます。price[] 配列内の索引付けの方向を決定するためには ArrayGetAsSeries()を呼び出します。初期値への依存を避けるためにはこれらの配列に対して ArraySetAsSeries() 関数を無条件に呼び出す必要があります。

price[] 配列として使用される必要な時系列または指標は指標開始時に「パラメータ( Parameters )」タブでユーザ選択が出来ます。そのためには「適用( Apply to )」フィールドのドロップダウンリストに必要な項目を指定する必要があります。

指標計算に使用する時系列の選択

他の MQL5 プログラムからカスタム指標の値を受信するには、その後の操作のための指標ハンドルを返すiCustom() 関数が使用されます。また、当該なprice[] 配列または他の指標ハンドルを指定することが出来ます。このパラメータは、カスタム指標の入力変数のリストに最後に送信されるべきです。
例:

void OnStart()
 {
//---
  string terminal_path=TerminalInfoString(STATUS_TERMINAL_PATH);
  int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL);
  if(handle_customMA>0)
    Print("handle_customMA = ",handle_customMA);
  else
    Print("Cannot open or not EX5 file '"+terminal_path+"\\MQL5\\Indicators\\"+"Custom Moving Average.ex5'");
 }

この例では、最後のパラメータは PRICE_TYPICAL 値です(ENUM_APPLIED_PRICE 列挙から)。これは、カスタム指標が (高値+安値+終値)/3 で取得された典型的な価格に基づいて構築されることを示します。このパラメータが指定されていない場合は、指標は PRICE_CLOSE 値、すなわち各足の終値に基づいて構築されます。

price[] 配列を指定するために最後のパラメータに指標ハンドラを渡すもう 1 つの例は iCustom() 関数の説明にてみられます。
 

2 番目の定義は、計算のために複数の時系列を使用する指標のために意図されています。

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& tick_volume[], // ティックボリューム
                const long& volume[],       // ボリューム
                const int& spread[]         // スプレッド
  );

open[]、high[]、low[] 及び close[] パラメータは現在の時間軸での始値、高/安値と終値の配列を含みます。time[] パラメータは オープンタイム値の配列、spread[] パラメータはスプレッドの履歴の配列(スプレッドがセキュリティの取引のために提供されている場合)を含みます。volume[] とtick_volume[] パラメータはそれぞれ、取引量とティックボリュームの履歴を含みます。

time[]、open[]、high[]、low[]、close[]、tick_volume[]、volume[] 及び spread[] の索引付けの方法を決定するには ArrayGetAsSeries() を呼び出します。初期値への依存を避けるためにはこれらの配列に対して ArraySetAsSeries() 関数を無条件に呼び出す必要があります。

初めの rates_total パラメータは指標計算に使用出来る、チャートで使用可能なバーの数に相当するバーの数を含みます。

ここで OnCalculate() の戻り値と prev_calculated の 2 番目の入力パラメータとの関係が指摘されるべきです。関数呼び出しの際、prev_calculated パラメータは以前の OnCalculate() 呼び出しに返された 値を持ちます。これは、この関数の前回の実行以降に変更されていない足の反復計算を避けてカスタム指標を計算するための経済的なアルゴリズムを可能にします。

このために、通常は現在の関数呼び出しでの足数を含む rates_total パラメータの値を返すので充分です。価格データが OnCalculate() の最後の呼び出し以降に変更された場合は(履歴ダウンロードや履歴ブランクの書き込み)、端末がprev_calculated 入力パラメータの値をゼロに設定します。

注意事項:OnCalculate がゼロを返した場合、指標値はクライアント端末のデータウィンドウには表示されません。

理解を深めるために、以下にコードが添付されている指標を起動してみてもいいでしょう。

指標の例:

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
//---- Line をプロットする
#property indicator_label1 "Line"
#property indicator_type1   DRAW_LINE
#property indicator_color1 clrDarkBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1  1
//--- 指標バッファ
double         LineBuffer[];
//+------------------------------------------------------------------+
//| カスタム指標を初期化する関数                                            |
//+------------------------------------------------------------------+
int OnInit()
 {
//--- 指標バッファマッピング
  SetIndexBuffer(0,LineBuffer,INDICATOR_DATA);
//---
  return(INIT_SUCCEEDED);
 }
//+------------------------------------------------------------------+
//| カスタム指標の反復関数                                                |
//+------------------------------------------------------------------+
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& tick_volume[],
              const long& volume[],
              const int& spread[])
 {
//--- 現在のシンボルとチャート期間に利用可能なバーの数を取得する
  int bars=Bars(Symbol(),0);
  Print("Bars = ",bars,", rates_total = ",rates_total,",  prev_calculated = ",prev_calculated);
  Print("time[0] = ",time[0]," time[rates_total-1] = ",time[rates_total-1]);
//--- 次の呼び出しのために prev_calculated の値を返す
  return(rates_total);
 }
//+------------------------------------------------------------------+

参照

プログラムの実行クライアント端末イベントイベントの操作