Analogo a iBarShift - pagina 14

 
fxsaber:

Allora non capisco perché Bars pensa che 18:00:01 appartenga a M1-bar 18:01 e non a 18:00.

E la logica qui è la stessa del fatto che mia figlia è al suo secondo compleanno, anche se ha compiuto un anno solo una settimana fa. Oppure oggi è il 09.04.2018, anche se il 01 gennaio 00 era 2017 anni, 3 mesi e 8 giorni fa .

A proposito, TimeCurrent deve essere sostituito con SYMBOL_TIME.

Grazie! Davvero non sapevo di un tale identificatore.

 

A proposito, quando ho testato la correttezza dell'algoritmo iBars confrontandolo con il benchmark Bars in MQL4, provando diverse varianti a caso, ho trovato un bug in Bars:

Print(Bars(_Symbol,PERIOD_MN1,D'2005.08.31 00:00:00',D'2005.08.31 23:00:00')); // 1  должен быть 0, т.к. временной диапазон находиться внутри одного бара.
Print(Bars(_Symbol,PERIOD_MN1,D'2006.08.31 00:00:00',D'2006.08.31 23:00:00')); // 0

Non c'è un tale bug in MQL5.

Naturalmente non è significativo, poiché appare solo a TF = MN1, alle date 30 e 31, stop_time = 23 e solo prima del 2005 :)))

Ecco lo script per MQL4 che lo cattura, e iBars si è rivelato essere più di riferimento rispetto a Bars nativo.

File:
TestiBars.mq4  10 kb
 
fxsaber:


A proposito, TimeCurrent dovrebbe essere sostituito da SYMBOL_TIME.

No, non è necessario.
Non aggiungerà correttezza, perché TimeCurrent() è universale per tutti i simboli, perché restituisce l'ultimo tempo di arrivo della quotazione per tutti i simboli, non quello attuale.

Allo stesso tempo, SymbolInfoInteger(symbol_name,SYMBOL_TIME) è molto lento rispetto a TimeCurrent(), e questo tempo è necessario ad ogni chiamata di iBars

 

Per coloro che sono interessati.

Versione modificata di iBars (simile alle Bars integrate, solo senza glitch e più veloce).

Corretti alcuni bug.

Se avete notato che il vostro codice MQL5 si blocca per 10-20 secondi all'improvviso e ha la funzione Bars, che può restituire 0, allora vi consiglio vivamente di sostituirlo con questa versione.
Funzionerà più velocemente e senza intoppi.

int iBars(string symbol_name,ENUM_TIMEFRAMES  timeframe,datetime start_time,datetime stop_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(LastTimeFrame!=timeframe) if(timeframe==PERIOD_MN1) PerSec=2419200; else PerSec=::PeriodSeconds(timeframe);
   if(timeframe<PERIOD_W1) TimeCur-=TimeCur%PerSec;
   if(start_time>TimeCur) {LastSymb=NULL; return(0);}
   if(LastTimeFrame!=timeframe || LastSymb!=symbol_name || ((TimeCur-LastBAR)>0 && 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 tS,tF=0;
   bool check=true;
   if(timeframe<PERIOD_W1) tS=start_time-(start_time-1)%PerSec-1;
   else if(timeframe==PERIOD_W1) tS=start_time-(start_time-259201)%PerSec-1;
   else
     {
      PerSec=2678400;
      MqlDateTime dt;
      TimeToStruct(start_time-1,dt);
      tS=dt.year*12+dt.mon;
     }
   if(stop_time<=LastBAR)
     {
      if(timeframe<PERIOD_W1) tF=stop_time-(stop_time)%PerSec;
      else if(timeframe==PERIOD_W1) tF=stop_time-(stop_time-259200)%PerSec;
      else
        {
         MqlDateTime dt0;
         TimeToStruct(stop_time,dt0);
         tF=dt0.year*12+dt0.mon;
        }
      if(tS==tF) {PreBars=0; check=false;}
     }
   if((LastTimeFrame!=timeframe || LastSymb!=symbol_name || tS!=LastTime || tF!=LastTime0) && check)
      PreBars=Bars(symbol_name,timeframe,start_time,stop_time);
   LastTime=tS; LastTime0=(datetime)tF;
   LastTimeFrame=timeframe;
   LastSymb=symbol_name;
   return(PreBars);
  }
 
Nikolai Semko:

Versione modificata di iBars(simile alle Bars integrate, solo senza glitch e più veloce).

Corretti alcuni bug.

La funzione integrata Bars() è sovraccaricata:

1. int Bars(const string symbol_name,ENUM_TIMEFRAMES timeframe)
2. int Bars(const string symbol_name,ENUM_TIMEFRAMES timeframe,datetime start_time,datetime stop_time)

Avete solo un modulo di chiamata.

 
Artyom Trishkin:

Il built-in Bars() è sovraccaricato:

Avete solo un modulo da chiamare.

se hai bisogno di un modulo breve, va bene usare quello integrato. Non c'è quasi nessun intoppo.

 
Nikolai Semko:

No, non è necessario.
Non aggiungerà correttezza, perché TimeCurrent() è universale per tutti i simboli, perché restituisce l'ultimo tempo di arrivo della quotazione per tutti i simboli, non quello attuale.

SymbolInfoInteger(symbol_name,SYMBOL_TIME) è molto lento rispetto a TimeCurrent(), e questo tempo è necessario ogni volta che iBars viene chiamato

I cotypes possono andare per tutti i personaggi tranne quello di interesse.

Ok, ho guardato la nuova fonte. Ha visto che le modifiche, che sono state discusse, non sono state fatte. Sono fuori.

 
Perché gli sviluppatori non lo fanno da soli?
 
Sarebbe molto più comodo per gli utenti chiamare una funzione e ottenere un array sincronizzato (allineato al tempo) di righe su diversi strumenti
 
A proposito, riguardo alla funzione Bars(). Questa può essere la causa del clincher.