CopyTicks」のテスト - ページ 42

 
1702 - 見つかった CopyTicks の不具合は修正されました!
 

CopyTicksオフラインの呼び出しに成功した後、GetLastErrorは 4403を返します。

 
カスタムシンボルティックを すべて取得しようとすると、メモリ不足になる
CopyTicks(Symb, Ticks, COPY_TICKS_ALL, 0, UINT_MAX); // out of memory


CopyTicksRange経由でやりますが、CopyTicksの挙動は変更するのが正しいようです。

 
CopyTicksRangeによって、2003.hccなどのヒゲのある年からBARがアップロードされることがあります。
 
カスタムキャラクタの CopyTicksRangeは0を返します。CopyTicksは正常です。
 

CopyTicks (build 1881) は、新しいティックが要求されない場合、要求されたものより古いデータを返します。つまり、パラメータより古いデータが返される。バグが浮いている - 異なる時間に表示されるので、私はそれを再現するいくつかの小さなコードを書いた。EURUSD H1、2017.08.01~2018.08.01でテスターで動かしてみました。

void OnTick()
{
   static datetime lastActivityTime = D'2017.08.01';   
   static MqlTick ticks[2000];
   static const uint requestedCount = 2000;
   datetime dt[1];
   CopyTime(NULL, PERIOD_CURRENT, 0, 1, dt);
   if (lastActivityTime >= dt[0]) {
      return;
   }
   lastActivityTime = TimeCurrent();
   
   int zero = 0;
   int idx = 0;
   do {
      ++idx;
      CopyTime(NULL, PERIOD_CURRENT, idx, 1, dt);
      if (dt[0] <= D'2017.08.01') break;
      Print("dt[0]=", dt[0]);
      ulong from = 1000 * dt[0];
      int cnt = CopyTicks(Symbol(), ticks, COPY_TICKS_INFO, from, requestedCount);
      if (cnt < 1) {
         Print("Error in CopyTicks");
         return;
      }
      Print("cnt=", cnt);
      for (int i = 0; i < cnt; ++i) {
         if (ticks[i].time_msc < from) {
            Print("ERROR: i=", i, ", ticks[i].time_msc=", ticks[i].time_msc, " (", ticks[i].time, ")");
            i = i / zero;
         }
      }
      Print("done");
   } while(true);
}

以下はその出力です。

2018.10.17 21:31:26.221 2017.08.01 12:00:00 dt[0]=2017.08.01 03:00:00

2018.10.17 21:31:26.221 2017.08.01 12:00:00 cnt=2000

2018.10.17 21:31:26.221 2017.08.01 12:00:00 ERROR: i=0, ticks[i].time_msc=1501552175606 (2017.08.01 01:49:35)

つまり、03:00からリクエストして、01:49から受信しました。実際の条件では、その差は1ヶ月以上ありました。

 
経験者の方に質問です。新鮮なダニを入手するこの方法には、どのような落とし穴が考えられるのでしょうか?
input datetime inFrom = __DATETIME__;

// Свежие тики с последнего вызова
int GetFreshTicks( MqlTick &Ticks[] )
{
  static long LastTime = 0;
  static int LastAmount = 0;
  
  ArrayFree(Ticks);

  int Size = CopyTicksRange(_Symbol, Ticks, COPY_TICKS_INFO, LastTime ? LastTime : (long)inFrom * 1000);
  
  if (Size > LastAmount)
  {
    LastTime = Ticks[Size - 1].time_msc;
    int NewLastAmount = 1;
    
    for (int i = Size - 2; (i >= LastAmount) && (Ticks[i].time_msc == LastTime); i--)
      NewLastAmount++;
      
    if (ArrayRemove(Ticks, 0, LastAmount))
      Size -= LastAmount;
      
    LastAmount = NewLastAmount;
  }
  else
    Size = ArrayResize(Ticks, 0);
  
  return(Size);
}

void OnTick()
{
  MqlTick Ticks[];
  
  if (GetFreshTicks(Ticks))
    ArrayPrint(Ticks);
}
 
fxsaber:
ここで、専門家の方に質問です。この方法で新鮮なダニを入手する場合、どのようなエラーが発生する可能性がありますか?

同じ時刻の刻みの順番は保証されていないようです。

トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム

リアルタイムの刻み

アンドレイ・ハチムリアンスキー さん 2020.01.31 14:40

ちなみに、ダニの正しい採取法については、Vasily Sokolov氏の素晴らしい記事が あります。そこにはアナログ同期処理の詳細が書かれています(私はこれを持っていないので、時々同じ目盛りが印刷されることがあります)。

しかし、CopyTiks関数では、最後のN個のティックを要求することはできません。その代わり、指定した時刻に発生したすべてのティックを提供します。これが作業を複雑にしている。クエリーを実行し、tickの配列を取得し、前回の更新時に受け取ったtickの配列と比較する必要があります。同時に、新しく受け取ったティックのうち、どれが「前の供給」に含まれないか、つまり新しいものかを調べます。しかし、両者の刻みを直接比較することは不可能で、単に目に見える違いが全くない場合もあるからです。例えば、下の取引表を見てみましょう。

図5.全案件の一覧と同一案件の例。

すぐに全く同じダニの2つのグループを見ることができます。赤枠で示されたものは、時間、数量、方向、価格が同じである。このように、個々のダニ同士を比較することは不可能であることがわかります。

しかし、一群の ダニを比較することは可能である。2つのティックのグループが互いに等しい場合、これらのティックとそれに続くティックは、前回の価格更新時にすでに分析されたと結論付けることができます。


Пишем скальперский стакан цен на основе графической библиотеки CGraphic
Пишем скальперский стакан цен на основе графической библиотеки CGraphic
  • www.mql5.com
Именно с этой, улучшенной и дополненной версией мы и начнем работать, чтобы постепенно превратить ее в скальперский стакан цен. Краткий обзор графической библиотеки CPanel Созданию пользовательских интерфейсов в MQL5 посвящено много статей. Среди них особенно выделяется серия Анатолия Кажарского "Графические интерфейсы", после которой сложно...
 
Andrey Khatimlianskii:

同じ時刻の刻みの順番は保証されていないようです。

ティックのグループということであれば、コード上は何も問題ないようです。

 
チックキャッシュはリセットされません。
#define  TOSTRING(A) " " + #A + " = " + (string)(A)

MqlTick Ticks[];

void OnInit()
{
  Print(__FUNCTION__ + TOSTRING(TerminalInfoInteger(TERMINAL_MEMORY_USED)) + TOSTRING(MQLInfoInteger(MQL_MEMORY_USED))); // Распечатываем начальное состояние памяти.
  
  CopyTicksRange(_Symbol, Ticks, COPY_TICKS_INFO, D'2020.01.01' * 1000); // Получили историю тиков для инициализации по ней советника.
}

void OnTick()
{
  const int Size = ArraySize(Ticks);
  
  if (Size)
  {
    const long BeginTime = Ticks[Size - 1].time_msc;
    
    ArrayFree(Ticks);
    
    CopyTicksRange(_Symbol, Ticks, COPY_TICKS_INFO, BeginTime); // Получаем свежие тики без пропусков, чтобы гнать по ним советник.
  }
  
  Print(__FUNCTION__ + TOSTRING(TerminalInfoInteger(TERMINAL_MEMORY_USED)) + TOSTRING(MQLInfoInteger(MQL_MEMORY_USED))); // Распечатываем текущее состояние памяти.
}


結果(コールド運転-ターミナル起動直後)。

OnInit TerminalInfoInteger(TERMINAL_MEMORY_USED) = 395 MQLInfoInteger(MQL_MEMORY_USED) = 1
OnTick TerminalInfoInteger(TERMINAL_MEMORY_USED) = 446 MQLInfoInteger(MQL_MEMORY_USED) = 1
OnTick TerminalInfoInteger(TERMINAL_MEMORY_USED) = 446 MQLInfoInteger(MQL_MEMORY_USED) = 1
OnTick TerminalInfoInteger(TERMINAL_MEMORY_USED) = 446 MQLInfoInteger(MQL_MEMORY_USED) = 1


Expert Advisor をオフにすることは可能ですが、ターミナルによる消費は何も変わりません。