CopyTicks」のテスト - ページ 19

 

1434 - 平均1msは、すでに1000ティックをアップロードしたCopyTicksを取得するのにかかる。遅い、ような気がする。

先に受信した最後のティックのfrom_mscでTRADE0ticを要求する。3回刻みで表示されますが、0.3〜0.9msで表示されます。- 今はとても遅い。

 
fxsaber:

上記のコードを強くログに残し、理由を把握。CopyTicks (from > 0) が最も新しいものよりも前にティックを取得した場合、いくつかをスキップすることができます。

サービスデスクからのとても重要な回答です。

本来の問題点である、次のコールのCopyTicksが同じ期間のより多くのティックを与えることができるという点について。

これは確かにそうです。問題は、取引所のデータストリームであるbid/askとflipper/volumeが異なるストリームであり、取引所側で既に互いに同期していないことです。

このため、最初に時間12時12分12秒300のビッド/アスクが来て、少し後に時間12時12分12秒299のフリッパー/ボリュームが来るという状況があります。

したがって、最後のティック(12時12分12秒300)以降のデータを要求しても、12時12分12秒299の新しいフリッパーを取得することはできません。

PS.端末は、時間順に並べた刻みを保存・送信しています。つまり、CopyTicksに与えられるティックの時間列は常に増加している。

ティックの受信には、「INFO」と「TRADE」の2つの流れがあります。ALLは合成された組合わせ(端末側のようです)なので、このような誤動作が起こるのでしょう。

シンセサイザーだからこそ、こんな言葉があったんですね。

スラワ

CopyTicksの呼び出し後の最初のティックレコードには、ゼロではなく、要求された時点のbid、ask、lastの現在値が含まれます。

そのため、ALLダニを扱う場合は、何を相手にしているのかを明確に意識する必要があります。ティックフラッグも合成している可能性があります。これらの問題点について、十分に具体的に説明してほしい。

テープの場合、CopyTicksが正しく動作していればこの問題は発生しないはずです。

ヘルプはかなり本格的に補填されると思います。

 
fxsaber:
オーバーロードは自分で追加することができます。
私にもあなたにも、他のプログラマーにもできることはたくさんありますが、願わくば開発者が「詰め物」をよく理解し、必要な刻みを得るための素早いアルゴリズムを作り上げられるといいのですが。
 

COPY_TICKS_TRADEフラグでCopyTicksをテストしてみました。

差はない。

2016.10.03 15:50:48.507 Check_ticks (RTS-12.16,M1)      History ticks = 9
2016.10.03 15:50:48.507 Check_ticks (RTS-12.16,M1)      Dynamic ticks = 9
2016.10.03 15:50:48.956 Check_ticks (RTS-12.16,M1)      History ticks = 11
2016.10.03 15:50:48.956 Check_ticks (RTS-12.16,M1)      Dynamic ticks = 11
2016.10.03 15:50:49.184 Check_ticks (RTS-12.16,M1)      History ticks = 12
2016.10.03 15:50:49.184 Check_ticks (RTS-12.16,M1)      Dynamic ticks = 12
2016.10.03 15:50:49.510 Check_ticks (RTS-12.16,M1)      History ticks = 14
2016.10.03 15:50:49.511 Check_ticks (RTS-12.16,M1)      Dynamic ticks = 14
2016.10.03 15:50:51.568 Check_ticks (RTS-12.16,M1)      History ticks = 15
2016.10.03 15:50:51.568 Check_ticks (RTS-12.16,M1)      Dynamic ticks = 15
2016.10.03 15:50:51.627 Check_ticks (RTS-12.16,M1)      History ticks = 16
2016.10.03 15:50:51.627 Check_ticks (RTS-12.16,M1)      Dynamic ticks = 16
2016.10.03 15:50:53.143 Check_ticks (RTS-12.16,M1)      History ticks = 19
2016.10.03 15:50:53.143 Check_ticks (RTS-12.16,M1)      Dynamic ticks = 19
2016.10.03 15:50:54.514 Check_ticks (RTS-12.16,M1)      History ticks = 27
2016.10.03 15:50:54.514 Check_ticks (RTS-12.16,M1)      Dynamic ticks = 26
2016.10.03 15:50:54.542 Check_ticks (RTS-12.16,M1)      History ticks = 27
2016.10.03 15:50:54.542 Check_ticks (RTS-12.16,M1)      Dynamic ticks = 27
2016.10.03 15:50:54.847 Check_ticks (RTS-12.16,M1)      History ticks = 30
2016.10.03 15:50:54.847 Check_ticks (RTS-12.16,M1)      Dynamic ticks = 30
2016.10.03 15:50:57.052 Check_ticks (RTS-12.16,M1)      History ticks = 31
2016.10.03 15:50:57.052 Check_ticks (RTS-12.16,M1)      Dynamic ticks = 31
2016.10.03 15:50:57.301 Check_ticks (RTS-12.16,M1)      History ticks = 32
2016.10.03 15:50:57.301 Check_ticks (RTS-12.16,M1)      Dynamic ticks = 32
2016.10.03 15:51:00.498 Check_ticks (RTS-12.16,M1)      History ticks = 44
2016.10.03 15:51:00.498 Check_ticks (RTS-12.16,M1)      Dynamic ticks = 44
ファイル:
Check_ticks.mq5  41 kb
 
prostotrader:

COPY_TICKS_TRADEフラグでCopyTicksをテストしてみました。

差はない。

 
fxsaber:

上記のコードを強くログに残し、理由を把握。CopyTicks (from > 0) が最も新しいものまでのティックを取得する場合、いくつかはスキップされるかもしれません。

from = 2016.09.29 11:05:55.564で要求されたティックです。返信で3ティック獲得

しばらくして、遠くからティック履歴を 要求したところ、以前はCopyTicksが見逃していたティックが表示されました。

こんな虫がいたのか!?

tickデータベースへの書き込みと読み込みが並行して行われるため、何らかのコンフリクトが発生しているように思われます。

1434はTRADE-typesの同じバグです。Expert Advisorの再現
#include <TypeToBytes.mqh> // https://www.mql5.com/ru/code/16280

long LastTime = 0; // time_msc-время последнего тика (самого свежего), полученного из истории
int Count = 0;     // Количество тиков в последенем запросе, у которых time_msc == LastTime

// Возвращает свежие тики, пришедшие после предыдущего вызова
int GetFreshTicks( MqlTick &Ticks[], const uint flags = COPY_TICKS_TRADE, const uint count = 100000 )
{
  int Res = 0;

  MqlTick NewTicks[];
  const int NewAmount = CopyTicks(Symbol(), NewTicks, flags, LastTime, count);

  if ((NewAmount > 0) && (Count < NewAmount))
  {
    Res = ArrayCopy(Ticks, NewTicks, 0, Count);

    // Взяли крайнее время из текущей истории
    LastTime = Ticks[Res - 1].time_msc;
    Count = 1;

    // Находим (Count) в текущей истории количество тиков со временем LastTime
    for (int i = Res - 2; i >= 0; i--)
    {
      if (Ticks[i].time_msc < LastTime)
        break;

      Count++;
    }
  }
  
  return(Res);
}

string GetTickFlag( uint tickflag )
{
  string flag = "";

#define  TICKFLAG_MACRO(A) flag += ((bool)(tickflag & TICK_FLAG_##A)) ? " TICK_FLAG_" + #A : "";
  TICKFLAG_MACRO(BID)
  TICKFLAG_MACRO(ASK)
  TICKFLAG_MACRO(LAST)
  TICKFLAG_MACRO(VOLUME)
  TICKFLAG_MACRO(BUY)
  TICKFLAG_MACRO(SELL)
#undef  TICKFLAG_MACRO

  if (flag == "")
    flag = " FLAG_UNKNOWN (" + (string)tickflag + ")";
     
  return(flag);
}

#define  TOSTRING(A) " " + #A + " = " + (string)Tick.A

string TickToString( const MqlTick &Tick )
{
  return(TOSTRING(time) + "." + (string)IntegerToString(Tick.time_msc %1000, 3, '0') +
         TOSTRING(bid) + TOSTRING(ask) + TOSTRING(last)+ TOSTRING(volume) + GetTickFlag(Tick.flags));
}

#define  TOSTRING2(A) #A + " = " + (string)(A) + " "

template <typename T>
bool ArrayEqual( const T &Array1[], const T &Array2[] )
{
  const int Amount = MathMin(ArraySize(Array1), ArraySize(Array2));
  bool Res = (Amount > 0);

  if (Res)
    for (int i = 0; i < Amount; i++)
      if (_R(Array1[i]) != Array2[i]) // https://www.mql5.com/ru/code/16280
      {
        Print(TOSTRING2(i) + TOSTRING2(ArraySize(Array1)) + TOSTRING2(ArraySize(Array2)));
        Print(TOSTRING2(TickToString(Array1[i])) + "\n" + TOSTRING2(TickToString(Array2[i])) + "\n");
        Print(TOSTRING2(TickToString(Array1[i - 1])) + "\n" + TOSTRING2(TickToString(Array2[i - 1])) + "\n");
        
        Res = false;
        
        ExpertRemove();

        break;
      }

  return(Res);
}

void OnTick( void )
{
  static bool FirstRun = true;
  static MqlTick PrevTicks[];
  
  if (FirstRun)
  {
    LastTime = TimeCurrent() * 1000;
    Count = 0;
    
    FirstRun = false;
  }
  
  MqlTick Ticks[];

  // Взяли свеженькие тики
  const int Amount = GetFreshTicks(Ticks);

  ArrayCopy(PrevTicks, Ticks, ArraySize(PrevTicks));
  
  if (ArraySize(PrevTicks) > 0)    
  {
    MqlTick NewTicks[];
    
    // Взяли историю тиков
    Print(CopyTicks(_Symbol, NewTicks, COPY_TICKS_TRADE, PrevTicks[0].time_msc, 1000000));
    
    // Проверка на совпадение собираемой истории с самой историей
    Print(ArrayEqual(NewTicks, PrevTicks) ? "Equal" : "Not Equal");
  }  
}
結果
2016.10.04 10:36:17.743 Test13 (RTS-12.16,M1)   Not Equal
2016.10.04 10:36:17.743 Test13 (RTS-12.16,M1)   ExpertRemove() function called
2016.10.04 10:36:17.743 Test13 (RTS-12.16,M1)   
2016.10.04 10:36:17.743 Test13 (RTS-12.16,M1)   TickToString(Array2[i-1]) =  time = 2016.10.04 10:37:07.791 bid = 99680.0 ask = 99690.0 last = 99690.0 volume = 4 TICK_FLAG_LAST TICK_FLAG_VOLUME TICK_FLAG_BUY 
2016.10.04 10:36:17.743 Test13 (RTS-12.16,M1)   TickToString(Array1[i-1]) =  time = 2016.10.04 10:37:07.791 bid = 99680.0 ask = 99690.0 last = 99690.0 volume = 4 TICK_FLAG_LAST TICK_FLAG_VOLUME TICK_FLAG_BUY 
2016.10.04 10:36:17.743 Test13 (RTS-12.16,M1)   
2016.10.04 10:36:17.743 Test13 (RTS-12.16,M1)   TickToString(Array2[i]) =  time = 2016.10.04 10:37:07.791 bid = 99680.0 ask = 99690.0 last = 99690.0 volume = 4 TICK_FLAG_LAST TICK_FLAG_VOLUME TICK_FLAG_BUY 
2016.10.04 10:36:17.743 Test13 (RTS-12.16,M1)   TickToString(Array1[i]) =  time = 2016.10.04 10:37:08.773 bid = 99690.0 ask = 99700.0 last = 99690.0 volume = 1 TICK_FLAG_LAST TICK_FLAG_VOLUME TICK_FLAG_SELL 
2016.10.04 10:36:17.743 Test13 (RTS-12.16,M1)   i = 144 ArraySize(Array1) = 145 ArraySize(Array2) = 146 
2016.10.04 10:36:17.743 Test13 (RTS-12.16,M1)   145
2016.10.04 10:36:16.768 Test13 (RTS-12.16,M1)   Equal

TRADEスレッドの収集されたリアルタイムティック履歴には、履歴の後半に登場する時刻2016.10.04 10:37:08.773のティックが含まれていませんでした。

これは、上で 述べたこととやや矛盾しています。問題は、合成された「ALL-flow」だけでなく、直接的な「TRADE」にもあるのです。

 
fxsaber:
1434はTRADE-typesの同じバグです。リプロダクションアドバイザー
申し訳ありません、これは私の重大な見落としです。
 
fxsaber:

1434 - 平均1msは、すでに1000ティックをアップロードしたCopyTicksを取得するのにかかる。遅い、ような気がする。

先に受信した最後のティックのfrom_mscでTRADE0ticを要求する。3回刻みで表示されますが、0.3〜0.9msで表示されます。- 今はとても遅い。

関連性が高い!?スピードアップの方法はないのか?

 

この場を借りて、CopyTicksの開発者の方々にお礼を申し上げます

CopyTicksが絶対に正しく動作するとは言えませんが、テープで完璧に動作させることができ、CopyTicksをより深く理解することができました。

車輪の再発明ではありませんが、テープをベースにしたティック指標の書き方の微調整例は、こちらと こちらで ご覧いただけます。

 
timeからtimeへの刻みを得るための最適(最速)なアルゴリズムは?