FORTALEZAS Por favor, ayuda - página 6

 
Serj_Che:
¿Por qué se repite en OnCalculate lo que había en OnInit? ¿Es ese un hechizo?)

Es simple magia de copiar y pegar))

Bien, te lo explicaré popularmente. No basta con comprobar la disponibilidad de los datos una vez en el inite. Como los datos se generan de forma asíncrona (para no ralentizar el proceso principal), es posible que se produzca un error de datos en el momento de la comprobación en el init (depende de muchos factores).

Por lo tanto, debe comprobar y (o sólo) en calcular y no iniciar los cálculos principales hasta que todos los datos requeridos están disponibles - es decir, comprobar hasta que esté listo en cada tic.

 
Dima_S:

Es simple magia de copiar y pegar))

Bien, te lo explicaré popularmente. No basta con comprobar la disponibilidad de los datos una vez en el inite. Como los datos se generan de forma asíncrona (para no ralentizar el proceso principal), en el momento de la comprobación en el init, es muy posible que se produzca un error de datos (depende de muchos factores).

Por eso la comprobación debe hacerse y(o sólo) en el cálculo y no comenzar los cálculos principales hasta que se disponga de todos los datos necesarios, es decir, comprobar hasta que esté listo en cada tic.

De eso estamos hablando, la función OnInit del indicador es una farsa, o los desarrolladores no están haciendo su trabajo.

Copiar y pegar es una gran cosa, yo mismo lo hago )).

 

Gritaron y llamaron a chukchi, ¡pero el problema no se ha resuelto!

//+------------------------------------------------------------------+
//|                                                         Test.mq5 |
//|                        Copyright 2014, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//
bool is_failed = false;
datetime start_time;
datetime end_time;
int mix_bars, rts_bars, si_bars;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
    start_time = StringToTime( "2015.03.17" );
    end_time = TimeCurrent();
//--- indicator buffers mapping
  mix_bars = GetBars( "MIX-6.15" , PERIOD_CURRENT, start_time, end_time ); 
  if ( mix_bars < 1 )
  {
    is_failed = true;
    Print( "Init failed. MIX-6.15 ");
  }
  rts_bars = GetBars( "RTS-6.15" , PERIOD_CURRENT, start_time, end_time ); 
  if ( rts_bars < 1 )
  {
    is_failed = true;
    Print( "Init failed. RTS-6.15 ");
  }
  si_bars = GetBars( "Si-6.15" , PERIOD_CURRENT, start_time, end_time ); 
  if ( si_bars < 1 )
  {
    is_failed = true;
    Print( "Init failed. Si-6.15 ");
  }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator Get bars function                               |
//+------------------------------------------------------------------+
int GetBars( string symbol, ENUM_TIMEFRAMES period, const datetime start_date, const datetime end_date )
{
  if ( !SymbolInfoInteger( symbol, SYMBOL_SELECT ) )
  {
    ResetLastError();
//---    
    if ( GetLastError() != ERR_MARKET_UNKNOWN_SYMBOL )
    {
      SymbolSelect( symbol, true );
    }
    else
    {
      Print( "GetBars: Неизвестный символ - ", symbol );
      return( 0 );
    }    
  }
//---  
  if ( MQL5InfoInteger( MQL5_PROGRAM_TYPE ) == PROGRAM_INDICATOR && Period() == period && Symbol() == symbol )
  {
    Print( "GetBars: Не пройдена проверка типа программы!" );
    return( 0 );
  }  
//---
  if ( SymbolIsSynchronized( symbol ) )
  {
    return( Bars( symbol, period, start_date, end_date ) );
  }
  else
  {
    long first_date = 0;
    datetime times[1];
//---    
    if ( SeriesInfoInteger( symbol, PERIOD_M1, SERIES_TERMINAL_FIRSTDATE, first_date ) )
    {
      if ( first_date > 0 )
      {
//--- force timeseries build
        CopyTime( symbol, period, datetime( first_date ) + PeriodSeconds( period ), 1, times );
//--- check date
        if ( SeriesInfoInteger( symbol, period, SERIES_FIRSTDATE, first_date ) )
//---        
        if ( first_date > 0 && first_date <= long( start_date ) )
        {
          return( Bars( symbol, period, start_date, end_date ) );
        } 
      }
    }
    Print( "Необходима загрузка истории с сервера!");
  }       
//---  
  return( 0 );
}  
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//---
   if ( is_failed )
   {
     Print( "Sorry! Get Bars failed." );
   }
   else Print( "Bingo! We done.");
//--- return value of prev_calculated for next call
   return(rates_total);
  }

Todavía no he escrito la descarga del historial, pero los datos están en el terminal, ¡y NO salen de él a la primera!

2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Необходима загрузка истории с сервера!
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Init failed. RTS-6.15 
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Необходима загрузка истории с сервера!
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Init failed. Si-6.15 
2015.03.26 20:49:01.641 Test (MIX-6.15,M1)      Sorry! Get Bars failed.
 
Serj_Che:

Vale, ¡interesante!

Los indicadores trabajan en su propio hilo, los EAs en su propio hilo. A menos que, por supuesto, sea una piedra de núcleo único.

Todo sucede exactamente como está escrito en la documentación. :)

Esbocé un indicador y EA para probar + el resultado en el video.

1) Primero trazo un Asesor Experto en un gráfico con la función OnTick funcionando durante 20 segundos.

El resultado es que el gráfico sigue funcionando y muestra todo como debe ser. El gráfico también funciona como se esperaba.

2) Luego aplicamos al gráfico el indicador que tiene la funciónOnCalculate durante 20 segundos.

El resultado: el chat se cuelga. Al mismo tiempo, la siguiente ventana de chat con el mismo símbolo y un período diferente también se suspende. El cristal sigue funcionando como debe. Una vez que la función ha funcionado, todo vuelve a la normalidad.

¡3) El video no lo tiene - pero si usted lanza el indicador en un chat (fijado 60 seg), y el experto en el otro - el experto no comienza a trabajar hasta que el indicador en el otro chat glitches!

He adjuntado el vídeo por separado - mi navegador es lento.

 
MigVRN:

Todo sucede exactamente como dice la documentación. :)

Esbozado un indicador y un Asesor Experto para comprobar + el resultado en el video.

1) Primero lo lancé al gráfico del Asesor Experto que tiene la función OnTick dentro de él que funciona durante 20 segundos.

El resultado es que el gráfico sigue funcionando y muestra todo como debe ser. El gráfico también funciona como se esperaba.

2) Luego aplicamos al gráfico el indicador que tiene la funciónOnCalculate durante 20 segundos.

El resultado: el chat se cuelga. Al mismo tiempo, el siguiente chat con el mismo símbolo que tiene un período diferente también se suspende. El cristal sigue funcionando como debe. Una vez que la función ha funcionado, todo vuelve a la normalidad.

¡3) El video no lo muestra - pero si usted lanza un indicador en un chat (fijado 60 seg), y un EA en el otro - el EA no comienza a trabajar hasta que el indicador funciona mal en otro chat!

Adjunto el vídeo por separado - se ralentiza en mi navegador.

Gracias, no consigo ver un vídeo, lo investigaré.

 

Si está tratando de obtener datos del entorno comercial cuando trabaja desde el indicador, ni siquiera intente establecer consultas en OnInit(). Realiza consultas y comprueba la respuesta en OnCalculate(). Cuando se reciben datos de otro símbolo o de otro marco temporal está casi garantizado que incluso en OnCalculate no se logrará recibir datos de la primera vez. Por eso hay que comprobar el retorno de los valores. Si no se obtienen valores, se intenta obtener los datos en el siguiente tick en OnCalculate().


También ya es interesante ver la respuesta de servicedesk - el código que se proporcionó.

Foro sobre comercio, sistemas de comercio automatizados y pruebas de estrategias

FORTS Por favor, ayuda

alexvd, 2015.03.26 15:48

Usted ha recibido el código fuente de servisdesk. Intenta poner tu último código en la función Test().

Ya el interés deportivo - el autor sigue escribiendo su propio código e ignora el código de servicedesk?

 
barabashkakvn:

Si está tratando de obtener datos del entorno comercial cuando trabaja desde el indicador, ni siquiera intente establecer consultas en OnInit(). Realiza peticiones y comprueba la respuesta en OnCalculate(). Cuando se reciben datos de otro símbolo o de otro marco temporal está casi garantizado que incluso en OnCalculate no se conseguirá recibir datos de la primera vez. Por eso hay que comprobar la devolución de los valores. Si no se reciben valores, intenta recibir datos en el siguiente tick en OnCalculate().

+++ y así hasta el final. Es decir, si no hay datos - volver;
 
MigVRN:
+++ y así hasta el final. Es decir, si no hay datos, devuelve;
Depende de lo que quiera consultar. Y el número de consultas a realizar depende totalmente de las preferencias del redactor del código.
 
barabashkakvn:
Depende de lo que se consulte. Y cuántas consultas: depende totalmente de las preferencias del redactor del código.

Usted entiende que

Si hay datos en el terminal, la función

SeriesInfoInteger( symbol, PERIOD_M1, SERIES_TERMINAL_FIRSTDATE, first_date )

no debería devolver FALSE?

¡P/S el código SD tampoco funciona desde la primera vez!

 

UNA VEZ MÁS.

de la ayuda:

SeriesInfoInteger

Devuelve información sobre el estado de los datos históricos. Hay 2 variantes de la función.

Segunda variante:

bool  SeriesInfoInteger(
   string                     symbol_name,     // имя символа
   ENUM_TIMEFRAMES            timeframe,       // период
   ENUM_SERIES_INFO_INTEGER   prop_id,         // идентификатор свойства
   long&                      long_var         // переменная для получения информации
   );

SERIE_TERMINAL_PRIMERAFECHA.

Primera fecha en el historial según el símbolo en el terminal del cliente, independientemente del periodo

datetime

¡¡¡LA FUNCIÓN NO DEBE DEVOLVER FALSE SI HAY DATOS EN EL TERMINAL!!!

No importa desde dónde lo llames.