ArraySwap関数の働き・役割
ArraySwap関数は、同じ型の2つの動的配列の内容を交換するために使用されます。この関数により、配列同士のデータを簡単に入れ替えることができます。特に、多次元配列の場合は最初の次元以外のすべての次元において、要素数が一致している必要があります。
例えば、価格データなどの金融情報を扱う際に、異なる配列間でデータを交換するケースが考えられます。ArraySwap関数を利用すれば、元の配列と交換先の配列の内容を効率的に入れ替えることが可能です。
ArraySwap関数の引数について
bool ArraySwap(
void& array1[], // 1番目の配列
void& array2[] // 2番目の配列
);
ArraySwap関数は、2つの同じ型の動的配列を引数に取ります。それぞれの配列間でデータを交換する際に使用されます。多次元配列の場合は、最初の次元以外の要素数が一致している必要があります。
引数1: array1[]
1番目の配列です。数値型の動的配列が指定されます。ArraySwap関数を使用すると、この配列の内容が2番目の配列と交換されます。
引数2: array2[]
2番目の配列です。こちらも数値型の動的配列が指定され、1番目の配列と同様にこの配列の内容が1番目の配列と交換されます。
いずれの引数も[in][out]パラメータとして機能し、配列同士のデータが交換されるため、呼び出し後に引数で指定された配列の内容はお互いに入れ替わります。
ArraySwap関数の戻り値について
ArraySwap関数は、処理が成功した場合にはtrueを返します。もしエラーが発生した場合はfalseを返し、GetLastError関数を使用することでエラーコードが確認できます。例えば、引数に指定された配列のサイズや次元が一致しない場合、エラーコードERR_INVALID_ARRAYが返されます。
ArraySwap関数を使う際の注意点
2つの配列は同じデータ型である必要があります。異なる型の配列同士では、ArraySwap関数を使用することはできません。符号の違いに関しては無視されるため、char型とuchar型のように符号が異なる場合でも問題なく使用できます。
ArraySwap関数を使ったサンプルコード
//+------------------------------------------------------------------+
//| スクリプトプログラムを開始する関数 |
//+------------------------------------------------------------------+
void OnStart()
{
//--- 相場データを格納するための2つの配列を定義(2次元配列)
// それぞれ8つの要素(時間、始値、高値、安値、終値、ティックボリューム、スプレッド、実ボリューム)を持つ
double source_array[][8]; // データをコピーする元の配列
double dest_array[][8]; // データを交換する先の配列
//--- MqlRates構造体を使用して、ローソク足データ(時間、始値、高値、安値、終値など)を格納する配列を定義
MqlRates rates[];
//--- 現在の時間枠(0=現在の時間枠)で、最後の20本のローソク足のデータを取得
int copied = CopyRates(NULL, 0, 0, 20, rates);
//--- データ取得に失敗した場合のエラーハンドリング
if (copied <= 0) // CopyRates関数が0以下の場合、データ取得失敗
{
//--- エラーメッセージをエキスパートログに出力し、終了する
PrintFormat("CopyRates(%s,0,0,20,rates) failed, error=%d",
Symbol(), GetLastError());
return;
}
//--- 取得したデータの数に合わせて、元配列のサイズを設定
ArrayResize(source_array, copied); // 元の配列のサイズを調整
//--- rates配列のデータを元配列(source_array)にコピー
for (int i = 0; i < copied; i++)
{
source_array[i][0] = (double)rates[i].time; // ローソク足の時間を格納
source_array[i][1] = rates[i].open; // 始値を格納
source_array[i][2] = rates[i].high; // 高値を格納
source_array[i][3] = rates[i].low; // 安値を格納
source_array[i][4] = rates[i].close; // 終値を格納
source_array[i][5] = (double)rates[i].tick_volume; // ティックボリューム(取引回数)を格納
source_array[i][6] = (double)rates[i].spread; // スプレッド(買値と売値の差)を格納
source_array[i][7] = (double)rates[i].real_volume; // 実ボリューム(実際の取引量)を格納
}
//--- source_arrayとdest_arrayのデータを互いに交換する
if (!ArraySwap(source_array, dest_array)) // ArraySwap関数が失敗した場合の処理
{
//--- エラーメッセージをエキスパートログに出力し、終了する
PrintFormat("ArraySwap(source_array,rate_array_2) failed, error code=%d", GetLastError());
return;
}
//--- データ交換後に、元の配列のサイズが0になっていることを確認
PrintFormat("ArraySwap() done: ArraySize(source_array)=%d", ArraySize(source_array));
//--- 交換後の配列のデータをエキスパートログに表示
ArrayPrint(dest_array); // dest_array(交換後の配列)の内容をログに出力
}
サンプルコード解説
このサンプルコードは、ArraySwap関数を用いて2つの動的配列間でデータを交換する内容となっています。ここでは、ローソク足の価格データを取得し、そのデータを2つの配列間で入れ替える処理を行っています。各部分の処理を以下に詳しく解説します。
1. OnStart関数
この関数はスクリプトが実行された際に自動的に呼び出される関数です。サンプルコードでは、この関数内でArraySwap関数を使用し、配列間のデータ交換を行っています。
2. 配列の定義
コード冒頭で、2つの2次元配列source_arrayとdest_arrayが定義されています。これらの配列はそれぞれ、ローソク足の時間、始値、高値、安値、終値、ティックボリューム、スプレッド、実ボリュームといった価格データを格納するために使用されます。また、MqlRates構造体の配列ratesは、MetaTraderが提供するローソク足データを格納するために使用されます。
3. CopyRates関数でデータ取得
CopyRates関数を使って、現在のシンボルと時間枠における直近20本のローソク足データを取得しています。関数の戻り値はコピーされたデータの本数で、この値が0以下の場合はデータの取得に失敗したことを示します。その際、GetLastError関数でエラーコードを取得し、エラーメッセージをエキスパートログに出力します。
4. ArrayResize関数で配列のサイズを調整
取得したローソク足データの数に応じて、source_arrayのサイズをArrayResize関数で調整しています。このステップにより、元配列のサイズが、コピーされたローソク足データの数に一致します。
5. forループによるデータの転送
forループを使用して、rates配列に格納されたローソク足データをsource_arrayに転送します。rates配列には時間、始値、高値、安値、終値などの価格情報が含まれており、各ローソク足の情報がsource_arrayのそれぞれの列に格納されます。
6. ArraySwap関数で配列の内容を交換
ArraySwap関数を使用して、source_arrayとdest_arrayの内容を入れ替えています。ここでは、source_arrayの内容がdest_arrayに移り、逆にdest_arrayの内容がsource_arrayに移ります。関数が失敗した場合にはfalseを返すため、その場合にはエラーメッセージをログに出力します。
7. 配列サイズの確認と出力
ArraySwap関数実行後、source_arrayのサイズが0になっていることを確認するため、ArraySize関数を使用して配列のサイズを確認し、その結果をエキスパートログに出力します。最後に、ArrayPrint関数を使用してdest_arrayの内容を表示し、データが正しく入れ替えられたことを確認します。
ArraySwap関数を使ってEAを作る際のアイディア
ArraySwap関数を活用することで、効率的なデータ管理や配列の操作を行うエキスパートアドバイザー(EA)を作成することが可能です。以下に、そのアイディアをいくつか紹介します。
過去データと現在データの比較
ArraySwap関数を使用して、過去のデータと現在のデータを毎回入れ替えながら保存するEAを作成することができます。たとえば、一定のタイミングで過去のローソク足データを別の配列に移し、その後に新しいデータを取得して分析することで、過去と現在の市場状況の変化を素早く把握できるロジックを実装できます。
トレード戦略の切り替え
異なるトレード戦略に基づく複数のデータセットを保持し、状況に応じてそれらを入れ替えるようなEAを構築することができます。例えば、短期と長期の戦略データを2つの配列に保持し、市場のボラティリティに応じて、それぞれの戦略データを交換しながら実行することが可能です。
マルチシンボルトレード
複数の通貨ペアやシンボルのデータを並行して処理するEAにおいて、シンボルごとのデータを入れ替える際にArraySwap関数を使用することができます。シンボル間のデータの切り替えを効率化し、複数の市場状況を同時に監視・分析することで、より高度なトレードシステムを実装することが可能です。
一時データの入れ替えによるメモリ管理
大量のデータを一度に保持する場合、メモリ管理が重要となります。ArraySwap関数を利用して、不要になったデータと新しいデータを入れ替えることで、メモリ使用量を抑えつつ効率的にデータを保持するEAを作成することができます。これにより、大規模なデータ処理を伴うEAでも安定したパフォーマンスを発揮させることが可能です。
このように、ArraySwap関数を活用することで、柔軟で効率的なデータ操作を行い、より高度なEAの作成が可能になります。複数のデータセットを動的に扱う必要がある場面で特に有用です。