Probando 'CopyTicks' - página 41

 
Me encontré con un error donde CopyTicksRange devuelve todos los ticks solicitados correctamente, pero LastError == ERR_HISTORY_TIMEOUT(4403).


 
fxsaber:

Los archivos tkc se desglosan por meses. Preguntas a causa de esto

  1. Si el terminal aún no tiene los datos de los ticks cargados, cuando se llama a CopyTicks, ¿cómo sabe el terminal qué archivos tkc debe extraer?
Se extrae cada mes, comenzando por el mes actual.
  1. ¿Se implementa CopyTicksRange basado en CopyTicks o de forma independiente?
Basado en CopyTicks, es decir, no está optimizado en absoluto.
  1. ¿Estoy en lo cierto al entender que obtener ticks para septiembre, por ejemplo, siempre será más rápido a través de CopyTicksRange, que a través de CopyTicks, porque CopyTicks no sabe a través de los parámetros de entrada, para qué mes se deben extraer los datos?

No, CopyTicksRange será igual de lento debido al punto anterior. Aquí hay un script que muestra algunas cosas absurdas de la implementación actual de 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));
}

Parece que se da una información clara sobre qué archivos tkc se deben extraer. Pero no, tirará de la misma manera que CopyTicks - todos los archivos tkc. Y dejará de funcionar por tiempo de espera. Pero en realidad debería funcionar casi al instante.

  1. Hay que poner el historial en el indicador lo antes posible. Es posible solicitarlo a través de CopyTicksRange y obtener un -1 hasta que se descargue todo. Y si se solicita por meses: el mes actual, luego el anterior, etc. No será más lento, pero el indicador estará listo para trabajar con al menos algo de historia. ¿Verdad?

Resulta que no hay diferencia (ver puntos anteriores).

 

CopyTicks no funciona en OnDeinit siUninitializeReason !=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();
}


Resultado (tras la eliminación del Asesor Experto)

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

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


Esto ocurre en los Asesores Expertos. En los indicadores, CopyTicks funciona normalmente en OnDeinit.

 
Cuando se cambia la cuenta(a otro servidor de comercio) necesitamos escribir en el archivo los últimos 2000 ticks de la cuenta antigua. ¿Cómo hacerlo?


Esto no funcionará.

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

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

  FileSave(__FILE__, Ticks);
}


Por favor, genere el evento CHARTEVENT_ACCOUNTCLOSING antes del cambio de cuenta, cuando lo procese (en OnChartEvent) todo el entorno de negociación aún no ha cambiado al nuevo.

 
fxsaber:
Al cambiar la cuenta(otro servidor de comercio) es necesario escribir en el archivo los últimos 2000 ticks de la cuenta antigua. ¿Cómo lo hago?


Esto no funcionará.


Antes de cambiar la cuenta, por favor, genere el evento CHARTEVENT_ACCOUNTCLOSING, cuando lo procese (en OnChartEvent) todo el entorno de negociación aún no ha cambiado al nuevo.

De forma inteligente, deberíamos añadir una retroalimentación, como se hace en Windows.

En la forma de una bandera en el evento gráfico (o no gráfico), cuando se establece, el evento en sí (en este caso, el cambio de cuenta) se cancela.

 

Que sea brusco, pero es molesto que decenas de informes de errores, se arreglen, y sigan apareciendo otros nuevos con este CopyTicks.

Me cansan esos trucos.

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


Resultado

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


Eliminar una del código fuente

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


Se reproduce en diferentes personajes y servidores comerciales. Comprobado en el día libre - los kotirs están de pie.


¿Cuándo se derrotarán los bichos en este hilo?

 

Efectivamente, una característica tan interesante en el lenguaje, y que funciona desde el principio...

He aquí una pregunta. He descargado los ticks manualmente (685.007 ticks) a través del menú Símbolos. Necesito para EURUSD de 2016.11.01 00:00 a 2016.11.08 00:00. Aquí tienes una captura de pantalla.



Lo solicito de forma programada así:

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


La salida es 0. ¿Qué ocurre?

 
Dennis Kirichenko:

La salida es 0. ¿Qué pasa?

Multiplica por 1000 desde y hasta.

 
fxsaber:

Multiplica por 1.000 desde y hasta.


Qué vergüenza, me he equivocado. Gracias.

 
Se ha perdido mucho tiempo en localizar este error 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);
  }
}

Después de la primera ejecución en EURUSD M1 MetaQuotes-Demo tenemos un resultado correcto

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


Todas las próximas ejecuciones mostrarán un error

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 situación se repetirá después de recargar el terminal: primera ejecución - bien, siguientes ejecuciones - error.


SZY ¡Nota el comentario destacado en la fuente!