MQL4 で、配列から要素を削除する時ってみなさんどうされているんでしょうか?push とか splice とかあのへんの一連のコマンドはないみたいです。
必要になって軽く検索したら、方法はあるにはあるらしいんですがなんだかむずかしそう。初心者でも分かるような簡単な配列の扱い方はなかなか見つかりません。
MQL4 で可変長配列を使用する方法
https://strategyofc.blogspot.com/2018/10/mql4.html
Yahoo!知恵袋では「同じ要素数の配列を作って、必要な部分をコピーするしかない」なんて書いてあったので
MT4の配列の操作のプログラムなのですが「配列の先頭に要素を追加し配… – Yahoo!知恵袋
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q14144867574
ArrayCopy を調べてみたらなんとなくできました。もっと要領よくできたらいいんですが今のところこれで問題なさそうです。
// 例えば配列の3番目の要素を削除
int origin_array[] = {1, 2, 3, 4, 5};
int copy_array[];
int target = 3; // 3番目の要素
//+------------------------------------------------------------------+
void OnStart()
{
// 要素削除前の origin_array のサイズ
int array_size = ArraySize(origin_array);
//--- 削除前 Print
for(int i = 0; i < array_size; i++)
PrintFormat("削除前配列:インデックス=%d, 値=%d", i, origin_array[i]);
// origin_array の要素と target を比較して存在すれば配列から削除
//--- ここから
for(int i = array_size - 1; i >= 0; i--) // decrement
{
if(origin_array[i] == target)
{
ArrayCopy(copy_array, origin_array, 0, 0, i);
ArrayCopy(copy_array, origin_array, i, i + 1);
ArrayCopy(origin_array, copy_array);
ArrayResize(origin_array, --array_size, 10);
ArrayResize(copy_array, 0, 10);
}
}
//--- ここまで
//--- 削除後 Print
for(int i = 0; i < ArraySize(origin_array); i++)
PrintFormat("削除後配列:インデックス=%d, 値=%d", i, origin_array[i]);
}
//+------------------------------------------------------------------+
結果:
削除前配列:インデックス=0, 値=1
削除前配列:インデックス=1, 値=2
削除前配列:インデックス=2, 値=3
削除前配列:インデックス=3, 値=4
削除前配列:インデックス=4, 値=5
削除後配列:インデックス=0, 値=1
削除後配列:インデックス=1, 値=2
削除後配列:インデックス=2, 値=4
削除後配列:インデックス=3, 値=5
見たとおりの力業なんですが
ArrayCopy(copy_array, origin_array, 0, 0, i);
まずは、コピー配列の先頭に、オリジナル配列の先頭から i 個の要素をコピー。先頭が削除対象なら i が 0 なのでコピーされずに次の行へ進みます。
ArrayCopy(copy_array, origin_array, i, i + 1);
続けて、コピー配列の i 番目(削除対象番目)から、オリジナル配列の i + 1 番目(削除対象要素を飛ばして)から最後までをコピー。これで対象要素を飛ばして順番を詰めた(削除した)ことになります。
ArrayCopy(origin_array, copy_array);
続いて対象要素が削除されたコピー配列をそのままオリジナル配列に戻します。
ArrayResize(origin_array, --array_size, 10);
ArrayResize(copy_array, 0, 10);
最後に、要素 1 個分配列が長いはずなので長さを 1 減らして配列から要素削除の完成。次のためにコピー配列の長さも 0 にしておきます。ArrayResize の3つ目の引数は動的配列用のメモリ確保量らしいです。使う予定の最大配列長くらいの値を入れておけば処理が遅くならないようです。実際に使うのは、ポジションごとにフラグを持ちたいときなどくらいなので適当に 100 とか入れてます。
今のところはこれで決済したポジション情報だけを削除したりで動いてます。でもそろそろへなちょこから脱却しなくちゃ。