Unisciti alla nostra fan page
- Visualizzazioni:
- 75
- Valutazioni:
- Pubblicato:
-
Hai bisogno di un robot o indicatore basato su questo codice? Ordinalo su Freelance Vai a Freelance
Alternativa alla libreria EAToMath https://www.mql5.com/it/code/61283
Registra i tick in modalità real ticks e li legge in modalità matematica richiamando la strategia ad ogni tick registrato.
Motivo della creazione: MQ tester, scrive file di dati di tick su ogni agente ogni volta che viene eseguito l'ottimizzatore. Ho 36 agenti che scrivono 10 GB ciascuno per uno degli strumenti e per il periodo di test, per un totale di 360 GB su un disco da 480 GB. Questo processo richiede circa 1 ora prima di ogni ottimizzazione. Le unità SSD tipiche hanno una durata di 500-1000 cicli di scrittura. Riscrivendo 360 GB ogni volta, la risorsa si esaurirà molto rapidamente. Questa libreria scrive solo un file e poi tutti i 36 agenti leggono i dati da questo file. Tutto questo è stato il motivo per cui abbiamo scritto la libreria: usiamo solo 1 file + risparmio di 1 ora per la scrittura dei dati a ciascun agente + accelerazione rispetto a MQ tester e anche a Virtual in modalità real ticks.
Il problema è stato studiato contemporaneamente a fxsaber (l'autore di EAToMath), ciascuno con la propria versione. Il mio codice mi è più chiaro, quindi lo uso.
Per le operazioni di trading si usa la libreria MT4Orders https://www.mql5.com/it/code/16006
Per il trading virtuale è necessario usare la libreria Virtual https://www.mql5.com/it/code/22577
Per visualizzare i risultati del trading si può usare MT4Orders QuickReport https://www.mql5.com/it/code/47816 o Report
Per comprimere i tick TickCompressorhttps://www.mql5.com/it/code/66201
Per rimuovere i tick non necessari si collega la libreria Control_Trade_Sessions https://www.mql5.com/it/code/48059, ad esempio se una sessione di quotazioni è più grande di una sessione di trading. Può anche essere eliminata se vengono utilizzati tutti i tick, cioè se le sessioni coincidono.
Differenze rispetto a EAToMath:
Pro:
- Il codice è più breve e più semplice, solo 5 librerie di plug-in. Se è necessario modificarlo, sarà più facile da capire.
- I dati sono compressi meglio grazie a un algoritmo diverso https://www.mql5.com/it/code/66201. Quando si salvano solo time_msc, ask e bid - fino all'86% dei tick sono salvati come numeri a 3 caratteri, cioè 3 byte. Dimensione media per tick = 3,266 Byte quando si salvano i dati dei tick di BTCUSDT per il 2023.
Quando si salvano i volumi la media è di 4,835 Byte. E quando si salvano i tick completi = 8,439 Byte. Di seguito è riportata la tabella con i risultati del test.
Inoltre, è possibile utilizzare l'archiviazione ZIP integrata. La dimensione del file si riduce di 2 volte. Un file di questo tipo richiede 245 Mb, mentre la somma delle dimensioni dei file in .tcs per 2023 richiede 364 Mb, ovvero la compressione è 1,5 volte migliore rispetto a MQ. Inoltre, la velocità di generazione dei tick in modalità matematica è ~2 volte superiore. Vedere la tabella sottostante. - Esistono più opzioni di salvataggio:

- Il file può essere salvato su un disco SSD o RAM creando un collegamento nel sistema. I file possono occupare molto spazio e l'unità RAM potrebbe non essere sufficiente, quindi è possibile scegliere di salvare sull'unità principale. Le velocità di lettura dell'SSD e della RAM sono più o meno le stesse; ho letto che l'SSD memorizza nella cache fino al 5% dell'intera capacità i dati richiesti più frequentemente.
L'SSD si usura un po' durante la lettura, poiché è necessario sovrascrivere le celle di memoria più spesso rispetto a quando si memorizza senza leggere. Non conosco i numeri esatti, ma ad esempio 1 sovrascrittura ogni 10 letture o ogni 1000 letture.... Ma questo è poco significativo rispetto all'usura del disco da parte del tester MQ.
Contro:
- La connessione di Virtual deve essere fatta da soli (istruzioni qui https://www.mql5.com/it/code/22577), EAToMath passerà la vostra strategia a Virtual stesso.
La velocità della variante BidAsk è paragonabile a quella di EAToMath. Le altre varianti sono più lente perché contengono più dati o hanno una compressione ZIP aggiuntiva.
Caratteristiche d'uso:
Non è possibile utilizzare le funzioni standard Symbol(), Digits( ) (=4), Point() (=0,0001) nella strategia, poiché produrranno valori predefiniti, non correlati al simbolo in esame. Al loro posto utilizzate _Symbol, _Digits, _Point , che vengono sovrascritti ai valori letti dal file. Sono state inoltre aggiunte le nuove costanti _TickSize e _TickValue con i valori del simbolo registrato, necessarie per il calcolo corretto di profitti, commissioni e swap nella valuta di deposito.
L'ordine di lavoro con il periodo di test selezionato durante il salvataggio dei tick:
- Selezionare la modalità di test per tick reali, lo strumento richiesto e le date di test. Impostare la variabile Task su Salva e selezionare l'opzione di salvataggio dei tick. Avviare il tester. Successivamente, verrà creato un file con i tick nella cartella specificata.
- Impostare la variabile Task su Run_Strategy. È possibile lasciare la modalità con tick reali da confrontare in seguito. Avviare il tester. I calcoli vengono effettuati con i tick reali, non dal file. Ottenere il risultato.

- Impostare la modalità di test su calcoli matematici. Avviare il tester. I calcoli vengono eseguiti con i tick del file. Confrontate il risultato con quello del punto 2. Dovrebbe essere lo stesso, ma diverse volte più veloce.
L'ordine di lavoro con l'archivio:
- Creare un archivio con tutti i tick dello storico: Selezionare la modalità di test con tick reali, lo strumento richiesto. Impostare le date dei test da <= primo tick a >= ultimo tick nella cronologia disponibile. Impostare la variabile Task su Save...To_Archive e selezionare l'opzione di salvataggio dei tick. Avviare il tester. Successivamente, nella cartella specificata verrà creata una cartella con il nome dello strumento in cui verranno salvati i file con le zecche per ogni anno. L'ultimo anno può essere sovrascritto se necessario; a tale scopo, selezionare solo l'anno corrente nelle date per evitare di sovrascrivere gli anni precedenti.
- Impostare la modalità di test su Maths. Impostate la variabile Task su Run_Strategy_Fron_Archive.
- Nel MathTicker: utilizzando il gruppo dell'archivio completo, impostare:
Instrument - al nome dello strumento (deve corrispondere al nome della cartella in cui sono memorizzati i suoi tick), alla data di inizio e di fine del test.

- Avviare il tester. I calcoli vengono eseguiti con le zecche dei file annuali richiesti. Poiché il lavoro non viene svolto con un solo file, ma con più file, è un po' più lento, perché richiede tempo per aprire e chiudere i file. Ad esempio, invece di 1,7 secondi ci vorranno 2,7 secondi per generare le zecche per 3 anni.
- La somma dei tick ottenuti dall'Expert Advisor qui sotto può differire di un piccolo valore di un primo tick. Quando si esegue il test su caratteri personalizzati in modalità real ticks, il primo tick produce solo Ask o Bid (se non sono stati salvati entrambi). Quando si esegue il test dall'archivio, entrambi vengono ripristinati dai tick precedenti.
Un esempio del più semplice Expert Advisor per valutare la velocità di lavoro:
#property tester_no_cache #include <Forester\MathTicker.mqh> // collegare il commercio in modalità matematica input int rep=0;//Ripetizioni per l'ottimizzazione sinput bool AddVolumes=true; void OnInit(){} void OnTick(){ static MqlTick Tick; if (SymbolInfoTick(_Symbol, Tick)){ #ifdef _MathTick_ if(MathTick.SaveTick(Tick)){ return; }//se salviamo i tick, allora usciamo e non facciamo trading. #endif Strategy(Tick); } } double Sum = 0;int tk=0; void Strategy(MqlTick& Tick){ // la strategia più semplice - utilizzata per confrontare la velocità di lettura con EAToMath Sum += Tick.bid+Tick.ask+(AddVolumes?Tick.volume_real:0.0); tk++; //se(tk<100){Stampa(Tick.time," ",Tick.ask," ",Tick.bid," ",Tick.last," ",Tick.volume_reale," ",Tick.flags);} } ulong StartTime = GetMicrosecondCount(); double OnTester(){ #ifdef _MathTick_ // viene eseguito con MathTick - conta i parametri dei simboli dal file con i tick. Per i test in modalità mat if(MathTick.SaveTicksEnd()){return 0;}// chiudere il file dopo la registrazione dei ticchettii e uscire if(MathTick.ReadSymbolVars()){ MathTick.Ticker();// in modalità mat alimenterà tutti i tick a Strategy(MqlTick &Tick). } #endif Print("ticks: ",tk); long work_time = (long)(GetMicrosecondCount() - StartTime)/1000; //ritornare(NormalizeDouble(work_time, 1)); // per ottenere la velocità del lavoro e la velocità del lavoro. return Sum;// per confrontare i risultati del calcolo }
È possibile modificare 1 impostazione:
//#define RestoreFlags // восстановить флаги тика из изменения ask, bid, volume - добавит 7% к времени генерации тиков 931 вместо 869 мс
Quando si generano i tick, vengono visualizzate le statistiche sulla compressione dei tick.
Di seguito sono riportate le stampe delle statistiche, dei volumi e del tempo di generazione dei tick.
-----------
MQtester senza volumi
pass 1 risultato restituito 4345830621850.311523 in 0:00:08.232
| Compressione C ZIP | |
|---|---|
| AskBid. Dimensione del file: 225 mb -------------------- Statistiche: -------------------- 3 byte: 86,6%, 62644158 zecche 4 byte: 0,6%, 412167 zecche 5 byte: 12,7%, 9185484 zecche 6 byte: 0,0%, 15274 zecche 11 byte: 0,1%, 46214 zecche 12 byte: 0,0%, 1 zecche 24 byte: 0. 0%, 1 zecche Totale: 626441580%, 1 ticks Totale: 72303299 ticks, 236108596 bytes. Media: 3.266 bytes per tick saldo finale 0.00 USD pass 10 risultato restituito 4345830621850.311523 in 0:00:01.485 nessuna normalizzazione pass 1 risultato restituito 4345830621850.311523 in 0:00:00.892 | AskBid_Zipped. Dimensione del file: 106 mb -------------------- Statistiche: -------------------- 3 byte: 86,6%, 62644158 zecche 4 byte: 0,6%, 412167 zecche 5 byte: 12,7%, 9185484 zecche 6 byte: 0. 0%, 15274 zecche 0%, 15274 tick 11 byte: 0,1%, 46214 tick 12 byte: 0,0%, 1 tick 24 byte: 0,0%, 1 tick Totale: 72303299 tick, 236108596 byte. Media: 3,266 byte per tick Dimensione non zippata:236108596. Dimensione zippata:111720863. Compressione ZIP: 47,3% pass 10 risultato restituito 4345830621850.311523 in 0:00:02.548 nessuna normalizzazione pass 2 risultato restituito 4345830621850.311523 in 0:00:01.890 |
MQ tester con volumi
pass 1 ha restituito il risultato 4345879117123.356445 in 0:00:07.962
| Compressione C ZIP | |
|---|---|
| AskBidVolume. Dimensione file: 333 mb -------------------- Statistiche: -------------------- 4 byte: 60,4%, 43684907 ticks 5 byte: 1,1%, 809676 ticks 6 byte: 33.5%, 24194111 ticks 7 byte: 4.9%, 3548666 ticks 8 byte: 0.0%, 7909 ticks 12 byte: 0.1%, 40022 ticks 13 byte: 0.0%, 17964 ticks 14 byte: 0.0%, 2 tick 19 byte: 0,0%, 41 tick 32 byte: 0,0%, 1 tick Totale: 72303299 tick, 349571243 byte. Media: 4,835 byte per tick passaggio 1 risultato restituito 4345879117123.356445 in 0:00:02.803 nessuna normalizzazione passaggio 4 risultato restituito 4345879117123.356445 in 0:00:01.659 | AskBidVolume_Zipped. Dimensione del file: 204 mb -------------------- Statistiche: -------------------- 4 byte: 60,4%, 43684907 zecche 5 byte: 1,1%, 809676 zecche 6 byte: 33,5%, 24194111 zecche 7 byte: 4,9%, 3548666 zecche 8 byte: 0. 0%, 7909 zecche 8 byte: 0.0%, 7909 zecche 12 byte: 0,1%, 40022 zecche 13 byte: 0,0%, 17964 zecche 14 byte: 0,0%, 2 zecche 19 byte: 0,0%, 41 zecche 32 byte: 0,0%, 1 zecca Totale: 72303299 zecche, 349571243 byte. Media: 4,835 byte per zecca Dimensione non zippata:349571243. Dimensione zippata:214897079. Compressione ZIP: 61,5% pass 2 ha restituito il risultato 4345879117123.356445 in 0:00:04.260 nessuna normalizzazione pass 2 ha restituito il risultato 4345879117123.356445 in 0:00:03.096 |
| Tutti. Dimensione file: 582 mb -------------------- Statistiche: -------------------- 8 byte: 61,5%, 44494583 zecche 9 byte: 33,5%, 24194111 zecche 10 byte: 4,9%, 3548666 zecche 11 byte: 0,0%, 7909 zecche 15 byte: 0,1%, 40022 zecche 16 byte: 0,0%, 17964 zecche 17 byte: 0. 0%, 2 zecche 17 byte: 0.0%, 2 tick 22 byte: 0,0%, 41 tick 44 byte: 0,0%, 1 tick Totale: 72303299 tick, 610166056 byte. Media: 8,439 byte per tick passaggio 2 risultato restituito 4345879117123.356445 in 0:00:03.768 nessuna normalizzazione passaggio 1 risultato restituito 4345879117123.356445 in 0:00:02.256 | All_Zipped. Dimensione file: 245 mb -------------------- Statistiche: -------------------- 8 byte: 61,5%, 44494583 zecche 9 byte: 33,5%, 24194111 zecche 10 byte: 4,9%, 3548666 zecche 11 byte: 0,0%, 7909 zecche 15 byte: 0. 1%, 40022 zecche 241941111%, 40022 zecche 16 byte: 0,0%, 17964 zecche 17 byte: 0,0%, 2 zecche 22 byte: 0,0%, 41 zecche 44 byte: 0,0%, 1 zecca Totale: 72303299 zecche, 610166056 byte. Media: 8,439 byte per zecca Dimensione non zippata:610166056. Dimensione zippata:257105213. Compressione ZIP: 42,1 % passaggio 1 risultato restituito 4345879117123.356445 in 0:00:05.388 nessuna normalizzazione passaggio 10 risultato restituito 4345879117123.356445 in 0:00:03.936 |
Le dimensioni dei file .tcs per lo stesso anno 2023:

Tutte le varianti con ZIP, anche il salvataggio dei tick completi, sono più compatte (da 3,5 a 1,5 volte).
Esempio di Expert Advisor per il trading virtuale e l'output dei report:
#property tester_no_cache #include <MT4Orders.mqh> // https://www.mql5.com/it/code/16006 #include <Forester\MathTicker.mqh> // collegare il commercio in modalità matematica #define ORDER_CURRENCY_DIGITS 2 // Impostazione delle cifre per il calcolo del profitto/commissione/scambio quando viene inserito nella cronologia di trading. #define VIRTUAL_LIMITS_TP_SLIPPAGE // I Limitatori e i TP vengono eseguiti al primo prezzo di accettazione - slippage positivo #define ORDER_COMMISSION -0 // Assegnazione commissione = Lotti * ORDER_COMMISSION. #include <fxsaber\Virtual\Virtual.mqh> // https://www.mql5.com/it/code/22577 #define REPORT_TESTER // Il tester registrerà automaticamente i rapporti #define REPORT_BROWSER // La creazione di un report con l'avvio del browser richiede l'autorizzazione della DLL. #define USE_highcharts //- È possibile scaricare e provare gratuitamente tutti i prodotti Highcharts. Una volta che il vostro progetto/prodotto è pronto per il lancio, acquistate una licenza commerciale. https://shop.highcharts.com/ #include <MT4Orders_QuickReport.mqh>// enum VirtTyp {MQ_Tester=0,Virtual1=1,Virtual2=2}; sinput VirtTyp tester1=1;//Tester 1 sinput VirtTyp tester2=2;//Tester 2 input int rep=0;//Ripetizioni per l'ottimizzazione bool isOptimization = false, isTester=false; double balInit=0; VIRTUAL_POINTER Virtual[10]; void OnInit(){ Virtual[0] = 0; // 0 - ambiente di trading reale Virtual[1] = VIRTUAL::Create(AccountBalance()); // Creazione della virtualizzazione 1. Virtual[2] = VIRTUAL::Create(AccountBalance()); // Creazione della virtualizzazione 2. //Virtual[tester1].Select(); isOptimization = MQLInfoInteger(MQL_OPTIMIZATION) ; isTester = MQLInfoInteger(MQL_TESTER); balInit=AccountBalance(); } void OnTick(){ //Virtual[0].Select(); VIRTUAL::NewTick();// inviare il tick alla macchina virtuale corrente static MqlTick Tick; if (SymbolInfoTick(_Symbol, Tick)){ #ifdef _MathTick_ if(MathTick.SaveTick(Tick)){ return; }//quando la scrittura dei tick uscirà dalla funzione, Strategy() non verrà richiamato #endif Strategy(Tick);//commercio } } void Strategy(MqlTick& Tick){ // la strategia più semplice - utilizzata per confrontare la velocità di lettura con EAToMath if(Tick.ask==0 || Tick.bid==0){return;}//MQ tester opera su un tick fallito, Virtual no. Divieto anche per MQ if(tester1>0){Virtual[tester1].Select(); VIRTUAL::NewTick(Tick);}//selezionare la virtualizzazione 1 e inviare un tick if(tester2>0){Virtual[tester2].Select(); VIRTUAL::NewTick(Tick);}//selezionare la virtualizzazione 2 e inviare un segno di spunta if(isNewHour(Tick.time)){//il primo ticchettio di ogni ora if(GetHour0(Tick.time) % 2==0){// acquistare a ore pari nel tester 1 Virtual[tester1].Select();//selezionare la virtualizzazione 1 OrderSend(_Symbol, OP_BUY, 1, Tick.ask, 0, Tick.ask - 100 * _Point, Tick.ask + 100 * _Point); }else{//vendere alle ore dispari nel tester 2 Virtual[tester2].Select();//selezionare la virtualizzazione 2 OrderSend(_Symbol, OP_SELL, 1, Tick.bid, 0, Tick.bid + 100 * _Point, Tick.bid - 100 * _Point); } } } double OnTester(){ #ifdef _MathTick_ // viene eseguito con MathTick: leggerà i parametri dei simboli dal file di tick. Per i test in modalità mat if(MathTick.SaveTicksEnd()){return 0;}//ritorno dopo il salvataggio dei tick if(MathTick.isMath && MathTick.ReadSymbolVars()){ if(tester1==0){Alert(" >>>>>>>>> Virtual tester 1=MQ. In math mode can be used only virtual tester. <<<<<<<<");return 0;} if(tester2==0){Alert(" >>>>>>>>> Virtual tester 1=MQ. In math mode can be used only virtual tester. <<<<<<<<");return 0;} SYMBOL_BASE sb; sb.Point=_Point; sb.Digits=_Digits; sb.Symbol=_Symbol; sb.SymbolID=0; sb.TickSize=_TickSize; sb.TickValue=_TickValue / _TickSize;//this.TickValue_ /= this.TickSize_; //come in SetSymbol() in \fxsaber\Virtual\Symbol_Base.mqh Virtual[1].Select(); VIRTUAL::SetSymbolBase(sb); Virtual[2].Select(); VIRTUAL::SetSymbolBase(sb); //minFreezeLevel = _minFreezeLevel*_Point; minStopLevel = _minStopLevel*_Point; Virtual[tester1].Select(); MathTick.Ticker();// in modalità mat alimenterà tutti i tick a Strategy(MqlTick &Tick). } #endif double ret_val=0; for (int v = 0 ; v <= VIRTUAL::Total(); v++){ if(Virtual[v].Select()){ if(v > 0){ VIRTUAL::Stop(); #ifdef _MathTick_ // viene eseguito con MathTick: leggerà i parametri dei simboli dal file di tick. Per i test in modalità mat if(MathTick.isMath){ VIRTUAL::CalcSwaps( MathTick.swapShort, MathTick.swapLong, 0, MathTick.swap3days ); }//scambio dal file tick else{VIRTUAL::CalcSwaps( _Symbol, 0 );} #else VIRTUAL::CalcSwaps( _Symbol, 0 );//calcolo degli swap - tutte le operazioni hanno uno swap, cioè se 2+ strumenti diversi, entrambi avranno lo swap del simbolo principale. #endif }// chiudiamo le operazioni incomplete al prezzo dell'ultimo tick, come nel tester if( !isOptimization){QuickReport("report_"+(string)v, true, v,false,true);} Print((string)v+" AccountBalance = ",AccountBalance(), " AccountEquity = ",AccountEquity()); double prib=AccountBalance()-balInit; ret_val += prib; // }} return ret_val;// per confrontare i risultati del calcolo } bool isNewHour (datetime &t){ static int next_h=-1; if(t < next_h){ return false; } else { next_h = (GetHour0(t)+1)*3600;return true;}} int GetHour0 (datetime &t){return((int)( t / 3600));}//ora corrente dal 1° gennaio 1971
Questo esempio crea 2 macchine virtuali con trading diverso. Nelle ore pari un tester acquista, l'altro vende nelle ore dispari.
Si tratta di un esempio complesso con 2 tester, che può essere semplificato se si ha bisogno di lavorare con un solo tester.
È inoltre possibile selezionare il tester MQ e confrontarlo con i risultati dei tester virtuali per controllare la correttezza dei calcoli. Solo la commissione può non coincidere, perché ci sono molte commissioni diverse e solo una variante è programmata nel tester virtuale.
Tradotto dal russo da MetaQuotes Ltd.
Codice originale https://www.mql5.com/ru/code/65821
EMA_ATR_VA
Adaptive Exponential Moving Average - ATR Volatilità corretta da Jose Silva in base all'indicatore ATR.
EMA_STD_VA
Media esponenziale adattiva in funzione del valore della deviazione standard.
SAR ADX Signal
Segnale SAR ADX con notifica mobile, riscritto dalla versione MT4 (la fonte non è più reperibile). Si tratta di un indicatore riverniciabile, si prega di fare attenzione quando lo si utilizza.
EMA_BB_VA
Media mobile esponenziale adattiva (dipendente dalle Bande di Bollinger) (BB Volatility Adjusted by Jose Silva).