CustomTicksReplace

指定された時間間隔内のカスタム銘柄の価格履歴をMqlTick型の配列からのデータで完全に置き換えます。

int  CustomTicksReplace(
  const string    symbol,            // 銘柄名
  long           from_msc,         // 開始の日付
  long           to_msc,           // 終了の日付
  const MqlTick& ticks[],           // カスタム銘柄に適用されるデータの配列
  uint            count=WHOLE_ARRAY // 使用されるticks[]配列要素の数
  );

パラメータ

symbol

[in]  カスタム銘柄名

from_msc

[in]  削除する指定範囲内の価格履歴の最初のティックの時間(1970.01.01 から経過したミリ秒)

to_msc

[in]  削除する指定範囲内の価格履歴の最後のティックの時間(1970.01.01 から経過したミリ秒)

ticks[]

[in] 昇順に並び替えられたMqlTick型のティックデータの配列

count=WHOLE_ARRAY

[in]  指定した時間間隔内の置き換えに使用されるticks[]配列要素の数。WHOLE_ARRAYはすべてのticks[]配列要素が使用されることを意味します。

戻り値

更新されたティックの数(エラーの場合は-1)

注意事項

クォーツの流れの中ではしばしば複数のティックがミリ秒単位で同じ時間を持つことがあるので(正確なティックの時間はMqlTick構造体のtime_mscフィールドに保存)、CustomTicksReplace関数は自動的にticks[]配列要素を時間順に並び替えることはありません。したがって、ティックの配列は事前に時間の昇順で並び替える必要があります。

ティックはto_mscで指定された時間まで、またはエラーが発生するまで、毎日連続して置き換えられます。指定された範囲の日は順番に処理され。ティック時間と昇順(非降順)の間の不一致が検出されると、現在の日のティックの置き換えが停止します。現在の日(間違ったティックの瞬間)と指定された間隔の残りは変更されませんが、その前日までのティックはすべて普通に置き換えられます。

ticks[] 配列にいずれの日のティックデータも含まれない場合は(一般的に、どの期間でも)、ticks[] からのティックデータが適応された後に、カスタム銘柄履歴には欠落したデータに対応する「穴」が表示されます。言い換えれば CustomTicksReplaceを欠陥したティックで呼び出すとティック履歴のその部分を削除され、これはCustomTicksDeleteを「穴」の範囲で呼び出すのと同じです。

 

例:

//+------------------------------------------------------------------+
//|                                           CustomTicksReplace.mq5 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link     "https://www.mql5.com"
#property version   "1.00"
 
#define   CUSTOM_SYMBOL_NAME     Symbol()+".C"     // カスタム銘柄名
#define   CUSTOM_SYMBOL_PATH     "Forex"           // 銘柄が作成されるグループの名前
#define   CUSTOM_SYMBOL_ORIGIN   Symbol()         // カスタム銘柄の基となる銘柄の名前
 
#define   DATATICKS_TO_COPY     UINT_MAX         // コピーされたティックの数
#define   DATATICKS_TO_PRINT     20               // 操作ログに送信されるティックの数
 
//+------------------------------------------------------------------+
//| スクリプトプログラム開始関数                                              |
//+------------------------------------------------------------------+
void OnStart()
 {
//--- カスタム銘柄を作成するときにエラーコードを取得する
  int create=CreateCustomSymbol(CUSTOM_SYMBOL_NAME, CUSTOM_SYMBOL_PATH, CUSTOM_SYMBOL_ORIGIN);
 
//--- エラーコードが0(銘柄の作成に成功)でも5304(銘柄がすでに作成されている)でもない場合は、終了する
  if(create!=0 && create!=5304)
    return;
 
//--- 標準銘柄ティックデータをMqlTick配列に取得する
  MqlTick array[]={};
  if(!GetTicksToArray(CUSTOM_SYMBOL_ORIGIN, DATATICKS_TO_COPY, array))
    return;
 
//--- 標準銘柄の最初と最後に受信したティックの時間を出力する
  int total=(int)array.Size();
  PrintFormat("First tick time: %s.%03u, Last tick time: %s.%03u",
              TimeToString(array[0].time,TIME_DATE|TIME_MINUTES|TIME_SECONDS), array[0].time_msc%1000,
              TimeToString(array[total-1].time, TIME_DATE|TIME_MINUTES|TIME_SECONDS), array[total-1].time_msc%1000);
             
/--- 標準銘柄の最後のDATATICKS_TO_PRINTティックを操作ログに出力する
  PrintFormat("\nThe last %d ticks for the standard symbol '%s':", DATATICKS_TO_PRINT, CUSTOM_SYMBOL_ORIGIN);
  for(int i=total-DATATICKS_TO_PRINT; i<total; i++)
    {
    if(i<0)
        continue;
    PrintFormat("  %dth Tick: %s", i, GetTickDescription(array[i]));
    }
 
//--- 気配値表示ウィンドウにカスタム銘柄を追加する
  ResetLastError();
  if(!SymbolSelect(CUSTOM_SYMBOL_NAME, true))
    {
    Print("SymbolSelect() failed. Error ", GetLastError());
    return;
    }
   
//--- カスタム銘柄の価格履歴にティック配列データを追加する
  Print("...");
  uint start=GetTickCount();
  PrintFormat("Start of adding %u ticks to the history of the custom symbol '%s'", array.Size(), CUSTOM_SYMBOL_NAME);
  int added=CustomTicksAdd(CUSTOM_SYMBOL_NAME, array);
  PrintFormat("Added %u ticks to the history of the custom symbol '%s' in %u ms", added, CUSTOM_SYMBOL_NAME, GetTickCount()-start);
 
//--- get the newly added custom symbol tick data to the MqlTick array
  Print("...");
  if(!GetTicksToArray(CUSTOM_SYMBOL_NAME, array.Size(), array))
    return;
 
//--- カスタム銘柄の最初と最後に受信したティックの時間を出力する
  total=(int)array.Size();
  PrintFormat("First tick time: %s.%03u, Last tick time: %s.%03u",
              TimeToString(array[0].time, TIME_DATE|TIME_MINUTES|TIME_SECONDS), array[0].time_msc%1000,
              TimeToString(array[total-1].time, TIME_DATE|TIME_MINUTES|TIME_SECONDS), array[total-1].time_msc%1000);
             
/--- カスタム銘柄の最後のDATATICKS_TO_PRINTティックを操作ログに出力する
  PrintFormat("\nThe last %d ticks for the custom symbol '%s':", DATATICKS_TO_PRINT, CUSTOM_SYMBOL_NAME);
  for(int i=total-DATATICKS_TO_PRINT; i<total; i++)
    {
    if(i<0)
        continue;
    PrintFormat("  %dth Tick: %s", i, GetTickDescription(array[i]));
    }
 
//--- now change Ask and Bid tick values in the array using the equation Ask(Symbol) = 1.0 / Ask(Symbol), Bid(Symbol) = 1.0 / Bid(Symbol)
  for(int i=0; i<total; i++)
    {
    array[i].ask = (array[i].ask !=0 ? 1.0 / array[i].ask : array[i].ask);
    array[i].bid = (array[i].bid !=0 ? 1.0 / array[i].bid : array[i].bid);
    }
  Print("\nNow the ticks are changed");
 
//--- カスタム銘柄のティック履歴を、変更されたティック配列のデータに置き換える
  Print("...");
  start=GetTickCount();
  PrintFormat("Start replacing %u changed ticks in the history of the custom symbol '%s'", array.Size(), CUSTOM_SYMBOL_NAME);
  int replaced=CustomTicksReplace(CUSTOM_SYMBOL_NAME, array[0].time_msc, array[total-1].time_msc, array);
  PrintFormat("Replaced %u ticks in the history of the custom symbol '%s' in %u ms", replaced, CUSTOM_SYMBOL_NAME, GetTickCount()-start);
 
//--- 新しく置き換えられたカスタム銘柄のティックデータをMqlTick配列に取得する
  Print("...");
  if(!GetTicksToArray(CUSTOM_SYMBOL_NAME, array.Size(), array))
    return;
 
//--- カスタム銘柄の最初に受信した変更されたティックと最後に受信した変更されたティックの時刻を出力する
  total=(int)array.Size();
  PrintFormat("First changed tick time: %s.%03u, Last changed tick time: %s.%03u",
              TimeToString(array[0].time, TIME_DATE|TIME_MINUTES|TIME_SECONDS), array[0].time_msc%1000,
              TimeToString(array[total-1].time, TIME_DATE|TIME_MINUTES|TIME_SECONDS), array[total-1].time_msc%1000);
             
/--- カスタム銘柄の最後のDATATICKS_TO_PRINT変更済みティックを操作ログに出力する
  PrintFormat("\nThe last %d changed ticks for the custom symbol '%s':", DATATICKS_TO_PRINT, CUSTOM_SYMBOL_NAME);
  for(int i=total-DATATICKS_TO_PRINT; i<total; i++)
    {
    if(i<0)
        continue;
    PrintFormat("  %dth Changed tick: %s", i, GetTickDescription(array[i]));
    }
 
//--- チャートのコメントにスクリプト終了キーに関するヒントを表示する
  Comment(StringFormat("Press 'Esc' to exit or 'Del' to delete the '%s' symbol and exit", CUSTOM_SYMBOL_NAME));
//--- EscキーまたはDelキーが押されるまで待機して無限ループを終了する
  while(!IsStopped() && TerminalInfoInteger(TERMINAL_KEYSTATE_ESCAPE)==0)
    {
    Sleep(16);
    //--- Delキーを押すと、作成したカスタム銘柄とそのデータが削除される
    if(TerminalInfoInteger(TERMINAL_KEYSTATE_DELETE)<0)
       {
        //--- バーデータを削除する
        int deleted=CustomRatesDelete(CUSTOM_SYMBOL_NAME, 0, LONG_MAX);
        if(deleted>0)
          PrintFormat("%d history bars of the custom symbol '%s' were successfully deleted", deleted, CUSTOM_SYMBOL_NAME);
       
        //--- ティックデータを削除する
        deleted=CustomTicksDelete(CUSTOM_SYMBOL_NAME, 0, LONG_MAX);
        if(deleted>0)
          PrintFormat("%d history ticks of the custom symbol '%s' were successfully deleted", deleted, CUSTOM_SYMBOL_NAME);
       
        //--- 銘柄を削除する
        if(DeleteCustomSymbol(CUSTOM_SYMBOL_NAME))
          PrintFormat("Custom symbol '%s' deleted successfully", CUSTOM_SYMBOL_NAME);
        break;
       }
    }
//--- 終了する前にチャートをクリアする
  Comment("");
  /*
  結果:
  Requested 4294967295 ticks to get tick history for the symbol 'EURUSD'
  The tick history for the 'EURUSD' symbol is received in the amount of 351195822 ticks in 55735 ms
  First tick time: 2011.12.19 00:00:08.000, Last tick time: 2024.06.21 08:39:03.113
 
  The last 20 ticks for the standard symbol 'EURUSD':
    351195802th Tick: 2024.06.21 08:38:10.076 Ask=1.07194 (Info tick)
    351195803th Tick: 2024.06.21 08:38:13.162 Ask=1.07195 (Info tick)
    351195804th Tick: 2024.06.21 08:38:13.872 Bid=1.07195 (Info tick)
    351195805th Tick: 2024.06.21 08:38:14.866 Ask=1.07194 Bid=1.07194 (Info tick)
    351195806th Tick: 2024.06.21 08:38:17.374 Bid=1.07194 (Info tick)
    351195807th Tick: 2024.06.21 08:38:18.883 Bid=1.07194 (Info tick)
    351195808th Tick: 2024.06.21 08:38:19.771 Bid=1.07194 (Info tick)
    351195809th Tick: 2024.06.21 08:38:20.873 Ask=1.07195 Bid=1.07195 (Info tick)
    351195810th Tick: 2024.06.21 08:38:22.278 Ask=1.07196 Bid=1.07196 (Info tick)
    351195811th Tick: 2024.06.21 08:38:22.775 Bid=1.07196 (Info tick)
    351195812th Tick: 2024.06.21 08:38:23.477 Bid=1.07196 (Info tick)
    351195813th Tick: 2024.06.21 08:38:38.194 Ask=1.07197 (Info tick)
    351195814th Tick: 2024.06.21 08:38:38.789 Ask=1.07196 (Info tick)
    351195815th Tick: 2024.06.21 08:38:39.290 Ask=1.07197 (Info tick)
    351195816th Tick: 2024.06.21 08:38:43.695 Ask=1.07196 (Info tick)
    351195817th Tick: 2024.06.21 08:38:52.203 Ask=1.07195 Bid=1.07195 (Info tick)
    351195818th Tick: 2024.06.21 08:38:55.105 Ask=1.07196 Bid=1.07196 (Info tick)
    351195819th Tick: 2024.06.21 08:38:57.607 Ask=1.07195 Bid=1.07195 (Info tick)
    351195820th Tick: 2024.06.21 08:39:00.512 Ask=1.07196 Bid=1.07196 (Info tick)
    351195821th Tick: 2024.06.21 08:39:03.113 Ask=1.07195 Bid=1.07195 (Info tick)
  ...
  Start of adding 351195822 ticks to the history of the custom symbol 'EURUSD.C'
  Added 351195822 ticks to the history of the custom symbol 'EURUSD.C' in 349407 ms
  ...
  Requested 351195822 ticks to get tick history for the symbol 'EURUSD.C'
  The tick history for the 'EURUSD.C' symbol is received in the amount of 351195822 ticks in 190203 ms
  First tick time: 2011.12.19 00:00:08.000, Last tick time: 2024.06.21 08:39:03.113
 
  The last 20 ticks for the custom symbol 'EURUSD.C':
    351195802th Tick: 2024.06.21 08:38:10.076 Ask=1.07194 Bid=1.07194 (Info tick)
    351195803th Tick: 2024.06.21 08:38:13.162 Ask=1.07195 Bid=1.07195 (Info tick)
    351195804th Tick: 2024.06.21 08:38:13.872 Ask=1.07195 Bid=1.07195 (Info tick)
    351195805th Tick: 2024.06.21 08:38:14.866 Ask=1.07194 Bid=1.07194 (Info tick)
    351195806th Tick: 2024.06.21 08:38:17.374 Ask=1.07194 Bid=1.07194 (Info tick)
    351195807th Tick: 2024.06.21 08:38:18.883 Ask=1.07194 Bid=1.07194 (Info tick)
    351195808th Tick: 2024.06.21 08:38:19.771 Ask=1.07194 Bid=1.07194 (Info tick)
    351195809th Tick: 2024.06.21 08:38:20.873 Ask=1.07195 Bid=1.07195 (Info tick)
    351195810th Tick: 2024.06.21 08:38:22.278 Ask=1.07196 Bid=1.07196 (Info tick)
    351195811th Tick: 2024.06.21 08:38:22.775 Ask=1.07196 Bid=1.07196 (Info tick)
    351195812th Tick: 2024.06.21 08:38:23.477 Ask=1.07196 Bid=1.07196 (Info tick)
    351195813th Tick: 2024.06.21 08:38:38.194 Ask=1.07197 Bid=1.07197 (Info tick)
    351195814th Tick: 2024.06.21 08:38:38.789 Ask=1.07196 Bid=1.07196 (Info tick)
    351195815th Tick: 2024.06.21 08:38:39.290 Ask=1.07197 Bid=1.07197 (Info tick)
    351195816th Tick: 2024.06.21 08:38:43.695 Ask=1.07196 Bid=1.07196 (Info tick)
    351195817th Tick: 2024.06.21 08:38:52.203 Ask=1.07195 Bid=1.07195 (Info tick)
    351195818th Tick: 2024.06.21 08:38:55.105 Ask=1.07196 Bid=1.07196 (Info tick)
    351195819th Tick: 2024.06.21 08:38:57.607 Ask=1.07195 Bid=1.07195 (Info tick)
    351195820th Tick: 2024.06.21 08:39:00.512 Ask=1.07196 Bid=1.07196 (Info tick)
    351195821th Tick: 2024.06.21 08:39:03.113 Ask=1.07195 Bid=1.07195 (Info tick)
 
  Now the ticks are changed
  ...
  Start replacing 351195822 changed ticks in the history of the custom symbol 'EURUSD.C'
  Replaced 351195822 ticks in the history of the custom symbol 'EURUSD.C' in 452266 ms
  ...
  Requested 351195822 ticks to get tick history for the symbol 'EURUSD.C'
  The tick history for the 'EURUSD.C' symbol is received in the amount of 351195822 ticks in 199812 ms
  First changed tick time: 2011.12.19 00:00:08.000, Last changed tick time: 2024.06.21 08:39:03.113
 
  The last 20 changed ticks for the custom symbol 'EURUSD.C':
    351195802th Changed tick: 2024.06.21 08:38:10.076 Ask=0.93289 Bid=0.93289 (Info tick)
    351195803th Changed tick: 2024.06.21 08:38:13.162 Ask=0.93288 Bid=0.93288 (Info tick)
    351195804th Changed tick: 2024.06.21 08:38:13.872 Ask=0.93288 Bid=0.93288 (Info tick)
    351195805th Changed tick: 2024.06.21 08:38:14.866 Ask=0.93289 Bid=0.93289 (Info tick)
    351195806th Changed tick: 2024.06.21 08:38:17.374 Ask=0.93289 Bid=0.93289 (Info tick)
    351195807th Changed tick: 2024.06.21 08:38:18.883 Ask=0.93289 Bid=0.93289 (Info tick)
    351195808th Changed tick: 2024.06.21 08:38:19.771 Ask=0.93289 Bid=0.93289 (Info tick)
    351195809th Changed tick: 2024.06.21 08:38:20.873 Ask=0.93288 Bid=0.93288 (Info tick)
    351195810th Changed tick: 2024.06.21 08:38:22.278 Ask=0.93287 Bid=0.93287 (Info tick)
    351195811th Changed tick: 2024.06.21 08:38:22.775 Ask=0.93287 Bid=0.93287 (Info tick)
    351195812th Changed tick: 2024.06.21 08:38:23.477 Ask=0.93287 Bid=0.93287 (Info tick)
    351195813th Changed tick: 2024.06.21 08:38:38.194 Ask=0.93286 Bid=0.93286 (Info tick)
    351195814th Changed tick: 2024.06.21 08:38:38.789 Ask=0.93287 Bid=0.93287 (Info tick)
    351195815th Changed tick: 2024.06.21 08:38:39.290 Ask=0.93286 Bid=0.93286 (Info tick)
    351195816th Changed tick: 2024.06.21 08:38:43.695 Ask=0.93287 Bid=0.93287 (Info tick)
    351195817th Changed tick: 2024.06.21 08:38:52.203 Ask=0.93288 Bid=0.93288 (Info tick)
    351195818th Changed tick: 2024.06.21 08:38:55.105 Ask=0.93287 Bid=0.93287 (Info tick)
    351195819th Changed tick: 2024.06.21 08:38:57.607 Ask=0.93288 Bid=0.93288 (Info tick)
    351195820th Changed tick: 2024.06.21 08:39:00.512 Ask=0.93287 Bid=0.93287 (Info tick)
    351195821th Changed tick: 2024.06.21 08:39:03.113 Ask=0.93288 Bid=0.93288 (Info tick)
  */
 }
//+------------------------------------------------------------------+
//| カスタム銘柄ルを作成し、エラーコードを返す                                    |
//+------------------------------------------------------------------+
int CreateCustomSymbol(const string symbol_name, const string symbol_path, const string symbol_origin=NULL)
 {
//--- カスタム銘柄の基となる銘柄の名前をする
  string origin=(symbol_origin==NULL ? Symbol() : symbol_origin);
 
//--- カスタム銘柄の作成に失敗し、エラー5304ではない場合は、操作ログに報告する
  ResetLastError();
  int error=0;
  if(!CustomSymbolCreate(symbol_name, symbol_path, origin))
    {
    error=GetLastError();
    if(error!=5304)
        PrintFormat("CustomSymbolCreate(%s, %s, %s) failed. Error %d", symbol_name, symbol_path, origin, error);
    }
//--- 成功
  return(error);
 }
//+------------------------------------------------------------------+
//| カスタム銘柄を削除する                                                 |
//+------------------------------------------------------------------+
bool DeleteCustomSymbol(const string symbol_name)
 {
//--- 気配値表示ウィンドウから銘柄を非表示にする
  ResetLastError();
  if(!SymbolSelect(symbol_name, false))
    {
    PrintFormat("SymbolSelect(%s, false) failed. Error %d", GetLastError());
    return(false);
    }
     
//--- カスタム銘柄の削除に失敗した場合は、操作ログにこれを報告してfalseを返す
  ResetLastError();
  if(!CustomSymbolDelete(symbol_name))
    {
    PrintFormat("CustomSymbolDelete(%s) failed. Error %d", symbol_name, GetLastError());
    return(false);
    }
//--- 成功
  return(true);
 }
//+------------------------------------------------------------------+
//| 配列内の指定された数のティックを取得する                                    |
//+------------------------------------------------------------------+
bool GetTicksToArray(const string symbol, const uint count, MqlTick &array[])
 {
//--- 履歴データの読み込み開始を通知する
  PrintFormat("Requested %u ticks to get tick history for the symbol '%s'", count, symbol);
 
//--- ティックの受信を3回試行する
  int attempts=0;
  while(attempts<3)
    {
    //--- ティックを受信する前に開始時間を測定する
    uint start=GetTickCount();
     
    //--- 1970.01.01 00:00.001 以降のティック履歴を要求する (パラメータ from=1 ms)
    int received=CopyTicks(symbol, array, COPY_TICKS_ALL, 1, count);
    if(received!=-1)
       {
        //--- ティック数と経過時間に関する情報を表示する
        PrintFormat("The tick history for the '%s' symbol is received in the amount of %u ticks in %d ms", symbol, received, GetTickCount()-start);
       
        //--- ティック履歴が同期されている場合、エラーコードはゼロになる - trueを返す
        if(GetLastError()==0)
          return(true);
 
        PrintFormat("%s: Ticks are not synchronized yet, %d ticks received for %d ms. Error=%d",
                    symbol, received, GetTickCount()-start, GetLastError());
       }
    //--- 試行回数を数える
    attempts++;
    //--- ティック データベースの同期が終了するまで1秒間待機する
    Sleep(1000);
    }
//--- 3 回の試行でティックをコピーできない
  return(false);
 }
//+------------------------------------------------------------------+
//| ティックの文字列の説明を返す                                             |
//+------------------------------------------------------------------+
string GetTickDescription(MqlTick &tick)
 {
  string desc=StringFormat("%s.%03u ", TimeToString(tick.time, TIME_DATE|TIME_MINUTES|TIME_SECONDS),tick.time_msc%1000);
 
//--- ティックのフラグを確認する
  bool buy_tick   = ((tick.flags &TICK_FLAG_BUY)   == TICK_FLAG_BUY);
  bool sell_tick  = ((tick.flags &TICK_FLAG_SELL)  == TICK_FLAG_SELL);
  bool ask_tick   = ((tick.flags &TICK_FLAG_ASK)   == TICK_FLAG_ASK);
  bool bid_tick   = ((tick.flags &TICK_FLAG_BID)   == TICK_FLAG_BID);
  bool last_tick  = ((tick.flags &TICK_FLAG_LAST)  == TICK_FLAG_LAST);
  bool volume_tick= ((tick.flags &TICK_FLAG_VOLUME)== TICK_FLAG_VOLUME);
 
//--- まず取引フラグのティックを確認する (CustomTicksAdd()には何も存在しない)
  if(buy_tick || sell_tick)
    {
    //--- 取引ティックの出力を作成する
    desc += (buy_tick ? StringFormat("Buy Tick: Last=%G Volume=%d ", tick.last, tick.volume)  : "");
    desc += (sell_tick? StringFormat("Sell Tick: Last=%G Volume=%d ",tick.last, tick.volume) : "");
    desc += (ask_tick ? StringFormat("Ask=%G ", tick.ask) : "");
    desc += (bid_tick ? StringFormat("Bid=%G ", tick.ask) : "");
    desc += "(Trade tick)";
    }
  else
    {
    //--- 情報ティックの出力を少し異なる方法で作成する
    desc += (ask_tick   ? StringFormat("Ask=%G ", tick.ask)    : "");
    desc += (bid_tick   ? StringFormat("Bid=%G ", tick.ask)    : "");
    desc += (last_tick  ? StringFormat("Last=%G ", tick.last)   : "");
    desc += (volume_tick? StringFormat("Volume=%d ",tick.volume): "");
    desc += "(Info tick)";
    }
//--- ティックの説明を返す
  return(desc);
 }

 

参照

CustomRatesDeleteCustomRatesUpdateCustomTicksDeleteCopyTicksCopyTicksRange