CopyTicks」のテスト - ページ 41

 
CopyTicksRange が要求されたすべての目盛りを正しく返しますが、LastError == ERR_HISTORY_TIMEOUT(4403) となるバグに遭遇しました。


 
fxsaber:

tkcファイルは月別に分かれています。このため質問

  1. ターミナルにまだティックデータがアップロードされていない場合、CopyTicks を呼び出すと、ターミナルはどの tkc ファイルをプルするのかがわかりますか?
当月を起点に毎月引きます。
  1. CopyTicksRangeはCopyTicksに基づいて実装されているのか、それとも独立して実装されているのか?
CopyTicksをベースに、つまり全く最適化されていない。
  1. CopyTicks は入力パラメータを通してどの月のデータを取得すべきかを知らないので、例えば 9 月の tick を取得するには、CopyTicks よりも CopyTicksRange の方が常に速いという理解で正しいですか?

いいえ、CopyTicksRangeも上記の点から、同じように遅くなります。以下は、CopyTicksRangeの現在の実装の不合理さを示すスクリプトです。

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

void OnStart()
{  
  
  MqlTick Ticks[];
  
  ResetLastError();
  
  Print(__FUNCTION__);
  Print(TOSTRING(CopyTicksRange(_Symbol, Ticks, COPY_TICKS_ALL, 1, 2)));
  Print(TOSTRING(_LastError));
}

どのようなtkc-filesを引かなければならないか、明確に情報提供されているようです。しかし、いいえ、それはCopyTicksと同じように、すべてのtkc-filesを引っ張ります。そして、タイムアウトで動作しなくなります。しかし、実際にはほとんど瞬時に動作するはずです。

  1. インジケータに履歴を早く表示させる必要があります。CopyTicksRangeでリクエストして、すべてダウンロードされるまで-1される可能性があります。また、当月、前月と月別に依頼する場合は、当月、前月、前々月となります。遅くなることはありませんが、少なくともある程度の履歴がある状態でインジケータが動作するようになります。そうだろ?

結論から言うと違いはない(上記のポイント参照)。

 

UninitializeReason !=REASON_CHARTCHANGE の場合、OnDeinit で CopyTicks が動作しない。

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

void TickTest()
{
  MqlTick Ticks[];

  ResetLastError();
  Print(TOSTRING(CopyTicks(_Symbol, Ticks)));
  Print(TOSTRING(_LastError));
}

void OnInit()
{
  Print("\n" + __FUNCTION__);
  
  TickTest();
}

void OnDeinit( const int )
{
  Print("\n" + __FUNCTION__);
  Print(TOSTRING(UninitializeReason()));
  
  TickTest();
}


結果(Expert Advisor削除後)

OnInit
CopyTicks(_Symbol,Ticks) = 2000
_LastError = 0

OnDeinit
UninitializeReason() = 1
CopyTicks(_Symbol,Ticks) = -1
_LastError = 4401


Expert Advisorで発生します。インジケータでは、OnDeinitでCopyTicksが正常に動作する。

 
あなたが口座を変更したとき(別の取引サーバーに)、私たちは古い口座の最後の2000ティックをファイルに書き込む 必要があります。どうすればいいのか?


これではうまくいきません。

void OnDeinit( const int )
{
  MqlTick Ticks[];

  CopyTicks(_Symbol, Ticks); // Если была смена торгового сервера, то БД-тиков поменялась

  FileSave(__FILE__, Ticks);
}


口座変更前にCHARTEVENT_ACCOUNTCLOSINGイベントを生成し、OnChartEventで処理する際には、すべての取引環境が新しいものに切り替わっていない状態にしてください。

 
fxsaber:
口座を変更する場合(別の取引サーバー)には、旧口座の直近2000ティックをファイルに書き込む 必要があります。どうすればいいのか?


これではうまくいきません。


口座を変更する前に、CHARTEVENT_ACCOUNTCLOSINGイベントを生成してください、それを処理するとき(OnChartEventで)、全体の取引環境はまだ新しいものに切り替わっていません。

知的には、Windowsで行われているように、フィードバックを追加すべきです。

チャート(またはチャート以外)イベントのフラグという形で、設定するとイベント自体(この場合、アカウント切り替え)がキャンセルされる。

 

唐突ですが、何十件ものバグ報告、それらは修正され、このCopyTicksで新しいバグがどんどん出てくるのは迷惑です。

そんな芸当は疲れる。

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

void OnStart()
{
  MqlTick Ticks[];

  if (CopyTicks(_Symbol, Ticks, COPY_TICKS_ALL, 0, 131072 + 1) > 0) // Если прибавлять не единицу, а ноль, то все будет работать
  {
    const ulong BeginTime = Ticks[0].time_msc;
    
    Print(TOSTRING(CopyTicksRange(_Symbol, Ticks, COPY_TICKS_INFO, BeginTime, LONG_MAX)));
    Print(TOSTRING(CopyTicksRange(_Symbol, Ticks, COPY_TICKS_INFO, BeginTime, (TimeCurrent() + 1) * 1000)));
  }
}


結果

CopyTicksRange(_Symbol,Ticks,COPY_TICKS_INFO,BeginTime,LONG_MAX) = 0
CopyTicksRange(_Symbol,Ticks,COPY_TICKS_INFO,BeginTime,(TimeCurrent()+1)*1000) = 131073


ソースコードから1つ削除する

CopyTicksRange(_Symbol,Ticks,COPY_TICKS_INFO,BeginTime,LONG_MAX) = 131072
CopyTicksRange(_Symbol,Ticks,COPY_TICKS_INFO,BeginTime,(TimeCurrent()+1)*1000) = 131072


異なるキャラクターやトレードサーバーで再現。休日に確認したところ、クオーターは立っている。


このスレでバグが討伐されるのはいつになるのか?

 

確かに、このような面白い機能を持った言語があり、しかもすぐに動作する...。

ここで質問です。シンボルメニューから手動でティックをダウンロードした(685,007ティック)。2016.11.01 00:00 から 2016.11.08 00:00 までのEURUSDについて必要です。以下はスクリーンショットです。



プログラム的にこのように要求しています。

void OnStart()
  {
   string symbol="EURUSD";
   MqlTick ticks_array[];
   uint flags=COPY_TICKS_INFO;
   ulong from_msc,to_msc;
   from_msc=(ulong)D'01.11.2016 00:00';
   to_msc=(ulong)D'08.11.2016 00:00';
//--- получить тики - 20 попыток
   for(int att=0;att<20;att++)
     {
      int copied=CopyTicksRange(symbol,ticks_array,flags,from_msc,to_msc);
      if(copied>0)
         break;
      Sleep(100);
     }
//--- остановка
   DebugBreak();
  }


出力が0になっているのですが、何がおかしいのでしょうか?

 
Dennis Kirichenko:

出力が0になっているのですが、どうしたのでしょうか?

から1000を掛け合わせる。

 
fxsaber:

からとからを1,000倍する。


恥ずかしながら、勘違いしてしまいました。ありがとうございます。

 
このバグをローカライズするのに多くの時間を費やした CopyTicksRange


template <typename T>
T MyPrint( const T Value, const string Str )
{
  static const bool IsDebug = MQLInfoInteger(MQL_DEBUG);

//  if (IsDebug)
  {
//    DebugBreak(); // если хочется посмотреть средствами дебага

    Print(Str + " = " + (string)Value);
  }
  
  return(Value);
}

#define _P(A) MyPrint(A, __FUNCSIG__ ", Line = " + (string)__LINE__ + ": " + #A)

int GetSymbolTicks( const string Symb, MqlTick &Ticks[] )
{
  const bool Selected = SymbolInfoInteger(Symb, SYMBOL_SELECT);

  const int Amount = SymbolInfoInteger(Symb, SYMBOL_CUSTOM) && (Selected || SymbolSelect(Symb, true)) ? _P(CopyTicksRange(Symb, Ticks, COPY_TICKS_INFO)) : -1; // здесь баг!
  
  if (!Selected)
    SymbolSelect(Symb, false);

  return(Amount);
}

bool TicksToSymbol( const string Symb, const MqlTick &Ticks[] )
{
  const int Size = ArraySize(Ticks);
  
  CustomTicksDelete(Symb, Ticks[0].time_msc, Ticks[Size - 1].time_msc);
  
  return(Size ? (_P(CustomTicksReplace(Symb, Ticks[0].time_msc, Ticks[Size - 1].time_msc, Ticks)) > 0) : false);
}

void OnStart()
{
  MqlTick Ticks[];
    
  if (CopyTicksRange(_Symbol, Ticks, COPY_TICKS_INFO, D'2017.12.01' * 1000, (TimeCurrent() + 1) * 1000) > 100) // Если поставить сегодня - D'2017.12.05', то баг не проявится
  {
    ArrayResize(Ticks, 100);
    
    static const string Name = _Symbol + "_Custom";
    
    CustomSymbolDelete(Name);
    
    if (CustomSymbolCreate(Name) && CustomSymbolSetInteger(Name, SYMBOL_DIGITS, _Digits))
    {    
      TicksToSymbol(Name, Ticks);
    
      MqlTick Ticks2[];
      
      GetSymbolTicks(Name, Ticks2);
    }

    CustomSymbolDelete(Name);
  }
}

EURUSD M1 MetaQuotes-Demoでの最初の実行の後、我々は正しい結果を持っています。

bool TicksToSymbol(const string,const MqlTick&[]), Line = 36: CustomTicksReplace(Symb,Ticks[0].time_msc,Ticks[Size-1].time_msc,Ticks) = 100
int GetSymbolTicks(const string,MqlTick&[]), Line = 22: CopyTicksRange(Symb,Ticks,COPY_TICKS_INFO) = 100


次の実行では、すべてバグが表示されます

bool TicksToSymbol(const string,const MqlTick&[]), Line = 36: CustomTicksReplace(Symb,Ticks[0].time_msc,Ticks[Size-1].time_msc,Ticks) = 100
int GetSymbolTicks(const string,MqlTick&[]), Line = 22: CopyTicksRange(Symb,Ticks,COPY_TICKS_INFO) = 0


ターミナルを再読み込みしても、最初の実行-問題なし、次の実行-バグという状況が繰り返されます。


SZY ソース内のハイライトされたコメントに注目!