Analogo a iBarShift - pagina 3

 
Vasiliy Pushkaryov:

Ecco il copione.

Si blocca e basta. Rimuovendolo forzatamente dal grafico si ottiene il risultato.

Così l'ho provato, ecco perché ve l'ho raccomandato. Ma visto che l'hai usato e ti sta bene, non cambierò idea.

Mi dispiace, Vassili. Ti ho frainteso. Ho letto il tuo post velocemente mentre guidavo. Pensavo si trattasse dell'ultimo parametro, dove ho32000000000, si scopre che intendevi il parametro t. Sì, infatti - è l'unico caso in cui il risultato è diverso dall'originale MQL4 iBarShift(). Tuttavia è molto strano cercare di usare questa funzione per ottenere il numero di barre (o indice di barra) dal punto temporale corrente, cioèTimeCurrent(), quando è chiaro che la barra è zero. In generale, è strano che la funzioneBars() aTimeCurrent() produca 0 e non 1. Formalmente è un bug degli sviluppatori, anche se dipende. Ma qualcosa non può bloccarsi a causa dell'uso della funzione standard Bars(), soprattutto perché lo script ha controllatoPrint(), cioè tutto è OK.
Capisci, Vasily, non voglio sminuire altre implementazioni di iBarShift analogico, solo che personalmente uso esattamente questa costruzione(Bars(NULL,0,t,32000000000)-1;), perché è la più veloce. E questa costruzione non è usata come sostituto di iBarShift, ma semplicemente come funzione di trovare un indice di una barra in un momento specificato, e non capisco cosa intendi per universalità. E non credo che sia ragionevole usare tutte le funzioni di cui sopra a causa del maggior costo in termini di tempo. (Ricordate le pubblicità della polvere Dosya). Il fatto è che l'uso di questa funzione avviene molto spesso in grandi cicli, il che aumenta significativamente il tempo di esecuzione del programma, e io sono terribilmente avido di runtime. Ho fatto esperimenti con il calcolo runtime di varie funzioni (e non solo io, vedi post precedente) e questa opzione è sicuramente la più veloce. Anche questa variante, che è posizionata come la più veloce, è la stessa, ma il costrutto(Bars(NULL,0,t,32000000000)-1;) è ancora più semplice. Naturalmente, dipende da ognuno cosa usare.

In ogni caso, grazie per la sua osservazione sostanziale.

 
Nikolai Semko:

Ma è molto strano cercare di usare questa funzione per ricevere il numero di barre (o l'indice di una barra) dal momento attuale, cioèTimeCurrent(), quando è già chiaro che la barra è zero. È strano che la funzioneBars() dia 0 invece di 1 aTimeCurrent().

TimeCurrent() era solo un caso speciale che avevo a portata di mano.

Ora leggo più attentamente questa nota alla funzione Bars():

"Quando si richiede il numero di barre in un dato intervallo di date , vengono prese in considerazione solo le barre il cui orario di apertura cade in quell'intervallo. Per esempio, se il giorno corrente della settimana è sabato, quando si richiede il numero di barre settimanali con start_time=lastTuesday e stop_time=lastFriday, la funzione restituisce 0 perché il tempo di apertura del timeframe settimanale cade sempre di domenica e nessuna barra settimanale cade nell'intervallo specificato".

Poiché TimeCurrent() è quasi sempre più tardi dell'orario di apertura della barra corrente, la funzione Bars() restituisce 0. Quindi, se passiamo l'orario corrispondente alle 02:05 del TF orario come parametro start_time , e vogliamo che la barra iniziata alle 2 sia valida, allora dobbiamo ottenere l'orario di apertura della barra (02:00:00) attraverso CopyTime() . Altrimenti, la funzione Bars() ignorerà questa barra.

Cioè, se l'ora è 3:30, capisco che nel TF orario, l'ora 2:05 si riferisce alla barra con indice 1. Nessuna delle funzioni della 2a pagina restituirà questo indice. Con questa correzione la funzione di Renat Akhtyamov ha restituito quello che mi aspettavo.

int iBarShift2(string symbol, ENUM_TIMEFRAMES timeframe, datetime time)
{
  datetime tm0[1], tm1[1];      
  CopyTime(symbol, timeframe, 0, 1, tm0);             // время открытия 0-го бара
  CopyTime(symbol, timeframe, time, 1, tm1);          // время открытия бара, в который попадает указанный time

  return Bars(symbol, timeframe, tm0[0], tm1[0])-1;
}

Allego uno script, con 4 opzioni per le funzioni di ricerca degli indici, che ho usato come test.

File:
TestIBS.mq5  5 kb
 
Vasiliy Pushkaryov:

IlTimeCurrent() è solo un caso speciale incontrato.

Ora leggo più attentamente questa nota alla funzione Bars():

"Quando si richiede il numero di barre in un dato intervallo di date , vengono prese in considerazione solo le barre il cui orario di apertura cade in quell'intervallo. Per esempio, se il giorno corrente della settimana è sabato, quando si richiede il numero di barre settimanali con start_time=lastTuesday e stop_time=lastFriday, la funzione restituisce 0 perché il tempo di apertura del timeframe settimanale cade sempre di domenica e nessuna barra settimanale cade nell'intervallo specificato".

Poiché TimeCurrent() è quasi sempre più tardi dell'orario di apertura della barra corrente, la funzione Bars() restituisce 0. Quindi, se passiamo il tempo corrispondente alle 02:05 sul timeframe orario come parametro start_time , e vogliamo che la barra iniziata alle 2 sia valida, allora dobbiamo ottenere l'orario di apertura della barra (02:00:00) attraverso CopyTime() . Altrimenti, la funzione Bars() ignorerà questa barra.

Cioè, se l'ora è ora 3:30, capisco che nel timeframe orario, 2:05 si riferisce alla barra con indice 1. Questo indice non sarà restituito da nessuna funzione della 2a pagina. Con questa correzione la funzione di Renat Akhtyamov ha restituito quello che mi aspettavo.

Allego uno script, con 4 opzioni per le funzioni di ricerca degli indici, che ho usato come test.

Naturalmente ho bisogno di passare l'esame di stato. Ho dimenticato di specificare.
 
Non capisco perché questa funzione non esiste ancora in SB
 
transcendreamer:
Non capisco perché questa funzione non è ancora disponibile nel SB

Provato tutte le varianti, la più corretta è quella di Alain Verleyen.
(testato su un indicatore complesso con molti oggetti)
 
Taras Slobodyanik:

Provato tutte le varianti, la più corretta è quella di Alain Verleyen.
(testato su un indicatore complesso con molti oggetti)
https://www.mql5.com/ru/code/18305
Высокопроизводительная библиотека iTimeSeries
Высокопроизводительная библиотека iTimeSeries
  • voti: 17
  • 2017.05.25
  • nicholishen
  • www.mql5.com
Эта библиотека предоставляет молниеносный доступ к таймсериям для реализации привычных методов MQL4 (например, iBarShift) в чувствительных к задержкам приложениях на MQL5.
 

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

Era:

int iBarShift3( const string Symb, const ENUM_TIMEFRAMES TimeFrame, datetime time, const bool Exact = false )
{
  static int Res = -1;
  static string LastSymb = NULL;
  static ENUM_TIMEFRAMES LastTimeFrame = 0;
  static datetime LastTime = 0;
  static bool LastExact = false;

  time -= time % ::PeriodSeconds(TimeFrame);

  if ((time != LastTime) || (Symb != LastSymb) || (TimeFrame != LastTimeFrame) || (Exact != LastExact))
  {
    datetime LastBar;

     if (::SeriesInfoInteger(Symb, TimeFrame, ::SERIES_LASTBAR_DATE, LastBar))
     {
        if (time > LastBar)
          Res = 0;
        else
        {
          const int Shift = ::Bars(Symb, TimeFrame, time, LastBar);

          if (Shift > 0)
            Res = Shift - 1;
        }
      }

    LastTime = time;
    LastSymb = Symb;
    LastTimeFrame = TimeFrame;
    LastExact = Exact;
  }

  return(Res);
}

Diventato:

int iBarShift3(const string Symb,const ENUM_TIMEFRAMES TimeFrame,datetime time,const bool Exact=false)
  {
   static int Res=-1;
   static string LastSymb=NULL;
   static ENUM_TIMEFRAMES LastTimeFrame=0;
   static datetime LastTime=0;
   static bool LastExact=false;
   static int PerSec=::PeriodSeconds(LastTimeFrame);
   
   if (LastTimeFrame!=TimeFrame) PerSec=::PeriodSeconds(TimeFrame);
   time-=time%PerSec;

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

      LastTime = time;
      LastSymb = Symb;
      LastTimeFrame=TimeFrame;
      LastExact=Exact;
     }

   return(Res);
  }

Il guadagno di velocità è di circa una volta e mezza.

E sembra essere l'opzione più veloce. Vero, l'ultimo parametroExact è falso e può essere rimosso. Ma secondo me non è necessario. Personalmente non ho mai incontrato compiti in cui avevamo bisogno diExact= true.

Ma se qualcuno ne ha bisogno, non può fare a meno di CopyTime ed è meglio usare lavariante di @Alain Verleyen.

SZY: ho bypassato le chiamate superflue alla funzionePeriodSeconds, se TF non è cambiato dall'ultima chiamata. Il guadagno è debole, però - qualche punto percentuale, ma comunque.

E un'altra osservazione: la costruzione

time-=time%PerSec;
non funzionerà correttamente con PERIOD_W1 e PERIOD_MN1 perché inizia il 1° gennaio 1970, che non è un lunedì, ma un giovedì. E ogni mese ha un numero diverso di secondi.
 
Nikolai Semko:

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

Era:

Diventato:

Il guadagno di velocità è di circa una volta e mezza.

E sembra essere l'opzione più veloce. Vero, l'ultimo parametroExact è falso. Ma se me lo chiedete, non ne avete bisogno.

O mi sbaglio?

SZY: ho anche bypassato le chiamate superflue alla funzionePeriodSeconds, se TF non è cambiato dall'ultima chiamata. Il guadagno è davvero minimo - qualche punto percentuale, ma comunque.

Non capisco quanto sia intelligente questo codice, per questo voglio farvi una domanda. Il codice funzionerà se il grafico non è a giornata intera?

 
Aleksey Vyazmikin:

Quanto sia contorto il codice, non mi è chiaro, quindi chiederò. Il codice funzionerà se il grafico non è a giornata intera?

Non capisco l'essenza della domanda. Mettilo in un modo diverso.

Il grafico non è sempre un giorno completo, tranne il primo secondo del giorno.

Di che periodo stiamo parlando? Un giorno?

E cosa le impedisce di controllare?

Il codice non è mio, l'ho solo semplificato e reso più veloce.

Nel mio messaggio precedente ho fatto un'aggiunta suPERIOD_W1 e PERIOD_MN1.

Tutti gli algoritmi precedenti, compreso quello di @Alain Verleyen, hanno situazioni anomale.

È possibile creare un analogo completo di iBarShift MQL4, ma il codice sarà piuttosto ingombrante, e non vedo alcun senso in esso.

 
Nikolai Semko:

Non capisco il senso della domanda. Mettilo in un modo diverso.

Il grafico non è sempre un giorno completo, tranne il primo secondo del giorno.

Di quale TF stiamo parlando? Un giorno?

E cosa le impedisce di controllare?

Il codice non è mio, l'ho solo semplificato e reso più veloce.

Nel mio messaggio precedente ho fatto un'aggiunta suPERIOD_W1 e PERIOD_MN1.

Tutti gli algoritmi precedenti, compreso quello di @Alain Verleyen, hanno situazioni anomale.

È possibile creare un analogo completo di iBarShift MQL4, ma il codice sarà molto ingombrante, e non ne vedo il motivo.

Non l'ho testato perché uno deve sapere con certezza se il codice funzionerà per una certa situazione, altrimenti non è corretto incolpare qualcun altro se ha 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?

Motivazione: