Testare 'CopyTicks'. - pagina 41

 
Si è imbattuto in un bug in cui CopyTicksRange restituisce correttamente tutti i tick richiesti, ma LastError == ERR_HISTORY_TIMEOUT(4403).


 
fxsaber:

I file tkc sono suddivisi per mese. Domande a causa di questo

  1. Se il terminale non ha ancora caricato i dati dei tick, quando chiamate CopyTicks, come fa il terminale a sapere quali file tkc tirare?
Tira ogni mese, a partire dal mese corrente.
  1. CopyTicksRange è implementato sulla base di CopyTicks o indipendentemente?
Basato su CopyTicks, cioè non ottimizzato affatto.
  1. Ho capito bene che ottenere i tick per settembre, per esempio, sarà sempre più veloce attraverso CopyTicksRange che attraverso CopyTicks, perché CopyTicks non sa, attraverso i parametri di input, per quale mese prendere i dati?

No, CopyTicksRange sarà altrettanto lento a causa del punto precedente. Ecco uno script che mostra alcune assurdità dell'attuale implementazione di 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));
}

Sembra essere chiaramente data l'informazione che i file tkc devono essere tirati. Ma no, tirerà allo stesso modo di CopyTicks - tutti i file tkc. E smetterà di funzionare per timeout. Ma in realtà dovrebbe funzionare quasi istantaneamente.

  1. Dovete mettere la storia nell'indicatore il più rapidamente possibile. È possibile richiederlo tramite CopyTicksRange e ottenere un -1 fino a quando tutto viene scaricato. E se si richiede per mese: mese corrente, poi mese precedente, ecc. Non sarà più lento, ma l'indicatore sarà pronto a lavorare con almeno un po' di storia. Giusto?

Nessuna differenza, a quanto pare (vedi punti precedenti).

 

CopyTicks non funziona in OnDeinit seUninitializeReason !=REASON_CHARTCHANGE

#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();
}


Risultato (dopo la rimozione di Expert Advisor)

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

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


Questo succede in Expert Advisors. Negli indicatori, CopyTicks funziona normalmente in OnDeinit.

 
Quando si cambia il conto(ad un altro server di trading) abbiamo bisogno di scrivere nel file gli ultimi 2000 tick del vecchio conto. Come fare?


Questo non funzionerà.

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

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

  FileSave(__FILE__, Ticks);
}


Si prega di generare l'evento CHARTEVENT_ACCOUNTCLOSING prima del cambio di conto, quando lo si elabora (in OnChartEvent) tutto l'ambiente di trading non è ancora passato a quello nuovo.

 
fxsaber:
Quando si cambia il conto(un altro server di trading) è necessario scrivere nel file gli ultimi 2000 tick del vecchio conto. Come si fa?


Questo non funzionerà.


Prima di cambiare il conto, genera l'evento CHARTEVENT_ACCOUNTCLOSING, quando lo elabora (in OnChartEvent) l'intero ambiente di trading non è ancora passato a quello nuovo.

Intelligentemente, dovremmo aggiungere un feedback, come si fa in Windows.

Come un flag in un evento grafico (o no), quando lo si imposta, l'evento stesso (in questo caso, il cambio di conto) viene annullato.

 

Che sia brusco, ma è fastidioso che dozzine di segnalazioni di bug, vengono risolti, e continuano a spuntare nuovi bug con questo CopyTicks.

Mi stanca questi trucchi.

#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)));
  }
}


Risultato

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


Rimuovere uno dal codice sorgente

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


Riprodotto su diversi personaggi e server commerciali. Controllato nel giorno libero - i quotisti sono in piedi.


Quando saranno sconfitti i bug in questo thread?

 

In effetti, una caratteristica così interessante nella lingua e funziona fuori dalla scatola...

Ecco una domanda. Ho scaricato i tick manualmente (685.007 tick) attraverso il menu Symbols. Ho bisogno di EURUSD dal 2016.11.01 00:00 al 2016.11.08 00:00. Ecco uno screenshot.



Sto richiedendo programmaticamente in questo modo:

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();
  }


L'uscita è 0. Cosa c'è di sbagliato?

 
Dennis Kirichenko:

L'uscita è 0. Cosa c'è che non va?

Moltiplicare per 1000 da e verso.

 
fxsaber:

Moltiplicare per 1.000 da e verso.


Vergogna, mi sono sbagliato. Grazie, amico.

 
Perso un sacco di tempo per localizzare questo bug 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);
  }
}

Dopo la prima esecuzione su EURUSD M1 MetaQuotes-Demo abbiamo un risultato corretto

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


Tutte le prossime esecuzioni mostreranno un bug

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


La situazione si ripeterà dopo aver ricaricato il terminale: prima corsa - bene, corse successive - bug.


SZY Notate il commento evidenziato nella fonte!