FX・ビットコイン・オプションのシステムトレード開発と取引録

FXとビットコインのシステムトレードの開発録、オプション取引の履歴を書き連ねています。MT4, Pythonで開発しています。

MQL4ブック MT4

配列

スポンサードリンク

配列

 

アプリケーションプログラムによって処理される情報の大部分は配列に含まれています。

配列の概念

 

配列は、共通の名前を持つ1つの型の変数の配列された値の集合です。 配列は、1次元および多次元であり得る。 配列内の次元の最大許容量は4です。 任意のデータ型の配列が許可されます。

配列要素は配列の一部です。 同じ名前とある値を持つ索引付き変数です。

 

イチジク。 整数型の配列の図式表示:a)一次元; b)二次元; c)三次元。

インデックス作成

 

配列要素インデックスは、コンマで区切られた定数、変数または式の形で指定された1つまたは複数の整数値で、角括弧で区切られています。 配列要素インデックスは、配列内の要素の場所を一意的に定義します。 配列要素インデックスは変数識別子(配列名)の後に表示され、配列要素の不可欠な部分です。 MQL4では、インデックスの開始はフォームゼロが使用されます。

各インデックスが角括弧で囲まれているときにインデックスを指定する方法も許容されます。

2次元アレイの最も一般的なアナログは、映画館です。 行番号は最初の索引値、生の場所の数は2番目の索引の値、ビューアは配列要素、ビューアの姓は配列要素の値、シネマチケット(行と場所の指定)はメソッドです配列要素の値にアクセスします。

配列の宣言と配列要素へのアクセス

 

プログラムで配列を使用する前に、配列を宣言する必要があります。 配列は、グローバルレベルとローカルレベルの変数のように宣言できます。 従って、グローバル配列要素の値は、プログラム全体に対して使用可能であり、局所的な値は宣言されている関数に対してのみである。 配列は、クライアント端末のレベルで宣言することはできません。そのため、クライアント端末のグローバル変数は配列に集められません。 配列要素の値は任意の型にすることができます。 すべての配列要素の値は、同じ型、つまり配列宣言で示された型の値です。 配列を宣言するときは、データ型、配列名、および各次元の要素数を指定する必要があります。

配列要素へのアクセスは要素単位で実装されます。つまり、1つのコンポーネントにのみアクセスできます。 配列のコンポーネントの値の型がプログラムで指定されていません。配列コンポーネントの値は、代入演算子を使用して代入または変更できます。

図2の配列要素の値は、 59は次のとおりです。

- 1次元の配列の場合、Mas [4]要素の値は整数34です。

- 2次元配列の場合、Mas [3,7]要素の値は整数28です。

- 3次元配列の場合、Mas [5,4,1]要素の値は整数77です。

注意:配列要素のインデックスの最小値は0(ゼロ)で、配列の宣言で示された対応する次元の要素の数よりも最大値が1小さい。

例えば、配列Mas [10] [15]の場合、最小のインデックス値を持つ要素が要素Mas [0,0]であり、最大のインデックス値を持つ要素が要素Mas [9,14]です。

配列の操作は、標準関数を使用して行うこともできます。 詳細については、開発者のWebサイト( https://docs.mql4.com )のドキュメントまたはMetaEditorの 「ヘルプ」を参照してください。 これらの機能のいくつかはさらに分析されます。

配列の初期化

 

配列は、対応する型の定数によってのみ初期化できます。 1次元および多次元配列は、コンマで区切られた1次元の定数シーケンスによって初期化されます。 シーケンスは中括弧に含まれています:

初期化されたシーケンスでは、1つまたは複数の定数を省略することができます。 そのような場合、対応する数値型の配列要素はゼロで初期化され、文字列型の配列の要素は文字列値 ""(空白のない引用符)で初期化されます。つまり、空行(空白と混同しないでください)。 次のプログラムは配列の値を表示し、配列の値を省略したシーケンスで初期化します(script arrayalert.mq4 ) 。

1次元の初期化された配列のサイズが指定されていない場合は、初期化されたシーケンスに基づいてコンパイラによって定義されます。 配列は、標準関数ArrayInitialize()で初期化することもできます。 すべての配列は静的です。つまり、初期化時に明示的に指定されていなくても静的型です。 これは、配列が宣言されている関数の呼び出しの間に、すべての配列がその値を保持していることを意味します(「変数の型」を参照 )。

 

MQL4で使用されるすべての配列は、ユーザー定義配列(プログラマーのイニシアチブによって作成されます)と配列-timeeries(事前定義された名前とデータ型を持つ配列)の2つのグループに分けられます。 ユーザー定義の配列のサイズと要素の値の定義は、プログラムの作成方法、最終的にはプログラマの意志によって異なります。 ユーザ定義の配列要素の値は、プログラムの実行時間全体で保持され、計算後に変更することができます。 ただし、配列timeseriesの要素の値は変更できません。ヒストリが更新されると、そのサイズは大きくなります。

ユーザー定義配列

 

演算子 'switch'セクションでは、 問題18を分析しました。 もっと複雑にしましょう(言葉で書かれたポイントの数を100に増やして)、配列を使って解決策を見つけましょう。

問題25次の条件が実装されたプログラムを作成します。価格が一定のレベルを超えた場合は、超過額が表示されたメッセージを表示します(最大100ポイント)。 それ以外の場合は、価格がこのレベルを超えないことを知らせます。

問題25の解決方法は、文字列配列を使用することができます(Expert Advisor stringarray.mq4 )。

問題解決の文字列配列Text []が使用されます。 プログラム実行中、配列要素の値は変更されません。 配列はグローバルレベルで(特別な関数の外で)宣言され、初期配列の実行はinit()で行われます。 したがって、特別な関数start()では、各ダニで必要な計算だけが行われます。

Text []配列要素のある部分には、文字列定数の値が割り当てられます。 別の部分には、加算されたサイクルで計算された値が加算されます。

これらの計算の意味は容易に理解できます。インデックスが21から99までの各配列要素(10の倍数を除く)に対応する文字列値が計算されます。 行に指定されたインデックスの値に注意してください。

インデックス値として変数(その値はサイクルで変更されます)と式が使用されます。 変数iとjの値に応じて、プログラムは対応するText []配列要素を参照し、それらの値を合計し、その結果がインデックス(i + j)を持つ配列要素に代入します。 例えば、ある計算段階で、iの値が30に等しく、jの値が7に等しい場合、値が合計される要素の名前は対応してText [30]およびText [7]、要素の名前結果が割り当てられるのはText [37]です。 ab型配列要素の値として、整数型の他の変数を使用できます。 この例では、start()関数の中で、デルタを持つ同じ配列の要素名が使用されています。

特別な関数start()は簡単なコードを持っています。 デルタの値に応じて計算が行われます。 100点以下の場合は、対応するメッセージが表示された後にstart()の実行が終了します。 値が指定された範囲内にある場合は、問題の状況に応じてアラートが表示されます。

イチジク。 EA stringarray.mq4で希望の値を表示する。

問題25の解に注意を払う。問題25に同じ解を使用した場合、演算子 'スイッチ'には約100行(各解法ごとに1行)が含まれる。 このようなプログラム開発へのアプローチは、満足のいくものとはみなされません。 さらに、このようなソリューションは、数十万、場合によっては数十万の変数値を処理する必要がある場合には役に立たない。 そのような場合、配列の使用は正当化され、非常に便利です。

配列 - タイムズ

 

Array-timeseriesは、あらかじめ定義された名前(Open、Close、High、Low、VolumeまたはTime)を持つ配列で、その要素には履歴バーの対応する特性の値が含まれます。

配列timseriesに含まれるデータは、非常に重要な情報を持ち、MQL4でのプログラミングに広く使用されています。 各配列 - timeseriesは1次元配列で、1つの特定のバー特性に関する履歴データを含んでいます。 各バーは、オープン価格[]、クローズ価格クローズ[]、最大価格ハイ[]、最小価格ロー[]、ボリュームボリューム[]およびオープニング時間[]によって特徴付けられる。 たとえば、array-timeseries Open []は、セキュリティウィンドウにあるすべてのバーの価格を開きます。配列要素の値[1]は最初のバーの開始価格、Open [2]は2番目のバーなどです。他の時系列でも同じことが言えます。

ゼロバーはまだ完全に形成されていない現在のバーです。 チャートウィンドウでは、ゼロバーが最後の右のものです。

バー(および配列の対応するインデックス - 時系列データ)のカウントは、ゼロ・バーから開始されます。 インデックス[0]を持つarray-timeseries要素の値は、ゼロ・バーを特徴付ける値です。 たとえば、Open [0]の値はゼロバーの開始価格です。 イチジク。 図61は、バーの数とバー特性(マウスカーソルが画像に移動されたときのチャートウィンドウに反映される)を示す。

イチジク。 各バーは、配列 - 時間系列に含まれる値のセットによって特徴付けられる。
バーのカウントはゼロバーから開始します。

図中のゼロバー。 61には以下の特徴があります。

インデックス 開いた[] 閉じる[] 高い[]、 Low []、 時間[]
[0] 1.2755 1.2752 1.2755 1.2752 2006.11.01 14:34

しばらくすると、現在のバーが形成され、セキュリティバーに新しいバーが表示されます。 今度はこの新しいバーがゼロのバーになり、1つの帽子がちょうど形成されたものが最初のものになります(インデックス1)。

イチジク。 数字はシフトされないが、バーはある時間後にシフトされる。

array-timeseries要素の値は次のようになります。

インデックス 開いた[] 閉じる[] 高い[]、 Low []、 時間[]
[0] 1.2751 1.2748 1.2752 1.2748 2006.11.01 14:35
[1] 1.2755 1.2752 1.2755 1.2752 2006.11.01 14:34

さらに、セキュリティウィンドウに新しいバーが表示されます。 現在のまだ未完成の最も右側のバーは常に0になり、その左側のバーが最初のバー、次のバー、2番目のバーなどになります。ただし、バーの特性は変更されません。この例のバーは開いています14:43に、そして彼の開かれた価格は14:43のままである、その他のパラメータも変わらないままである。 ただし、新しいバーの出現後にこのバーのインデックスが増加します。

したがって、配列timeseriesに関する最も重要な機能は次のとおりです。

array-timeseries要素の値はバーの適切な特性であり、(ゼロバーの次の特性を除いて、変更されます:Close [0]、High [0]、Low [0]、Volume [0])、バーのインデックスは現在の瞬間のために未来に深化し、時間の経過とともに変化しています。

また、バーの開時間は、カレンダー時間の倍数でカウントされ、秒は考慮されないことにも注意してください。 言い換えれば、14:34から14:35までの期間に14:34:07に新しいチックがあると、14:43の開始時間を持つ新しいバーが分の時間枠内に表示されます。 したがって、15分の時間枠内のバーの開き時間は15分の倍数であり、1時間の間隔内で最初のバーはn時間00分に開き、2番目のバーはn:15で、3番目のバーはn: - n:45で。

時系列でのインデックスの重要性を正しく理解するには、簡単な問題を解決しましょう:

問題26.最後のn個のバーの中で最小値と最大値を求めよ。

注意してください、配列の値を参照することなく、このような問題の解決は不可能ですtimeseries。 予め設定された最後のバーの最大値と最小値を定義するエキスパートアドバイザーは、次の解を持つことができます( extremumprice.mq4 )。

プログラム極座標mq4では 、単純なアルゴリズムが使用される。 分析するバーの量は、外部変数Quant_Barsに設定されます。 プログラムの開始時に、現在の価格値が希望の最小値と最大値に割り当てられます。 最大値と最小値の検索は、サイクル演算子で実行されます。

ここでは、処理された配列 - 時系列要素Low [i]とHigh [i]のインデックス値(整数変数i)の間隔を記述します。 サイクル演算子ヘッダーのExpression_1とConditionに注意してください。

最初の反復計算では、ゼロインデックス値を使用して計算が行われます。 これは、最初の反復で、ゼロ・バーの値が分析されることを意味します。 したがって、セキュリティウィンドウに表示された最後の価格値も考慮されることが保証されます。 定義済みの変数セクションには、特別な関数の開始時に配列 - 時系列を含むすべての事前定義された変数の値が更新される規則が含まれています。 したがって、価格の価値のどれもがカウントされないままになります。

1サイクルで処理されるtimeseries要素のリストインデックスは、処理されるバーの数より1だけ小さいインデックスです。 この例では、バーの数は30です。つまり、最大インデックス値は29でなければなりません。つまり、0〜29のインデックスを持つtimeseries要素の値、つまり30バーの値がサイクルで処理されます。

サイクル演算子本体の計算の意味を理解するのは簡単です。

現在の値Low [i](すなわち、現在のインデックス値を有する現在の反復中)が既知の最小値よりも低い場合、それは新しい最小値になる。 同じ方法で最大値が計算されます。 サイクル終了時に、変数の最小値と最大値が目的の値になります。 それ以降の行では、これらの値が表示されます。

このプログラムを起動すると、次のような結果が得られます。

イチジク。 EA 極限操作の結果。

エキスパートアドバイザーが無期限に正確な結果を示し、プログラムは同じインデックス値(この場合は0〜29)を使用することに注意してください。 ゼロインデックスを持つ配列timeseries要素の値は、新しい外観の瞬間に変化し、ゼロバーを特徴付ける配列timeseries要素の値は、次のティックで変化することがあります(Open []とTime []の値は異なります)ゼロバーで変更)。

場合によっては、バーが完全に形成された瞬間からいくつかのアクションを実行する必要があります。 これは、例えば、ろうそく分析に基づくアルゴリズムの実装にとって重要である。 そのような場合には、通常、完全に形成されたバーのみが考慮される。

問題27.各バーの冒頭には、最後に形成されたバーの中で最小値と最大値を持つメッセージが表示されます。

タスクを解決するには、事実を新しいバー開始点、つまりゼロバーで新しいチックを検出するように定義する必要があります。 これを行うための簡単で信頼できる方法があります。ゼロバーの開始時間を分析することです。 ゼロバーの開始時間は、バーの形成中に変化しないバー特性である。 バーが形成されている間に新しいティックが来ると、High [0]、Close [0]、Volume [0]が変更されます。 しかし、Open [0]やTime [0]などの特性は変更されません。

そのため、ゼロバーの開始価格を覚えておけば十分であり、各ティックで最後に知られているゼロバー開始価格と比較することができます。 不一致が見つかるとすぐに、これは新しいバーの形成を意味します(前のバーの完成)。 EA newbar.mq4では、新しいバーを検出するアルゴリズムは、ユーザ定義関数の形で実装されています。

グローバル変数New_Barがプログラムで使用されています。 値が 'true'の場合は、最後の既知のティックが新しいバーの最初のティックであることを意味します。 New_Barの値がfalseの場合 最後の既知のティックは、現在のゼロバーの形成内に現れた。

フラグは変数であり、その値はいくつかの事象または事実に従って定義される。

プログラム内でのフラグの使用は非常に便利です。 フラグの値は、1か所で定義され、異なる場所で使用できます。 時々、プログラム内でアルゴリズムが使用され、異なるフラグの値の組み合わせに応じて決定が行われることがあります。 エキスパートアドバイザーのnewbar.mq4では 、変数New_Barがフラグとして使用されます。 その価値は新しいバー形成の事実に直接依存します。

新しいバーの検出に関する計算は、ユーザ定義関数Fun_New_Bar()に集中する。 関数の最初の行では、静的変数New_Timeが定義されています(静的変数は、関数の実行が終了した後も値が失われません)。 各関数呼び出しで、グローバル変数New_Barの値は 'false'に設定されます。 新しいバーの検出は 'if'演算子で実行されます:

New_Time値(前回の履歴で計算された値)がゼロバーのTime [0]と等しくない場合、新しいバーの形成の事実を示します。 そのような場合、制御は、ゼロバーの新しい開始時間が記憶され、真の値がNew_Barに割り当てられる(オペレータの身体に)制御が渡される(便宜上、フラグが上方位置に設定されていると言える) 。

このような問題を解決するには、異なるフラグを使用することの特異性を考慮する必要があります。 この場合、New_Bar値(フラグ位置)は、計算で使用されるよりも早く更新されなければならない(この場合、特殊関数start())。 New_Bar値はユーザー定義関数で定義されているため、プログラムの早い段階、つまりNew_Barが使用される最初の計算の前に呼び出される必要があります。 特殊関数start()は、それに対応して構築されます。ユーザー定義関数呼び出しは、変数の宣言の直後に実行されます。

start()が新しいバーが形成されるティックによって開始される場合にのみ、望ましい値の計算は価値があります。 そのため、start()では、新しいバーの形成を検出した直後に、フラグ位置(New_Bar値)が分析されます。

start()の実行を開始した最後のティックが新しいバーを形成していない場合、start()の実行を終了するオペレータに制御が渡されます。 そして、新しいバーが形成された場合にのみ、制御は所望の値の計算のために次の行に渡される(問題の規定によって要求されるもの)。

最大値と最小値の計算は、標準関数ArrayMaximum()とArrayMinimum()を使用して実行されます。 各関数は、指定された索引間隔の配列要素索引(対応する最大値と最小値の)を戻します。 問題の条件では、完全に形成されたバーのみを分析しなければならないため、選択した境界インデックス値は1で、Quant_Bars - バーの設定量(ゼロバーはまだ形成されていません。 これらの機能や他のタイムリー機能にアクセスする操作の詳細については、デベロッパーのWebサイト( https://docs.mql4.com )のドキュメントまたはMetaEditorの 「ヘルプ」を参照してください。

イチジク。 図64は、プログラム実行中の予め設定されたインターバルにおける最大値と最小値の変化を示す。

イチジク。 64.エキスパートアドバイザーnewbar.mq4の操作結果。

スポンサードリンク
スポンサードリンク

-MQL4ブック, MT4
-,