Analogo a iBarShift - pagina 4

 
Nikolai Semko:

Secondo me, l'uso della funzioneSeriesInfoInteger è ridondante, perché non è libera.

Era:

Diventato:

Guadagno di velocità di circa un fattore e mezzo.

2% di guadagno. Nota.

non funzionerà correttamente con PERIOD_W1 e PERIOD_MN1, perché viene contato dal 1° gennaio 1970, ed è giovedì, non lunedì. E ogni mese ha un numero diverso di secondi.

Questo deve essere aggiunto alla documentazione di PeriodSeconds.

 
Aleksey Vyazmikin:

Non l'ho controllato - perché ho bisogno di sapere con certezza se il codice funzionerà o meno per una situazione specifica, perché non è corretto incolpare qualcun altro se tu stesso hai fatto un errore.

Sto parlando di situazioni come questa: supponiamo di avere 14 ore in un giorno (o meno, se non ci fossero quotazioni ogni ora), ho un grafico M1 e ho bisogno di sapere lo spostamento di una barra su M15 per il giorno precedente. Cioè, tutto funzionerà correttamente se ho 45 minuti in un'ora o 14 ore in un giorno, o qualsiasi altro calo di tempo/commutazione?

Personalmente penso che sia appropriato utilizzare una tale funzione:

int iBarShift(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

   if((time!=LastTime) || (Symb!=LastSymb) || (TimeFrame!=LastTimeFrame))
     {
      Res=::Bars(Symb,TimeFrame,time,UINT_MAX)-1; 
      if(Res<0) Res=0;

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }

Ma va notato che non è un analogo completo della funzioneiBarShift di MQL4, almeno per il fatto che non ha il parametroExact

Altrimenti è identico.

Sto incollando un semplice script MQL4 che mostra la piena identità della funzione standard con questa.

Se i valori della funzione standardiBarShift e della mia funzione non sono uguali, allora Print. Non mi ha stampato nulla.

//+------------------------------------------------------------------+
//|                                                    iBarShift.mq4 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   datetime t=TimeCurrent()+1000;
   const ENUM_TIMEFRAMES tf[9]={PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4,PERIOD_D1,PERIOD_W1,PERIOD_MN1};
   while(!IsStopped())
     {
      for(int i=0; i<9;i++)
        {
         int i1=iBarShift(NULL,tf[i],t);
         int i2=iBarShift2(NULL,tf[i],t);
         if(i1!=i2) Print(EnumToString(tf[i]),"   ",TimeToString(t),"   ",i1,"   ",i2);
        }
      t-=10;
      Comment(TimeToString(t));
     }

  }
//+------------------------------------------------------------------+
int iBarShift2(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

   if((time!=LastTime) || (Symb!=LastSymb) || (TimeFrame!=LastTimeFrame))
     {
      Res=::Bars(Symb,TimeFrame,time,UINT_MAX)-1;
      if(Res<0) Res=0;

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }
//+------------------------------------------------------------------+
 
fxsaber:

Tasso di vincita del 2%. Nota.

Cosa, davvero?

Ero troppo pigro per mettere GetMicrosecondCount(), quindi mi sono fidato del profiling.

 
Nikolai Semko:

Davvero?

Ero troppo pigro per impostare GetMicrosecondCount(), quindi mi sono fidato del profiling.

Il profiling riguarda qualcos'altro. Il 2% è il massimo guadagno che si può ottenere.

250 milioni di chiamate nel Tester sulla mia macchina danno un risparmio di 1 secondo.

Sicuramente la tua opzione è la migliore! Ma non riesco nemmeno a immaginare perché in MT5 si debba lavorare con le barre.

 
fxsaber:

Ma non ho idea del perché in MT5 devo lavorare con le barre.

Lo uso quando controllo il mouse. Per esempio qui.

 
Nikolai Semko:

Lo uso quando controllo il mouse. Qui, per esempio.

Sì, è questo che non capisco.

 
fxsaber:

Sì, è questo che non capisco.

E non capisco il malinteso ))

Per esempio, ho un canale, una delle cui caratteristiche è il tempo di inizio (bordo sinistro). E ho bisogno di costruire questo canale su diversi TF. Bene, quale altra alternativa ho se non trovare il numero di bar in un nuovo TF?

Ho un sacco di altre cose.

Per esempio, quando combino tutti i TF in uno solo con una scala logaritmica. Questo è un argomento molto bello. Anche qui non si può fare a meno dell'analogo iBarShift

 
Nikolai Semko:

Personalmente penso che sia ragionevole usare una tale funzione:

Ma va notato che non è un analogo completo della funzione standard MQL4iBarShift, almeno perché non ha il parametroExact

Altrimenti è identico.

Sto incollando un semplice script MQL4 che mostra la piena identità della funzione standard con questa.

Se i valori della funzione standardiBarShift e della mia funzione non sono uguali, allora Print. Non ho stampato nulla.

No, non l'ha fatto a causa di Comment().

Se lo rimuovi, c'è una mancata corrispondenza di 1, ma non credo che sia un errore, perché in effetti la nuova barra è definita in due algoritmi con uno spostamento di mezza barra. La mia versione del rilevamento delle nuove barre mi sembra più logica di quella standard.

 
Nikolai Semko:

E non capisco il malinteso ))

Non capisco il senso dell'uso delle barre. CopyRate ecc.

 

Perché lo script è così lento?

2018.03.30 09:21:05.208 BS (Si Splice,H4) 1 Start=15 Stop=3 Day_Shift=0 index=0

2018.03.30 09:21:05.208 BS (Si Splice,H4) 1 Start=2018.03.26 00:00 Stop=2018.03.29 00:00 Day_Shift=2018.03.29 20:00 index=0

2018.03.30 09:21:20.209 BS (Si Splice,H4) 2 Start=15 Stop=3 Day_Shift=0 index=0

2018.03.30 09:21:20.209 BS (Si Splice,H4) 2 Start=2018.03.26 00:00 Stop=2018.03.29 00:00 Day_Shift=2018.03.29 20:00 index=0

2018.03.30 09:20:49.300 Scripts script BS (Si Splice,H4) loaded successfully

2018.03.30 09:21:20.209 Scripts script BS (Si Splice,H4) removed

//+------------------------------------------------------------------+
//|                                                    iBarShift.mq4 |
//|                        Copyright 2017, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property script_show_inputs

input ENUM_TIMEFRAMES TF=PERIOD_D1;
input int Bar=3;
input int calcN=1;
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
   for(int index=0;index<calcN;index++)
     {
      int Day_Shift=iBarShift(_Symbol,TF,iTime(_Symbol,PERIOD_CURRENT,index),false);
      int Start=iBarShift(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Bar+Day_Shift),false);
      int Stop=iBarShift(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Day_Shift),false);

      if(index<3)Print("1 Start=",Start," Stop=",Stop," Day_Shift=",Day_Shift," index=",index);

      if(index<3)Print("1 Start=",TimeToString(iTime(_Symbol,TF,Bar+Day_Shift),TIME_DATE|TIME_MINUTES),
         " Stop=",TimeToString(iTime(_Symbol,TF,Day_Shift),TIME_DATE|TIME_MINUTES),
         " Day_Shift=",TimeToString(iTime(_Symbol,PERIOD_CURRENT,index),TIME_DATE|TIME_MINUTES)," index=",index);
     }



   for(int index=0;index<calcN;index++)
     {
      int Day_Shift=iBarShift2(_Symbol,TF,iTime(_Symbol,PERIOD_CURRENT,index),false);
      int Start=iBarShift2(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Bar+Day_Shift),false);
      int Stop=iBarShift2(_Symbol,PERIOD_CURRENT,iTime(_Symbol,TF,Day_Shift),false);

      if(index<3)Print("2 Start=",Start," Stop=",Stop," Day_Shift=",Day_Shift," index=",index);

      if(index<3)Print("2 Start=",TimeToString(iTime(_Symbol,TF,Bar+Day_Shift),TIME_DATE|TIME_MINUTES),
         " Stop=",TimeToString(iTime(_Symbol,TF,Day_Shift),TIME_DATE|TIME_MINUTES),
         " Day_Shift=",TimeToString(iTime(_Symbol,PERIOD_CURRENT,index),TIME_DATE|TIME_MINUTES)," index=",index);
     }
   return;

  }
//+------------------------------------------------------------------+ 
//| Получим iBarShift для заданного номера бара                      | 
//+------------------------------------------------------------------+  
int iBarShift2(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

   if((time!=LastTime) || (Symb!=LastSymb) || (TimeFrame!=LastTimeFrame))
     {
      Res=::Bars(Symb,TimeFrame,time,UINT_MAX)-1;
      if(Res<0) Res=0;

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }
//+------------------------------------------------------------------+ 
//| Получим iBarShift для заданного номера бара                      | 
//+------------------------------------------------------------------+   
int iBarShift(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;

   if((time!=LastTime) || (Symb!=LastSymb) || (TimeFrame!=LastTimeFrame))
     {
      Res=::Bars(Symb,TimeFrame,time,UINT_MAX)-1;
      if(Res<0) Res=0;

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
     }
   return(Res);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime iTime(string symbol,ENUM_TIMEFRAMES tf,int index)
  {
   if(index < 0) return(-1);
   datetime Arr[];
   if(CopyTime(symbol,tf,index,1,Arr)>0)
      return(Arr[0]);
   else return(-1);
  }
//+------------------------------------------------------------------+