関数
全てのタスクはサブタスクに分割することができ、それぞれが直接コードの形で表されるか更に小さいサブタスクに分割することが出来ます。このメソッドは段階的詳細化と呼ばれています。関数はサブタスク解決のコードを記述するために使用されます。関数が実行する内容を記述したコードは 関数定義と呼ばれます。
function_header |
最初のブレースの前にあるのは関数定義のヘッダのみで、ブレースに挟まれているのが関数定義の 本体 です。関数ヘッダーは、戻り値の型、名称(識別子)と仮パラメータの記述を含みます。関数に渡されるパラメータの数は限られており、64 を超えることは出来ません。
関数は、プログラムの他の部分から必要に応じて何回でも呼び出すことが出来ます。実際には、戻り値の型、関数識別子とパラメータ型が関数のプロトタイプを構成します。
関数プロトタイプは、関数宣言ではなく関数定義です。戻り型の明示的な宣言と引数の型のリストによって関数呼び出し時に厳密な型チェックと暗黙の型キャストが可能です。非常に多くの場合、コードの可読性を向上させるために関数の宣言はクラス内で行われています。
関数定義は、確実に宣言と一致する必要があります。宣言された関数は全て定義される必要があります。
例:
double // 戻り値の型 |
return 演算子は自己に含まれる式の値を返すことが出来ます。必要であれば、式の値は関数結果の型に変換されます。返せるものとしては、基本データ型、基本構造体、及びオブジェクトポインタがあります。return 演算子は、配列、クラスオブジェクトや複合構造体の変数を返すことは出来ません。
値を返さない関数は void 型として記述されるべきです。
例:
void errmesg(string s) |
関数に渡されたパラメータは、その型の定数によって定義された初期値を持つことが出来ます。
例:
int somefunc(double a, |
パラメータのいずれかが初期値を持つ場合、それ以降の全てのパラメータは、初期値を持たなければいけません。
下記は不正な宣言の例です。
int somefunc(double a, |
関数の呼び出し
以前に記載されていない名称が式の中で表示され左括弧が続く場合、それは文脈上で関数の名称とみなされます。
関数名 (x1, x2,…, xn) |
引数(仮パラメータ)は値によって関数に渡されます。つまり x1、•••、XN の各式が算出されその値が関数に渡されます。式の計算順序と値の読み込みの順序は保証されていません。実行中に、システムは関数に渡される引数の数と型をチェックします。このように関数に対処する方法は値渡しと呼ばれています。
関数呼び出しは、関数によって返される値を値とする式です。上記で説明された関数の型は戻り値の型と一致する必要があります。関数はプログラムのグローバルスコープ の任意の部分、つまり関数の外側で宣言または記述されることが出来ます。関数は別の関数の内部で宣言されたり記述されたりすることは出来ません。
例:
int start() |
デフォルトパラメータを使用した関数の呼び出しでは、渡されるパラメータのリストは制限されることがありますが、最初のデフォルトパラメータの前では無制限です。
例:
void somefunc(double init, |
関数を呼び出す時は、初期値を持つパラメータも抜かせません。
somefunc(3.14, , 10); // 不正な呼び方( 2 番目のパラメータが抜かされた) |
パラメータの引き渡し
機械語がサブプログラム(関数)に引数を渡す方法は 2 つあります。1 番目の方法はパラメータの値渡しです。この方法では、引数値が仮関数引数に複製されます。従って、関数内でのこのパラメータの変更は、対応する呼び出しの引数に影響を及ぼしません。
//+——————————————————————+ |
2 番目の方法は、参照渡しです。この場合、(値でなく)パラメータへの参照が関数パラメータに渡されます。それが、関数の内部で、呼び出しで指定された実際のパラメータを参照するために使用されます。従って、パラメータの変更は関数の呼び出しに使用される引数に影響を与えます。
//+——————————————————————+ |
MQL5 言語では、配列、構造型の変数やクラスオブジェクトは常に参照によって渡されますが、その例外を除いて両方法が使用されます。実際のパラメータ(関数呼び出しで渡される引数)の変化を避けるには const アクセス指定子を使用します。const 指定子で宣言された変数の内容を変更しようとするとコンパイラがエラーを生成します。
注意事項
パラメータは逆の順序で関数に渡されること、すなわち、最後のパラメータが最初に計算されて、最後から 2 つ目のパラメータが次に計算されて引き渡されることには留意すべきです。最後に計算されて渡されたパラメータは、括弧を開いた後の最初のパラメータです。
例:
void OnStart() func(a[i],a[i++],“First call (i = “+string(i)+“)”); } |
最初の呼び出し(上記の例を参照)では、i 変数は最初に文字列の連結に使用されます。
“First call (i = “+string(i)+“)” |
ここではその値は変更されません。その後 i 変数は a[i++] 配列要素の計算に使用されます。インデックス付き配列要素iがアクセスされた時、i 変数は 増加されます。そしてこの後初めて最初のパラメータが変更された i の値をもって計算されます。
2 番目の呼び出しでは、同じ i の(関数呼び出しの最初の段階で計算された)値が 3 つのパラメータの全てを算出する際に使用されます。最初のパラメータが算出された後で初めて i 変数がもう一度変更されます。
関数の多重定義(オーバーロード)
通常、関数名にはその主な目的を反映する傾向があります。原則として、人間によって読まれるのが可能なプログラムには、うまく選択された 識別子が含まれます。しかし、たまに 1 つの目的のために複数の関数が使用されることがあります。例として、double の配列の平均値を算出する関数と整数の配列の平均値を算出する関数について考えましょう。両方とも AverageFromArray と呼ぶのが便利です。
//+——————————————————————+ |
どちらの関数も Print() 関数を使用してメッセージを出力します。
Print(“Calculation of the average for an array of int type”); |
コンパイラは、引数の型と数に応じて必要な関数を選択します。このような選択ルールは署名マッチングアルゴリズムと呼ばれます。署名とは、関数宣言で使用される型のリストです。
例:
//+——————————————————————+ |
関数オーバーロードとは、パラメータが異なるいくつかの同名の関数を作成する過程です。つまり、関数のオーバーロードバリアントでは引数の数及び/またはその型は異なっていなければなりません。特定の関数バリアントは、関数宣言のパラメータのリストと関数を呼び出す引数のリストの対応関係に基づいて選択されます。
オーバーロードされた関数が呼び出されると、コンパイラに適切な関数を選択するためのアルゴリズムが存在する必要があります。この選択アルゴリズムは存在する型のキャストに基づきます。最良のマッチは一意である必要があります。オーバーロードされた関数は、少なくとも 1 つの引数にとって全てのバリアントの内で最良のマッチである必要があります。同時に、他の全ての引数に対しての一致も他のバリアントに劣らない必要があります。
以下は各引数のマッチングアルゴリズムです。
オーバーロード関数選択アルゴリズム
- (可能な場合)厳密なマッチングを使用します。
- 標準型の増加を試します。
- 標準型キャストを試します。
標準型の増加は、他の標準的な変換よりも優れています。増加とは float を double、bool、char、short 及び enum を intに変換することです。類似の 整数型 配列の型キャストも型キャストに属します。類似の型は次の通りです。シングルバイト整数である bool、char、及び uchar の 3 型。ダブルバイト整数である short と ushort。 4 バイト整数の int、uint 及び color。long、ulong、及び datetime。
厳密なマッチングが一番です。このような一貫性を達成するために型キャスト を使用することが出来ます。コンパイラは、あいまいな状況に対処することは出来ません。従って、オーバーロード関数をあいまいにする型の微妙な違いや暗黙の変換に依存してはいけません。
はっきりしない場合には厳格な遵守を確保するために明示的な変換を使用してください。
MQL5 におけるオーバーロード関数の例は ArrayInitialize() 関数の例でご覧になれます。
関数オーバーロードの規則はクラスメソッドのオーバーロードにも適応されます。
システム関数のオーバーロードは可能ですが、コンパイラが正確に必要な関数を選択することが出来なければいけません。例えば、システム関数 MathMax() のオーバーロードの仕方は 4 つありますが、そのうち2 つのみが正しいものです。
例:
// 1. オーバーロードは可能 – 関数は内蔵された MathMax() と違う数のパラメータを持つ // 2. オーバーロードは不可能 // 3. オーバーロードは可能 – パラメータ a と b の型による通常のオーバーロード // 4. オーバーロードは不可能 |
演算子の多重定義(オーバーロード)
コードの読み込みと書き込みを容易にするためには、いくつかの演算のオーバーロードが可能です。演算子のオーバーロードは、キーワード operator を使用して書かれます。可能な演算子のオーバーロードは次の通りです。
- 二項 +、-、/、*、%、<<、>>、==、!=、<、>、<=、>=、=、+=、-=、/=、*=、%=、&=、|=、^=、<<=、>>=、&&、||、&、|、^
- 単項 +、-、++、–、!、~
- 代入演算子 =
- インデックス作成演算子 []
操作のオーバーロードは構造体とクラスのように複雑なオブジェクトの(単純な式の形で書かれた)演算の表記を可能にします。より複雑な実装が隠されているので、オーバーロードを使用して演算の式を書くことでソースコードの表示が簡素化します。
例えば、実部と虚部で構成された複素数を見てみましょう。これらは数学で幅広く使用されています。MQL5 言語には複素数を表現するデータ型がありませんが構造体やクラスを使用して新しいデータ型を作成することが可能です。複雑な構造体を宣言し、四則演算を実装する 4 つのメソッドを定義してみます。
//+——————————————————————+ |
さて、コードで複素数を表す変数を宣言して使用することが出来ます。
例えば、
void OnStart() |
しかし複素数の算術演算に「/」、「+」、「-」、「*」及び「/」の 通常の演算子を使用するのが便利です。
Keyword 演算子は型変換を実行するメンバ関数の定義に使用されます。クラスオブジェクトの変数の単項及び二項操作は非静的メンバ関数としてオーバーロードすることが出来ます。これらは暗黙的にクラスオブジェクトに使用されます。
ほとんどの二項演算は、クラス変数、またはこのクラスオブジェクトへのポインタなどの 1 つまたは両方の引数を受ける通常の関数のようにオーバーロードすることが出来ます。例の複素数型は、宣言でオーバーロードすると、次のようになります。
//— 演算子 |
スクリプトの完全な例は下記です。
//+——————————————————————+ |
ほとんどの単項演算は、クラス変数、またはこのクラスオブジェクトへのポインタなどの引数を受ける通常の関数のようにオーバーロードすることが出来ます。ここでは単項演算子「 – 」と「 ! 」のオーバーロードを追加します。
//+——————————————————————+ |
複素数の値がゼロかをチェックし、負の値を取得します。
//+——————————————————————+ |
基本データ型の構造体 は互いに直接にコピー出来るため、代入演算子「 = 」のオーバーロードは必要がなかったことにご注目ください。このように通常の方法で複素数を含む計算のコードを書くことが出来ます。
索引付け演算子のオーバーロードは、単純かつなじみ深い方法で、オブジェクトで囲まれた配列の値を取得することができ、ソースコードの読みやすさに貢献します。例えば、文字列内の指定された位置にあるシンボルへのアクセスを提供する必要があるとします。MQL5 言語の文字列はシンボルの配列ではない別の string 型ですが、インデックス演算のオーバーロードの助けを借りて、生成された CString クラスで単純かつ分かりやすい利用法を提供することが出来ます。
//+——————————————————————+ public: |
索引操作のオーバーロードの別例は、行列演算です。行列は配列のサイズが予め定義されていない 2 次元の動的配列を表します。従って、2 次元目のサイズを指定せずに array[][] の形式で配列を宣言することも、パラメータとしてこの配列を渡すことも出来ません。可能な解決策は、CRow クラスオブジェクトの配列が含まれている特別なクラス CMatrix です。
//+——————————————————————+ //— 行列の加算 //— 行列の乗算 //— 次に動的配列 matrix[i][j] のスタイルで値を取得する方法を示す public: |
外部関数の記述
別のモジュールで定義された外部関数は明示的に記述されるべきです。記述は、戻り型、関数名及び入力パラメータとその型を含みます。そのような記述が存在しないとコンパイル、ビルド、またはプログラムの実行中にエラーが起こることがあります。外部オブジェクトを記述する時は#import キーワードを使用してモジュールを示します。
例:
#import “user32.dll” |
import の助けを借りれば、外部 DLL またはコンパイル済みの EX5 ライブラリから呼び出される関数の記述が容易に出来ます。EX5ライブラリは library プロパティを持つ、コンパイル済みの ex5 ファイルです。export 修飾子 のついた関数のみが EX5 ライブラリからインポート出来ます。
DLL と EX5 ライブラリが一緒にインポートされる場合は(配置されているディレクトリに関係なく)別の名称を持つ必要があるのでご注意ください。インポートされた関数は全てライブラリの「ファイル名」に対応するスコープの解像度を持っています。
例:
#import “kernel32.dll” class CFoo void OnStart() |
関数のエクスポート
MQL5 プログラムで export 後置修飾語とともに宣言された関数は別の MQL5 プログラムで使用することが出来ます。このような関数は、エクスポータブル(エクスポート可能)と呼ばれ、コンパイル後に、他のプログラムから呼び出すことが出来ます。
int Function() export |
この修飾子は、この EX5 ファイルによってエクスポートされる EX5 関数の表にこの関数を追加するようにコンパイラに指示します。この修飾子を持った関数のみが他の MQL5 プログラムから使用可能また可視です。
library プロパティは、この EX5 ファイルがライブラリになることをコンパイラに伝え、コンパイラがそれを EX5 のヘッダに表示します。
エクスポート可能として計画されている全ての関数は、export 修飾子でマークされる必要があります。
イベント処理の関数
MQL5 言語はいくつかの定義済みイベントの処理を提供します。これらのイベントを処理するための関数は MQL5 プログラムで定義されている必要があります。関数名、戻り値の型、パラメータの組成物(もしあれば)と型は、イベントハンドラ関数の記述に厳格に適合しなければなりません。
クライアント端末のイベントハンドラは、戻り値とパラメータの型によって、各イベントハンドラ関数を識別します。以下の説明に対応していないパラメータが指定された場合、また別の戻り値の型が使用された場合、その関数はイベントハンドラとして使用されません。
OnStart #
OnStart() 関数は Start イベントハンドラでスクリプトの実行のみに自動的に生成されます。この関数はvoid 型でパラメータを持ってはいけません。
void OnStart(); |
OnStart() 関数では int 型の戻り値を指定することが出来ます。
OnInit #
OnInit() 関数は Init イベントハンドラです。この関数は void または int 型でパラメータを持ちません。
void OnInit(); |
Initイベントは、エキスパートアドバイザーや指標がダウンロードされた直後に生成されます。このイベントは、スクリプトには生成されません。OnInit() 関数は初期化に使用されます。OnInit() がint 型の戻り値を持つ場合、ゼロ以外のリターンコードは失敗した初期化を意味し初期化解除の理由である REASON_INITFAILED のコードを含む Deinit イベントが生成されます。
エキスパートアドバイザーの入力パラメータを最適化するためには、リターンコードとして 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 アプリケーションから OrderSend と OrderSendAsync 関数を使用して取引リクエストを送信し、取引が実行される。
- 端末のグラフィカルインターフェースを使用して取引リクエストを送信し、取引が実行される。
- サーバ上で未決注文と逆指値注文が執行される。
- 取引サーバ側で操作を行う。
これらのアクションの結果として以下の取引トランザクションが実行されます。
- 取引リクエストの処理
- 未執行注文の変更
- 注文履歴の変更
- 約定履歴の変更
- ポジションの変更
例えば、買いの成行注文を送信すると、注文が処理され、買い注文が口座に記録されます。その後注文が実行されオープン注文の表から削除されて注文履歴に追加されます。 約定が履歴に追加され新しいポジションが作成されます。これらのアクションは全て取引トランザクションです。このようなトランザクションの端末への到着が TradeTransaction イベントです。それは OnTradeTransaction ハンドラを呼びます。
void OnTradeTransaction( |
ハンドラには 3 つのパラメータがあります。
- trans – このパラメータは取引口座に適用される取引トランザクションを記述する MqlTradeTransaction 構造体を取得します。
- request – このパラメータは取引リクエストを記述する MqlTradeRequest 構造体を取得します。
- result – このパラメータは取引リクエスト実行の結果を記述する MqlTradeResult 構造体を取得します。
最後の 2 つの request と result パラメータはTRADE_TRANSACTION_REQUEST 型のトランザクションでのみ値が書き入れられます。トランザクションのデータは trans 変数の type パラメータから受け取られます。この場合 result 変数の request_id フィールドは request 取引リクエストのIDを含んでいます。実行後は trans 変数で記述された 取引トランザクションが終了しています。リクエストIDは実行されるアクション(OrderSend または OrderSendAsync 関数の呼び出し)と OnTradeTransaction() に送られたアクションの結果を関連付けることが出来ます。
手動で端末から送信された、または OrderSend()/OrderSendAsync() 関数によってリクエストされた 1 つの取引リクエストが取引サーバ上で複数の連続したトランザクションを生成することがあります。端末におけるこれらのトランザクションの到着の優先順位は保証されません。よって取引アルゴリズムを開発する際にトランザクション到着の順番を仮定すべきではありません。
|
取引トランザクションは、クライアント口座への適用後、端末の取引トランザクションのキューに置かれます。ここから端末への到着順に OnTradeTransaction エントリーポイントに送られます。
OnTradeTransaction ハンドラを使用してエキスパートアドバイザーによって取引トランザクションを取り扱う場合、端末は新たに到着した取引トランザクションの取り扱いを継続します。そのため、取引口座の状態はすでに OnTradeTransaction 動作中に変更することがあります。例えば、MQL5 プログラムが新しい注文を追加するイベントを処理している間に、注文が、実行可能の未執行注文のリストから削除され、履歴に移動されることもあります。更にアプリケーションはこれらのイベントの通知を受けます。
トランザクションキューは 1,024 要素を備えます。OnTradeTransaction が新しいトランザクションを処理するのに長くかかりすぎると、代わりにキュー内の新しいトランザクションが処理されることがあります。
|
OnTester #
OnTester() 関数は自動的に選択された区間のエキスパートアドバイザーの履歴テストの後に生成される Tester イベントのハンドラです。この関数は double 型でパラメータを 2 つ持ちます。
double OnTester(); |
この関数は OnDeinit() 呼び出しの直前に呼び出され、同様に double の戻り値を返します。OnTester() はエキスパートアドバイザーのテストに使用出来ます。この関数の主な目的は入力パラメータの遺伝的最適化におけるカスタム最大基準として使用される特定の値を計算することです。
遺伝的最適化では一世代内の結果に降順のソートが適用されます。すなわち最適化基準の観点からすると、最良の結果は(OnTester 関数によって返されるカスタム最大の最適化基準値が考慮されるので)最大値を有するものです。このようなソートでは最悪値が終わりに配置されるので次の世代の形成に関与しません。
OnTesterInit #
OnTesterInit() 関数は、ストラテジーテスターでエキスパートアドバイザーの最適化が始まる前に自動的に生成される TesterInit のハンドラです。この関数は void 型で定義される必要があります。パラメータはありません。
void OnTesterInit(); |
最適化が始まると、エキスパートアドバイザーは 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, // イベント識別子 |
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[] 配列のサイズ |
price[] 配列のように、時系列またはいくつかの指標の計算されたバッファが渡されます。price[] 配列内の索引付けの方向を決定するためには ArrayGetAsSeries()を呼び出します。初期値への依存を避けるためにはこれらの配列に対して ArraySetAsSeries() 関数を無条件に呼び出す必要があります。
price[] 配列として使用される必要な時系列または指標は指標開始時に「パラメータ( Parameters )」タブでユーザ選択が出来ます。そのためには「適用( Apply to )」フィールドのドロップダウンリストに必要な項目を指定する必要があります。
他の MQL5 プログラムからカスタム指標の値を受信するには、その後の操作のための指標ハンドルを返すiCustom() 関数が使用されます。また、当該なprice[] 配列または他の指標ハンドルを指定することが出来ます。このパラメータは、カスタム指標の入力変数のリストに最後に送信されるべきです。
例:
void OnStart() |
この例では、最後のパラメータは PRICE_TYPICAL 値です(ENUM_APPLIED_PRICE 列挙から)。これは、カスタム指標が (高値+安値+終値)/3 で取得された典型的な価格に基づいて構築されることを示します。このパラメータが指定されていない場合は、指標は PRICE_CLOSE 値、すなわち各足の終値に基づいて構築されます。
price[] 配列を指定するために最後のパラメータに指標ハンドラを渡すもう 1 つの例は iCustom() 関数の説明にてみられます。
2 番目の定義は、計算のために複数の時系列を使用する指標のために意図されています。
int OnCalculate (const int rates_total, // 入力時系列のサイズ |
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 |
Originally posted 2019-07-27 10:14:29.