Bibliotecas: IsNewBar

 

IsNewBar:

La clase СIsNewBar permite determinar el momento de una barra cambiando.

Autor: Nikolay Kositsin

 
No soy un profesional, pero creo que este código es incorrecto. La variable Recount es siempre verdadera. Por lo tanto, cada tick será tratado como una nueva barra. ¿Por qué existe esta variable? ¿Por qué llamar a CopyClose? ¿Se comprueba el correcto funcionamiento de los códigos publicados? Si estoy equivocado, por favor corrija y explique.
 
lordlev:
No soy un profesional, pero creo que este código es incorrecto. La variable Recount es siempre verdadera. Por lo tanto, cada tick será tratado como una nueva barra. ¿Por qué existe esta variable? ¿Por qué llamar a CopyClose? ¿Se comprueba el correcto funcionamiento de los códigos publicados? Si estoy equivocado, por favor corrija y explique.
He vuelto a comprobarlo todo y he encontrado un error. En el propio archivo adjunto no hay ninguna asignación de Recount a false, pero en el código de ejemplo todo es correcto.
 
lordlev:
He vuelto a comprobarlo todo y he encontrado un error. En el propio archivo adjunto no hay ninguna asignación de Recount a false, pero en el código de ejemplo todo es correcto.
Bueno, ¡se puede arreglar!
 

Tal vez me equivoque, pero creo que esta es la forma correcta de hacerlo.

if(TNew>m_TOld)

De lo contrario, será inexacta durante la paginación (edición de la historia).

¿Podría explicar qué es esto y por qué se inserta esta comprobación?

if(...  && TNew)

No lo entiendo. ¿Cuándo es verdadera esta condición, cuándo es falsa? Gracias

 
Prival:

¿Pueden explicarme qué es esto y por qué se inserta esta comprobación?

No lo entiendo. ¿Cuándo es verdadera esta condición y cuándo es falsa? Gracias.

Imho, comprueba que TNew no es igual a m_TOld y al mismo tiempo no es igual a cero ( i.e. D'1970.01.01.01 00:00:00:00')....

La segunda condición, también imho, comprueba que la función

datetime TNew=datetime(SeriesInfoInteger(symbol,timeframe,SERIES_LASTBAR_DATE));

haya devuelto algo distinto de cero...

Ahora corrí el script con esta función - me devolvió exactamente 0. Tal vez debido al fin de semana.

 
Prival:

¿Pueden explicarme qué es esto y por qué se inserta esta comprobación?

No lo entiendo. ¿Cuándo es verdadera esta condición y cuándo es falsa? Gracias.

La comprobación de cero es necesaria para evitar que al inicio y en la primera comprobación de la condición aparezca el comienzo de una nueva barra (por mucho tiempo que haya pasado desde su apertura).
 
Prival:

Tal vez me equivoque, pero creo que esta es la forma correcta de hacerlo.

De lo contrario, habrá inexactitud de trabajo durante la paginación (edición de la historia).

¿Podría explicar qué es y por qué se inserta esta comprobación?

No lo entiendo. ¿Cuándo es verdadera esta condición, cuándo es falsa? Gracias.

Creo que sería más lógico hacerlo por precaución.

if(TNew>m_TOld && TNew)

aunque TNew seguirá siendo cero cuando se intercambie el historial. Un cero puede entrar en la variable TNew en cualquier momento, así que deberías comprobar si es cero todo el tiempo.

 
Automated-Trading:

IsNewBar:

Autor: Nikolay Kositsin

Hay un pequeño error en tu clase(como en la mayoría de las funciones en las que he visto el código). La primera vez que llamas a tu método IsNewBar, siempre devuelve true, independientemente de la existencia de una nueva barra real .

Pero tal función contiene una variable estática, y por lo tanto no podemos utilizar varias llamadas de esta función.

También se puede utilizar un array bidimensional para guardar la hora de apertura de la última barra.

 
Hice una versión alternativa de CIsNewBar, sin ninguna variable estática. Acabo de utilizar el Tick.time_msc para hacer una función idempotent :


class CIsNewBar{
private:
   long checkedMs;
   datetime lastBarOpenedAt;
   bool lastValue;
   CTickUtils tickUtils;
public:
   CIsNewBar(){}
   ~CIsNewBar(){}

   bool isNewBar(){
      MqlTick tick;
      SymbolInfoTick(_Symbol, tick);
      long tickMs = tick.time_msc;

      
      if(checkedMs >= tickMs){ //¿ya procesó esta función en este tick?
         return lastValue;     //así, devuelve el valor almacenado
      }

      datetime time[1];
      CopyTime(_Symbol, _Period, 0, 1, time);


      if(lastBarOpenedAt != time[0]){
         lastBarOpenedAt = time[0];
         lastValue = true;
      } else {
         lastValue = false;
      }

      checkedMs = tickMs;
      return lastValue;
   }
 

Creo que es una clase ligera y rápida que soluciona los problemas mencionados.

Esta versión

  • no dará una falsa alerta la primera vez que se llame a la función.isNewBar().
  • elimina la constante re-instanciación de nuevas variables cada vez que se llama a la función sin usar variables estáticas, lo que acelera la ejecución.
  • sólo devuelve true una vez por barra.
  • ocupa poca memoria.
class CIsNewBar{
        private:
                datetime lastBarOpenedAt;
                datetime time[1];
        public:
                CIsNewBar(){CopyTime(_Symbol, _Period, 0, 1, time);lastBarOpenedAt = time[0];}
                ~CIsNewBar(){}
                bool isNewBar(){
                        CopyTime(_Symbol, _Period, 0, 1, time);
                        if(lastBarOpenedAt < time[0]){
                                lastBarOpenedAt = time[0];
                                return(true);
                                }
                        else { return(false);}
                        }
        };

Para implementar la clase:

CIsNewBar someName;

void OnTick(){
        if(someName.isNewBar()){
                /// Llamar al nuevo manejador de eventos de la barra o
                /// Hacer el trabajo para la nueva barra. 
                }
        }
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
Documentation on MQL5: Constants, Enumerations and Structures / Named Constants / Predefined Macro Substitutions
  • www.mql5.com
Predefined Macro Substitutions - Named Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5