Se ha smesso di funzionare, è bene sapere se è la cosa giusta da fare.
Se si creano puntatori invece di oggetti, funzionerà anche la vecchia versione.
Ottima osservazione e grazie per il suggerimento!
Sì, in effetti la situazione è perfettamente risolta con un puntatore:
class A;
class B
{
public: A * a;
public: int Val;
};
class A
{
public: B * b;
public: int Test() {return b.Val + 1;}
};
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnStart()
{
B b;
A a;
b.a = GetPointer(a);
b.a.b = GetPointer(b);
b.Val = 1;
Print(b.a.Test());
}
Gli appassionati di algoritmi veloci. Quelli che lottano per i nanosecondi :)
Compito: trovare l'ora di apertura della barra in base all'ora e al TF indicati, quando si sa che la barra esiste in questo momento. Ad esempio, in base all'orario di apertura e chiusura delle posizioni.
La maggior parte dei programmatori utilizzerà una combinazione di iTime e iBarShift. Questa sarà l'implementazione più lenta, soprattutto perché richiede una cronologia aggiornata dei dati caricati o degli array combinati. Inoltre, questo approccio può generare errori se manca la cronologia richiesta.
I programmatori più avanzati risolveranno questo problema con la struttura MqlDateTime e la funzione TimeToStruct(). Questa non è una cattiva soluzione ed è abbastanza veloce.
Ma esiste una terza soluzione, che è più produttiva della precedente di molte volte:
//+------------------------------------------------------------------+// получает время открытия виртуального бара по входному времени и Таймфрейму, вне зависимости от того, существует реальный бар или нет.// корректно считает только до 28.02.2100 !!!!// не является заменой iBarShift!!! Не зависит от истории баров. datetime getStartTimeOfBarFast(ENUM_TIMEFRAMES tf, datetime t) {
if (tf==0) tf=_Period;
int ts=0;
if (tf<PERIOD_MN1) {
ushort i_tf= ushort(tf);
uchar _i =uchar(i_tf>>14);
int n = i_tf & 0x0FFF;
ts = (_i==0)?n*60:(_i==1)?n*60*60:60*60*24*7;
}
if (tf<PERIOD_W1) return t-t%ts;
if (tf==PERIOD_W1) return t-(t+4*24*60*60)%ts;
else { // Period MN1staticint dm[12] = {0,31,61,92,122,153,184, 214, 245, 275, 306, 337};
staticint last_days = 0;
staticdatetime last_result = 0;
int days = int(t/(24*60*60));
if (last_days!=days) {
last_days = days;
int d1 = (days+306+365)%1461;
int y = d1/365;
datetime t1 = t - t%(24*60*60) - d1*24*60*60;
int m = 0;
if (d1==1460) {
m=11;
y--;
};
int d = d1-y*365+1;
if (d!=31) if (d==276) m = 9;
else m = int (d/30.68);
if (m<0 || m>11) return -1;
last_result = t1+y*365*24*60*60+dm[m]*24*60*60;
}
return last_result;
}
}
//+------------------------------------------------------------------+
La difficoltà principale di questo algoritmo è il calcolo dell'ora di inizio del mese (evidenziata in verde) Non cercate di capire il funzionamento dell'algoritmo. C'è una magia, che è il risultato del passaggio dal semplice al complesso. Il percorso inverso, da complesso a semplice, sarà molto più difficile da percorrere.
Il guadagno di prestazioni è dato anche dall'algoritmo che ricava i secondi in una barra dal TF invece che dalla funzione standard PeriodSeconds() - evidenziato in giallo.
Allego uno script di test che calcola e confronta le prestazioni di tutti e tre i metodi:
2023.11.1412:15:29.145 timeToStartMonth (EURUSD,M1) =====LOOP=10000========STEPS=100000 seconds======PERIOD_MN1========
2023.11.1412:15:29.146 timeToStartMonth (EURUSD,M1) контрольная сумма - 11987239507200, время выполнения 1 иттерации = 21.20 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:15:29.146 timeToStartMonth (EURUSD,M1) контрольная сумма - 11987239507200, время выполнения 1 иттерации = 6.10 наносекунд - Быстрый расчет
2023.11.1412:15:29.147 timeToStartMonth (EURUSD,M1) контрольная сумма - 11987239507200, время выполнения 1 иттерации = 142.00 наносекунд - Расчет через iBarShift2023.11.1412:15:29.147 timeToStartMonth (EURUSD,M1) ========================================================================
2023.11.1412:15:34.226 timeToStartMonth (EURUSD,M1) =====LOOP=10000========STEPS=100000 seconds======PERIOD_MN1========
2023.11.1412:15:34.227 timeToStartMonth (EURUSD,M1) контрольная сумма - 11987239507200, время выполнения 1 иттерации = 19.80 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:15:34.227 timeToStartMonth (EURUSD,M1) контрольная сумма - 11987239507200, время выполнения 1 иттерации = 6.70 наносекунд - Быстрый расчет
2023.11.1412:15:34.228 timeToStartMonth (EURUSD,M1) контрольная сумма - 11987239507200, время выполнения 1 иттерации = 127.50 наносекунд - Расчет через iBarShift2023.11.1412:15:34.228 timeToStartMonth (EURUSD,M1) ========================================================================
2023.11.1412:15:39.856 timeToStartMonth (EURUSD,M1) =====LOOP=10000========STEPS=100000 seconds======PERIOD_W1========
2023.11.1412:15:39.856 timeToStartMonth (EURUSD,M1) контрольная сумма - 11997367833600, время выполнения 1 иттерации = 2.80 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:15:39.856 timeToStartMonth (EURUSD,M1) контрольная сумма - 11997367833600, время выполнения 1 иттерации = 1.50 наносекунд - Быстрый расчет
2023.11.1412:15:39.857 timeToStartMonth (EURUSD,M1) контрольная сумма - 11997367833600, время выполнения 1 иттерации = 98.30 наносекунд - Расчет через iBarShift2023.11.1412:15:39.857 timeToStartMonth (EURUSD,M1) ========================================================================
2023.11.1412:15:52.770 timeToStartMonth (EURUSD,M1) =====LOOP=10000========STEPS=100000 seconds======PERIOD_H2========
2023.11.1412:15:52.771 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000355999200, время выполнения 1 иттерации = 4.10 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:15:52.771 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000355999200, время выполнения 1 иттерации = 1.50 наносекунд - Быстрый расчет
2023.11.1412:15:54.255 timeToStartMonth (EURUSD,M1) контрольная сумма - 0, время выполнения 1 иттерации = 148466.50 наносекунд - Расчет через iBarShift2023.11.1412:15:54.255 timeToStartMonth (EURUSD,M1) ========================================================================
2023.11.1412:15:58.759 timeToStartMonth (EURUSD,M1) =====LOOP=10000========STEPS=100000 seconds======PERIOD_M4========
2023.11.1412:15:58.759 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000391999920, время выполнения 1 иттерации = 3.60 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:15:58.759 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000391999920, время выполнения 1 иттерации = 1.50 наносекунд - Быстрый расчет
2023.11.1412:15:59.864 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000017286960, время выполнения 1 иттерации = 110555.70 наносекунд - Расчет через iBarShift2023.11.1412:15:59.864 timeToStartMonth (EURUSD,M1) ========================================================================
Il checksum con iBarShift non coincide , perché iBarShift lavora con barre reali. Il checksum coinciderà solo sui timeframe MN1 e W1, perché non ci sono buchi nella storia di tali barre. Le prestazioni saranno più elevate se si utilizza un piccolo passo temporale nel ciclo (meno di un giorno) quando l'algoritmo inizia a lavorare per salvare i calcoli precedenti:
2023.11.1412:14:10.714 timeToStartMonth (EURUSD,M1) =====LOOP=1000000========STEPS=1000 seconds======PERIOD_MN1========
2023.11.1412:14:10.722 timeToStartMonth (EURUSD,M1) контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 8.03 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:14:10.723 timeToStartMonth (EURUSD,M1) контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 1.18 наносекунд - Быстрый расчет
2023.11.1412:14:10.860 timeToStartMonth (EURUSD,M1) контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 136.80 наносекунд - Расчет через iBarShift2023.11.1412:14:10.860 timeToStartMonth (EURUSD,M1) ========================================================================
2023.11.1412:14:17.502 timeToStartMonth (EURUSD,M1) =====LOOP=1000000========STEPS=1000 seconds======PERIOD_MN1========
2023.11.1412:14:17.510 timeToStartMonth (EURUSD,M1) контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 7.70 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:14:17.511 timeToStartMonth (EURUSD,M1) контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 1.18 наносекунд - Быстрый расчет
2023.11.1412:14:17.648 timeToStartMonth (EURUSD,M1) контрольная сумма - 1198674131961600, время выполнения 1 иттерации = 137.54 наносекунд - Расчет через iBarShift2023.11.1412:14:17.648 timeToStartMonth (EURUSD,M1) ========================================================================
I valori eccessivi per l'algoritmo tramite iBarShift (evidenziati in blu) sono causati dall'attuale mancanza dello storico necessario o dei TF calcolati dall'array, che ne avvia il caricamento. Dopo il caricamento il risultato sarà il seguente:
2023.11.1412:47:06.158 timeToStartMonth (EURUSD,M1) =====LOOP=10000========STEPS=100000 seconds======PERIOD_H2========
2023.11.1412:47:06.158 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000379996800, время выполнения 1 иттерации = 4.60 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:47:06.158 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000379996800, время выполнения 1 иттерации = 2.60 наносекунд - Быстрый расчет
2023.11.1412:47:06.159 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000009103200, время выполнения 1 иттерации = 129.10 наносекунд - Расчет через iBarShift2023.11.1412:47:06.159 timeToStartMonth (EURUSD,M1) ========================================================================
2023.11.1412:47:13.899 timeToStartMonth (EURUSD,M1) =====LOOP=10000========STEPS=100000 seconds======PERIOD_M4========
2023.11.1412:47:13.899 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000411199920, время выполнения 1 иттерации = 2.80 наносекунд - Расчет через структуру MqlDateTime2023.11.1412:47:13.899 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000411199920, время выполнения 1 иттерации = 1.40 наносекунд - Быстрый расчет
2023.11.1412:47:13.903 timeToStartMonth (EURUSD,M1) контрольная сумма - 12000038634480, время выполнения 1 иттерации = 381.30 наносекунд - Расчет через iBarShift2023.11.1412:47:13.903 timeToStartMonth (EURUSD,M1) ========================================================================
S.F. Questo mi ha divertito: "conta correttamente solo fino al 28.02.2100 !!!!".
Cosa facciamo dopo?
haha. Dubito che questo algoritmo sarà richiesto per 75 anni. I computer quantistici probabilmente governeranno già il mondo, con una programmazione completamente diversa. Ad essere onesti, è stato pigro tenere conto del calendario gregoriano. Il 2000 era una data importante, il 2100 non lo è più.
haha. Dubito che questo algoritmo sarà richiesto per 75 anni. I computer quantistici probabilmente governeranno già il mondo, con una programmazione completamente diversa. ad essere onesti, è stato pigro tenere completamente conto del calendario gregoriano. Il 2000 era una posta in gioco alta, il 2100 non lo è più.
Per MN si può usare un array precalcolato, non c'è quasi nulla lì dentro
Ln2(12 mesi * cento anni)... 11 if` e confronti nella ricerca binaria, ma senza altri calcoli.
È possibile utilizzare un array precalcolato per MN, i dati sono praticamente inesistenti.
Ln2(12 mesi * cento anni)... 11 if` e confronti nella ricerca binaria, ma senza altri calcoli.
Ah, ho letto male all'inizio. No, ti sbagli. L'aumento delle prestazioni non funzionerà. Si rimarrà comunque bloccati nei calcoli. E l'accesso agli elementi dell'array rallenta molto l'algoritmo.
Consenti l'uso dei cookie per accedere al sito MQL5.com.
Abilita le impostazioni necessarie nel browser, altrimenti non sarà possibile accedere.
Hai effettuato l'accesso. L'autenticazione a due fattori è stata disattivata. Configurala di nuovo e scansiona un nuovo codice QR, oppure continua con l'autenticazione a due fattori disattivata.
Se smette di funzionare, sarebbe bene sapere se è corretto.
Se si creano dei puntatori al posto degli oggetti, funzionerà anche la vecchia versione.
Se ha smesso di funzionare, è bene sapere se è la cosa giusta da fare.
Se si creano puntatori invece di oggetti, funzionerà anche la vecchia versione.
Ottima osservazione e grazie per il suggerimento!
Sì, in effetti la situazione è perfettamente risolta con un puntatore:
Gli appassionati di algoritmi veloci. Quelli che lottano per i nanosecondi :)
Compito: trovare l'ora di apertura della barra in base all'ora e al TF indicati, quando si sa che la barra esiste in questo momento. Ad esempio, in base all'orario di apertura e chiusura delle posizioni.
La maggior parte dei programmatori utilizzerà una combinazione di iTime e iBarShift. Questa sarà l'implementazione più lenta, soprattutto perché richiede una cronologia aggiornata dei dati caricati o degli array combinati. Inoltre, questo approccio può generare errori se manca la cronologia richiesta.
I programmatori più avanzati risolveranno questo problema con la struttura MqlDateTime e la funzione TimeToStruct(). Questa non è una cattiva soluzione ed è abbastanza veloce.
Ma esiste una terza soluzione, che è più produttiva della precedente di molte volte:
La difficoltà principale di questo algoritmo è il calcolo dell'ora di inizio del mese (evidenziata in verde) Non cercate di capire il funzionamento dell'algoritmo. C'è una magia, che è il risultato del passaggio dal semplice al complesso. Il percorso inverso, da complesso a semplice, sarà molto più difficile da percorrere.
Il guadagno di prestazioni è dato anche dall'algoritmo che ricava i secondi in una barra dal TF invece che dalla funzione standard PeriodSeconds() - evidenziato in giallo.
Allego uno script di test che calcola e confronta le prestazioni di tutti e tre i metodi:
Il checksum con iBarShift non coincide , perché iBarShift lavora con barre reali. Il checksum coinciderà solo sui timeframe MN1 e W1, perché non ci sono buchi nella storia di tali barre.
Le prestazioni saranno più elevate se si utilizza un piccolo passo temporale nel ciclo (meno di un giorno) quando l'algoritmo inizia a lavorare per salvare i calcoli precedenti:
I valori eccessivi per l'algoritmo tramite iBarShift (evidenziati in blu) sono causati dall'attuale mancanza dello storico necessario o dei TF calcolati dall'array, che ne avvia il caricamento.
Dopo il caricamento il risultato sarà il seguente:
Gli appassionati di algoritmi veloci. Quelli che lottano per i nanosecondi :)
...😮😲😳🥴🤪
...
ah...
mmm....
oooh....
gkghm... Non pensavo che la mia semplice domanda sarebbe uscita in questo modo.
Proprio così.
😮😲😳🥴🤪
...
ah...
mmm.
ohhhh....
ahem. Non pensavo che la mia semplice domanda sarebbe uscita in questo modo.
Oh.
Sì, Artem, mi hai ingannato per un po'.
Era un interesse sportivo.
Spero che possa essere utile a qualcuno, me compreso. :))
Sì, Artem, mi hai imbrogliato per un po'.
Ho lavorato sull'interesse sportivo.
Spero che sia utile a qualcuno, e a me tra gli altri. :))
Certo che lo sarà. Ottimo. Grazie ancora!
S.F. Questo mi ha divertito: "conta correttamente solo fino al 28.02.2100 !!!!".
Cosa facciamo dopo?
Certo che tornerà utile. Ottimo. Grazie ancora!
S.F. Questo mi ha divertito: "conta correttamente solo fino al 28.02.2100 !!!!".
Cosa facciamo dopo?
haha.
Dubito che questo algoritmo sarà richiesto per 75 anni. I computer quantistici probabilmente governeranno già il mondo, con una programmazione completamente diversa.
Ad essere onesti, è stato pigro tenere conto del calendario gregoriano. Il 2000 era una data importante, il 2100 non lo è più.
haha.
Dubito che questo algoritmo sarà richiesto per 75 anni. I computer quantistici probabilmente governeranno già il mondo, con una programmazione completamente diversa.
ad essere onesti, è stato pigro tenere completamente conto del calendario gregoriano. Il 2000 era una posta in gioco alta, il 2100 non lo è più.
Per MN si può usare un array precalcolato, non c'è quasi nulla lì dentro
Ln2(12 mesi * cento anni)... 11 if` e confronti nella ricerca binaria, ma senza altri calcoli.
È possibile utilizzare un array precalcolato per MN, non ci sono praticamente dati.
Ln2(12 mesi * cento anni)... 11 if` e confronti nella ricerca binaria, ma senza altri calcoli.
È possibile utilizzare un array precalcolato per MN, i dati sono praticamente inesistenti.
Ln2(12 mesi * cento anni)... 11 if` e confronti nella ricerca binaria, ma senza altri calcoli.
Ah, ho letto male all'inizio.
No, ti sbagli. L'aumento delle prestazioni non funzionerà. Si rimarrà comunque bloccati nei calcoli. E l'accesso agli elementi dell'array rallenta molto l'algoritmo.