【MQL5】CustomTicksReplace関数の使い方と自動売買実装コード

1. CustomTicksReplace関数の概要と実務での活用法

MQL5におけるCustomTicksReplaceは、「カスタム銘柄(Custom Symbol)」のティック履歴を、指定した範囲で完全に置き換えるための関数です。

実務レベルの開発において、この関数は主に以下のシーンで活用されます。
* 高品質な外部データのインポート: ブローカーが提供するティックデータに欠損がある場合、外部で購入した精度の高いデータをカスタム銘柄に反映させる。
* 合成通貨ペアの作成: 例えば「USD/JPY」と「EUR/JPY」を組み合わせて独自の「EUR/USD」を生成し、相関トレードのバックテストを行う。
* ティックデータのクレンジング: 明らかな異常値(スパイク)をプログラムで自動修正する。

初心者が特につまずきやすい点は、この関数が「リアル口座の既存銘柄(EURUSDなど)には使用できない」という点です。あくまで自分で作成した「カスタム銘柄」に対してデータを書き込むための関数であることを理解しておきましょう。

2. 構文と戻り値

CustomTicksReplace関数の構文は以下の通りです。

int  CustomTicksReplace(
   string           symbol,          // カスタム銘柄名
   long             from_msc,        // 開始日時(ミリ秒単位)
   long             to_msc,          // 終了日時(ミリ秒単位)
   const MqlTick&   ticks[],         // 置き換えるティックデータの配列
   uint             count=WHOLE_ARRAY // 配列内の使用する要素数
   );

パラメーターの解説

  1. symbol: データを操作したいカスタム銘柄の名前を指定します。
  2. from_msc / to_msc: 置き換えたい期間をミリ秒(1970年1月1日からの経過ミリ秒)で指定します。この期間内の既存データはすべて削除され、新しいデータに置き換わります。
  3. ticks[]: 挿入したいティックデータを格納したMqlTick型の配列です。
  4. count: 配列のうち、何個のデータを使用するかを指定します。通常はデフォルトのWHOLE_ARRAY(全要素)で問題ありません。

戻り値

  • 成功した場合:変更されたティックの数が返ります。
  • 失敗した場合:-1が返ります。エラーの詳細はGetLastError()で確認できます。

3. 具体的な使い方・実践サンプルコード

以下は、独自のカスタム銘柄「MySymbol」を作成し、そこにテスト用のティックデータを流し込む実用的なスクリプトの例です。

void OnStart()
{
   string customSymbol = "MySymbol";

   // 1. カスタム銘柄が存在しない場合は作成(既存の場合はスキップ)
   if(!SymbolInfoInteger(customSymbol, SYMBOL_CUSTOM))
   {
      // 既存のEURUSDをベースにカスタム銘柄を作成
      if(!CustomSymbolCreate(customSymbol, "Custom\\MyGroup", "EURUSD"))
      {
         Print("カスタム銘柄の作成に失敗しました。Error:", GetLastError());
         return;
      }
   }

   // 2. 挿入するティックデータの準備(例として10個のティックを作成)
   MqlTick tickArray[10];
   datetime startTime = TimeCurrent();

   for(int i = 0; i < 10; i++)
   {
      tickArray[i].time = startTime + i;          // 秒単位の時間
      tickArray[i].time_msc = (startTime + i) * 1000; // ミリ秒単位の時間
      tickArray[i].bid = 1.1000 + (i * 0.0001);   // ダミーのBid価格
      tickArray[i].ask = tickArray[i].bid + 0.0002; // ダミーのAsk価格
      tickArray[i].last = 0;
      tickArray[i].volume = 1;
      tickArray[i].flags = TICK_FLAG_BID | TICK_FLAG_ASK;
   }

   // 3. CustomTicksReplaceでデータを置き換え
   // 開始時間はtickArray[0]、終了時間はtickArray[9]の時間を指定
   long from_msc = tickArray[0].time_msc;
   long to_msc   = tickArray[9].time_msc;

   int result = CustomTicksReplace(customSymbol, from_msc, to_msc, tickArray);

   if(result > 0)
   {
      Print(customSymbol, " に ", result, " 個のティックを正常に書き込みました。");
   }
   else
   {
      Print("ティックの書き込みに失敗しました。Error:", GetLastError());
   }
}

4. 使用上の注意点とよくあるエラー

開発時にハマりやすいポイントを整理しました。

  1. 時間のソート順: ticks[]配列に格納するデータは、必ず時間の昇順(古い順)である必要があります。時間が前後していると、チャート上で正しく表示されなかったり、関数の実行がエラーになったりすることがあります。
  2. ミリ秒単位の指定: from_mscto_mscは秒ではなく「ミリ秒」です。TimeCurrent()などの戻り値(秒)をそのまま使うのではなく、必ず1000倍するか、MqlTicktime_mscを使用してください。
  3. 既存データの消失: この関数は「置き換え」です。指定したfrom_mscからto_mscの期間内にあった古いデータは完全に消去されます。追加(追記)したい場合はCustomTicksAdd関数を使用しましょう。
  4. 銘柄の選択: カスタム銘柄を作成した後、気配値表示ウィンドウでその銘柄を表示(選択)状態にしておかないと、データの更新が反映されない場合があります。

5. 【重要】自動売買における約定スピードと環境の罠

アルゴリズムトレードの世界では、どんなに優れたロジックを組み、CustomTicksReplaceで精緻なバックテスト環境を構築しても、「実行環境」が貧弱であればすべてが台無しになります。

特に自宅のPCや一般的な光回線での自動売買は、ブローカーのサーバーとの物理的な距離が離れているため、ネットワーク遅延(レイテンシ)が致命的な損失を招きます。相場急変時に注文を出しても、自宅からの信号が届く頃には価格が滑り(スリッページ)、バックテストの結果とはかけ離れた悲惨な約定価格になるのが現実です。

プロのクオンツや専業トレーダーにとって、ブローカーのデータセンターに近い場所で稼働する「専用VPS(仮想専用サーバー)」の導入は、単なる推奨ではなく「必須条件」です。 0.1秒の遅延が収益を左右するFXシストレにおいて、極限まで約定スピードを高めることは、ロジックを磨くことと同等、あるいはそれ以上に重要であることを忘れないでください。

💡 この記事の内容を実運用で活かすには?

この記事の内容を実運用で活かすには、正しい環境が必要です。
特にVPSを使わないと、このロジックは再現できません。

コメント

タイトルとURLをコピーしました