Analogo a iBarShift - pagina 12

 
Nikolai Semko :

Hai detto che tutto dovrebbe funzionare in MQL4.

Ma questo script può essere eseguito anche in MQL5

Con exact=True e tempo futuro si dovrebbe restituire -1

Il mio script ha anche trovato uno strano errore:

Questo errore è confermato da questo controllo:

Quindi avevo ragione sull'esistenza di situazioni anomale nel vostro algoritmo, dopo tutto.

È bello che tu abbia finalmente trovato l'errore

Lo controllerò, grazie.

 

Buona sera a tutti. Forse sto fraintendendo qualcosa, ma comunque - non è del tutto chiaro cosa ci sia di sbagliato nella funzione standard, che è già stata suggerita all'inizio di Bars(). L'ho usato tutto il tempo e non ha causato alcun problema. L'unica cosa è che si può incontrare "array out of range" o valore negativo quando si usa TimeCurrent(), ma allora bisogna fare un controllo per questo. Esempi:

//найти бар на котором продали
Bar_sell_H4=Bars(Symbol(),PERIOD_H4,P_opentime,32000000000)-1;
if(Bar_sell_H4<=0)
   {
      Bar_time_sell_H4=Time_H4[0];
   }
else
   {
      Bar_time_sell_H4=Time_H4[Bar_sell_H4];
   }
Bars_forsearch_highfr_H1=Bars(Symbol(),PERIOD_H1,TimeCurrent(),Time_M15[B_DownTrend_M15_int]);
if(Bars_forsearch_highfr_H1<=0)
   {
      high_H1_int=0;
   }
else
   {
      high_H1_int=ArrayMaximum(High_H1,0,Bars_forsearch_highfr_H1);
   }
 
Almat Kaldybay:

Buona sera a tutti. Forse sto fraintendendo qualcosa, ma comunque - non è del tutto chiaro cosa ci sia di sbagliato nella funzione standard, che è già stata suggerita all'inizio di Bars(). L'ho usato tutto il tempo e non ha causato alcun problema. L'unica cosa è che si può incontrare "array out of range" o valore negativo quando si usa TimeCurrent(), ma allora bisogna fare un controllo per questo. Esempi:

A giudicare dal numero 32000000000 anche questa è una mia creazione. UINT_MAX è semplicemente più corto e dall'aspetto più solido. ))

Il punto è che questa variante è più corretta, come risulta:

Bars(Symb,TimeFrame,time+1,UINT_MAX);

piuttosto che

Bars(Symb,TimeFrame,time,UINT_MAX)-1;

non c'è quasi nessuna differenza esterna. Ma la variante superiore ripete molto precisamente la funzione standard iBarShift di MQL4

 
Nikolai Semko:

A giudicare dal numero 32000000000, anche questa è una mia creazione. UINT_MAX sembra semplicemente più corto e solido. ))

Il punto è che questa variante è più corretta, come risulta:

piuttosto che

non c'è quasi nessuna differenza esterna. Ma la variante superiore ripete molto precisamente la funzione standard iBarShift di MQL4.

Allora, qual è il più facile e quello giusto?

 
Vitaly Muzichenko:

Allora qual è la cosa più semplice e giusta da fare?

Finora questa variante, ma ora voglio integrarla per aggirare il bug del blocco della funzione Bars, di cui ho già riferito al Service Desk.

L'essenza di questo bug è che se nella funzione Bars siastart_time chestop_time sono dentro una barra o sono nel futuro (a destra della barra zero), allora questa funzione si blocca per più di 10 secondi.

Forse più tardi farò una versione più veloce ma più ingombrante.

 

Ho deciso di prendere un'altra strada.
Non rifarò iBarShift, ma rifarò la funzione Bars glitchata.

E la nuova funzione iBars non solo aggirerà il bug del singhiozzo, ma sarà anche più veloce delle Bars originali.

Altri saranno in grado di utilizzare questa funzione e gli algoritmi già esistenti lavoreranno più velocemente.

Ho solo bisogno di tempo. Sarò in grado di farlo non prima di un giorno.

 
Nikolai Semko:

Ho deciso di prendere una strada diversa.
Non rifarò iBarShift, ma rifarò la funzione Bars glitchata.

E la nuova funzione iBars non solo aggirerà il bug del singhiozzo, ma sarà anche più veloce delle Bars originali.

Altri saranno in grado di utilizzare questa funzione e gli algoritmi già esistenti lavoreranno più velocemente.

Ho solo bisogno di tempo. Non sarà in grado di farlo prima di un giorno.

Molto bene! Non vedo l'ora!

 
Nikolai Semko:

Da tutta l'analisi che ho fatto, possiamo concludere che questo analogo completo dell'iBarShift:

int iBarShift(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false)
  {
   int Res=Bars(Symb,TimeFrame,time+1,UINT_MAX);
   if(exact) if((TimeFrame!=PERIOD_MN1 || time>TimeCurrent()) && Res==Bars(Symb,TimeFrame,time-PeriodSeconds(TimeFrame)+1,UINT_MAX)) return(-1);
   return(Res);
  }

è di gran lunga il più corretto, e allo stesso tempo il più veloce e con l'algoritmo più semplice e breve.

È bello, ma qualcosa mi confonde...

dovrà testarlo)

 

La funzione iBars è abbastanza ingombrante, ma raccomando comunque di usarla al posto della normale Bars, finché MQ non risolve il bug di blocco in essa presente.

L'iBar si blocca quando logicamente dovrebbe restituire 0. Di regola, lo restituisce per più di 10 secondi. Non c'è un tale bug in MQL4.

Nella maggior parte dei compiti, iBars lavorerà più velocemente del normale Bars poiché non solo eviterà il bug, ma cercherà di non usare le funzioni Bars e SeriesInfoInteger quando possibile a causa dell'algoritmo di salvataggio dei valori precedenti.

int iBars(string symbol_name,ENUM_TIMEFRAMES  timeframe,datetime start_time,datetime stop_time) // stop_time > start_time
  {
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;
   static datetime LastTime0=0;
   static int PerSec=0;
   static int PreBars=0;
   static datetime LastBAR=0;
   static datetime LastTimeCur=0;
   datetime TimeCur;
   if(stop_time<start_time) {TimeCur=stop_time; stop_time=start_time; start_time=TimeCur; }
   TimeCur=TimeCurrent();
   if(start_time>TimeCur) {LastSymb=NULL; return(0);}
   if(LastTimeFrame!=timeframe) if(timeframe==PERIOD_MN1) PerSec =2419200; else PerSec=::PeriodSeconds(timeframe);
   if(LastTimeFrame!=timeframe || LastSymb!=symbol_name || ((TimeCur-LastBAR)>=PerSec && TimeCur!=LastTimeCur))
      LastBAR=(datetime)SeriesInfoInteger(symbol_name,timeframe,SERIES_LASTBAR_DATE);

   LastTimeCur=TimeCur;
   if(PerSec==0) return(0);
   if(start_time>LastBAR)
     {LastTimeFrame=timeframe; LastSymb=symbol_name; return(0);}

   datetime t,t0=0;
   bool check=true;
   if(timeframe<PERIOD_W1) t=start_time-(start_time-1)%PerSec;
   else if(timeframe==PERIOD_W1) t=start_time-(start_time-259201)%PerSec;
   else
     {
      PerSec=2678400;
      MqlDateTime dt;
      TimeToStruct(start_time-1,dt);
      t=dt.year*12+dt.mon;
     }
   if(stop_time<=LastBAR)
     {
      if(timeframe<PERIOD_W1) t0=stop_time-(stop_time)%PerSec;
      else if(timeframe==PERIOD_W1) t0=stop_time-(stop_time-259200)%PerSec;
      else
        {
         MqlDateTime dt0;
         TimeToStruct(stop_time,dt0);
         t0=dt0.year*12+dt0.mon;
        }
      if(t0==t) {PreBars=0; check=false;}
     }
   if((LastTimeFrame!=timeframe || LastSymb!=symbol_name || t!=LastTime || t0!=LastTime0) && check)
      PreBars=Bars(symbol_name,timeframe,start_time,stop_time);
   LastTime=t; LastTime0=t0;
   LastTimeFrame=timeframe;
   LastSymb=symbol_name;
   return(PreBars);
  }

Ho testato questa funzione su e giù. Sembra essere una copia completa di Bars.

Forse può essere fatto in un modo più elegante. Se avete un desiderio, siete i benvenuti. Se trovate degli errori, li correggeremo.

Quindi...

Allora l'analogo completo della funzione iBarsShift avrà la seguente forma:

int iBarShift(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false)
  {
   int Res=iBars(Symb,TimeFrame,time+1,UINT_MAX);
   if(exact) if((TimeFrame!=PERIOD_MN1 || time>TimeCurrent()) && Res==iBars(Symb,TimeFrame,time-PeriodSeconds(TimeFrame)+1,UINT_MAX)) return(-1);
   return(Res);
  }

E la variante senza ultimo parametro, che è usata nella stragrande maggioranza dei casi, avrà questa forma:

int iBarShift1(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false)
  {
   return(iBars(Symb,TimeFrame,time+1,UINT_MAX));
  }
// ИЛИ БОЛЕЕ СОКРАЩЕННЫЙ БЕЗ ФУНКЦИИ:

iBars(Symb,TimeFrame,time+1,UINT_MAX);
 

Indicatore che mostra le prestazioni della funzione iBars rispetto alle barre integrate e alla funzione iBarShift di @Alain Verleyen
Tempo di esecuzione della funzione in microsecondi.


File:
Motivazione: