MathTicker - Quote Generator in Math Mode - MetaTrader 5 Library - MT4/MT5 Resources




Alternative to EAToMath library https://www.mql5.com/en/code/61283
Record quotes in real quote mode and read them in math mode and call your strategy with each recorded quote.
Reason for creation: MQ tester that writes a tick data file to each broker every time the optimizer runs. I have 36 agents, each writing 10GB for one of the tools and during testing - a total of 360GB written on a 480GB drive. This process takes approximately 1 hour before each optimization. Typical SSD lifespan is 500-1000 write cycles. With 360GB rewritten each time, resources will be exhausted quickly. The library only writes to 1 file from which all 36 agents will then read. All these are the reasons for writing this library: we only use 1 file + save 1 hour writing data to each broker + speedup compared to MQ tester or even virtual in real tick mode.
Worked on this problem at the same time as fxsaber (author of EAToMath) and each had their own version. My code is clearer to me, so I use it.
For trading operations, use the MT4Orders library https://www.mql5.com/en/code/16006
For virtual transactions, you need to use the virtual library https://www.mql5.com/en/code/22577
To view trading results you can use MT4Orders QuickReport https://www.mql5.com/en/code/47816 or TickCompressor https://www.mql5.com/en/code/66201
Removed possibly unnecessary ticks from the Control_Trade_Sessions library https://www.mql5.com/en/code/48059. For example, if the quote period is larger than the trading period, it is connected. All quotes can also be deleted if they are used, i.e. the sessions overlap.
Differences from EAToMath:
The speed of the BidAsk variant is comparable to EAToMath. Other variants are slower because they contain more data or have additional ZIP compression.
Usage features:
You cannot use the standard functions symbol() , number( ) (=4), opinion() (=0.0001) in the strategy, since they will produce default values, independent of the tested symbol. Instead of them using _symbols , _numbers , _views they are overwritten with the values read from the file. Additionally, new constants _TickSize and _TickValue were added to record the value of the sign - they are necessary for correct calculation of profits, commissions and swaps on deposit currencies.
Working sequence for the test period selected when saving the quote:
Archiving working sequence:
The simplest Expert Advisor example for estimating the speed of work:
#property tester no cache #include// Join transactions in math mode Input integer represents = 0 ; //Repeat optimization input boolean addvolume = true ; blank on initialize () {} blank check () { static MQTick tick; if ( symbol information tick ( _symbol , tick)) { #ifdef _math_flag_ if (MathTick.SaveTick(Tick)){ return ; } //If we save the tick, exit and do not trade. #endif Strategy (check); } } sum of doubles = 0 ; integer tk = 0 ; blank strategy ( MQTick & tick) { // Simplest strategy - for comparing reading speed with EAToMath Sum += Tick.bid+Tick.ask+(AddVolumes?Tick.volume_real: 0.0 ); tk++; //if(tk<100){Print(Tick.time," " ",Tick.ask," ",Tick.bid," ",Tick.last," ",Tick.volume_real," ",Tick.flags);} } own start time = get microsecond count (); double tester (){ #ifdef _MathTick_ // Run with MathTick - it uses ticks to count symbolic arguments in the file. Used for testing in mat mode if (MathTick.SaveTicksEnd()){ returns 0 ;} // Record ticks and close the file after exiting if (MathTick.ReadSymbolVars()){ MathTick.Ticker(); // In mat mode all price changes will be provided to Strategy(MqlTick &Tick). } #endif print ( "check:" ,tk); long working time = ( long )( getmicrosecond count () - start time)/ 1000 ; //Return(NormalizeDouble(work_time, 1)); //Get the work speed return sum; //Compare the calculation results }
You can toggle 1 setting:
//#define RestoreFlags // восстановить флаги тика из изменения Ask, Bid, Volume - добавит 7% к времени генерации тиков 931 вместо 869 мс
When a tick is generated, statistics about tick compression are displayed.
Below is a printout of the statistics, volume and time of quote generation.
----------
MQ roll-free tester <br/>The first pass returns the result 4345830621850.311523 0:00:08.232
MQ tester with coil <br/>The first pass returns the result 4345879117123.356445 0:00:07.962
Size of .tcs files for the same year in 2023:

All variants with ZIP, even full saves are more compact (3.5 to 1.5 times).
Example of Expert Advisor with virtual trading and report output:
#property tester no cache #include// https://www.mql5.com/en/code/16006 #include // Join transactions in math mode #define ORDER_CURRENCY_DIGITS 2 // Set of numbers used to calculate profits/commissions/swaps when placed in trading history. #Define VIRTUAL_LIMITS_TP_SLIPPAGE // Limiters and take profit prices are executed at the first accepted price - positive slippage #Define order commission - 0 // Commission allocation = lot * ORDER_COMMISSION. #include // https://www.mql5.com/en/code/22577 #Define report tester // The tester will automatically record the report #define REPORT_BROWSER // Create report on browser startup - requires DLL permissions. #define USE_highcharts //- You can download and try all Highcharts products for free. Once your project/product is ready to launch, purchase a commercial license. https://shop.highcharts.com/ #include // Enumeration VirtTyp {MQ_Tester= 0 , virtual 1= 1 , virtual 2= 2 }; input VirtTyp tester 1= 1 ; //Tester 1 Enter VirtTyp Tester 2 = 2 ; //Tester 2 Input integer represents = 0 ; //Repeat optimization boolean isoptimize= false , isTester= false ; double- bar initialization= 0 ; VIRTUAL_POINTER virtual[ 10 ]; blank initialization (){ virtual[ 0 ] = 0 ; // 0 - real trading environment virtual[ 1 ] = VIRTUAL::Create(AccountBalance()); // Create virtualization 1. virtual[ 2 ] = VIRTUAL::Create(AccountBalance()); // Create virtualization 2. //Virtual [tester1].Select(); is optimization = MQLInfo integer ( MQL_optimization ); is tester = MQLInfoInteger ( MQL_Tester ); balInit=account balance(); } Blank check (){ //Virtual[0].Select(); Virtual::NewTick(); // Send the tick to the current virtual machine's static MQTick check; if ( symbol information tick ( _symbol , tick)) { #ifdef _math_flag_ if (MathTick.SaveTick(Tick)){ return ; } //The function will be exited when the price change is written, Strategy() will not be called #endif strategy(check); //trade } } blank strategy ( MQTick & tick) { // The simplest strategy - for comparing reading speed with EAToMath if (tick.ask == 0 || tick.bid == 0 ) { return ;} //MQ tester trades on failed ticks, while dummy does not. Also disable MQ if (tester1> 0 ){virtual[tester1].Select();virtual::NewTick(Tick);} //select virtualization 1 and send a tick if (tester2> 0 ){virtual[tester2].Select();virtual::NewTick(Tick);} //select virtualization 2 and send a tick if (isNewHour(Tick.time)){ //The first tick of each hour if (GetHour0(Tick.time) % 2 == 0 ){ // Purchase at even time in tester 1 Virtual[tester1].Select(); //Select virtualization 1 order to send ( _symbol , OP_Buy, 1 , check.ask, 0 , check.ask - 100 * _views , check.ask + 100 * _views ); } else { // Sell at odd times in tester 2 Virtual[tester2].Select(); // Select virtualization 2 order to send ( _symbol , OP_SELL, 1 , tick.bid, 0 , tick.bid+ 100 * _views , tick. bid - 100 * _views ); } } } doubletester (){ #ifdef _math_mark_ // Run with MathTick - it will read the symbol parameters from the ticks file. Used for testing in mat mode if (MathTick.SaveTicksEnd()) { return 0 ;} //Return after saving ticks if (MathTick.isMath && MathTick.ReadSymbolVars()) { if (tester1== 0 ){ alert ( " >>>>>>>>> Virtual tester1=MQ. Only virtual testers can be used in math mode. <<<<<<<<" ); return 0 ;} if (tester2 == 0 ) { alert ( " >>>>>>>>> virtual tester 1 = MQ. Only virtual testers can be used in math mode. <<<<<<<<" ); return 0 ;} SYMBOL_BASE sb; sb.view = _perspective ; s.number = _number ; sb.symbol = _symbol ; sb.SymbolID = 0 ; sb.TickSize = _TickSize; sb.TickValue=_TickValue / _TickSize; //this.TickValue_ /= this.TickSize_; //Virtual [ 1 ] as shown in SetSymbol() in \fxsaber\Virtual\Symbol_Base.mqh . select(); virtual::SetSymbolBase(sb); virtual[ 2 ]. Select(); Virtual::SetSymbolBase(sb); //minFreezeLevel = _minFreezeLevel*_Point; minStopLevel = _minStopLevel*_Point; Virtual[tester1].Select(); MathTick.Ticker(); // In mat mode all price changes will be provided to Strategy(MqlTick &Tick). } #endif double ret_val= 0 ; for ( integer v = 0 ; v <= virtual::total(); v++){ if (virtual[v].Select()) { if (v > 0 ){ virtual::stop(); #ifdef _math_mark_ // Run with MathTick - it will read the symbol parameters from the tick file. For testing in mat mode if (MathTick.isMath) { VIRTUAL::CalcSwaps( MathTick.swapShort, MathTick.swapLong, 0 , MathTick.swap3days ); } //Swap else from tick file {Virtual::CalculateSwap( _symbol , 0 );} #otherVirtual ::CalculateSwaps( _symbol , 0 ); //Calculate swap- All trades have a swap, i.e. if there are more than 2 different instruments, they will all have a swap of the main instrument. #endif } // Close outstanding trades at the price of the last tick, as in the tester if ( !isOptimization) {QuickReport( "report_" + ( string )v, true , v, false , true ); } print (( string )v + "account balance = " , account balance (), " account equity = " ,AccountEquity()); Doubled prib=AccountBalance()-balInit; ret_val += prib; // }} Return ret_val; // Compare calculation results } Boolean value is new time ( date time &t) { static integernext_h=- 1 ; if (t < next_h) { return false ; } else { next_h = (GetHour0(t)+ 1 )* 3600 ; return true ; }} integer get time 0 ( datetime &t) { return (( integer )( t / 3600 ));} //The current time since January 1, 1971
This example creates 2 virtual machines with different transactions. One tester buys at even times and the other sells at odd times.
This is a complex example with 2 testers, it can be simplified if you need to work with 1 tester.
You can also select the MQ tester and compare it with the results of the virtual tester to control the correctness of the calculations. It's just that the delegates may not be consistent because there are many different delegates and only one variant is programmed in the virtual tester.
Professional closing panel with 6 smart filters. Close all positions by type, by symbol or by P&L. Real-time profit and loss display. Ideal for emergency exits and risk management. Includes security confirmation.
This function calculates the lot size of an open position. The opening price of the trade, the price of the stop loss level and the risk per trade (as a percentage of margin) are passed as parameters
An idea by Andrey F. Zelinsky, based on William Blau's indicator
Set up three crossovers and monitor daily percentage performance starting from a given time (which can also be set).
Attachment download
📎 Control_Trade_Sessions.mqh (13.48 KB)
📎 TickCompressor.mqh (39.54 KB)
📎 MathTicker.mqh (31.16 KB)
📎 MathTickerTest.mq5 (13.48 KB)
Source: MQL5 #65821
💡 Featured Recommendations
✍️ Latest by the author
- •
- •
- •
- •
- •
- •
📌 Popular topics
- •
- •
- •
- •
- •
- •
- •
- •
🔗 You May Be Interested In
- •
- •
- •
- •
- •
- •