cowil:
And then ran it in the Strategy Tester using USDJPY data from 2007.1.1->2013.1.1. If "placeOrder" is set to false (i.e. no order is placed), the Expert does absolutely nothing and completes in 53509ms or approx 54 seconds (this can be seen in the journal). If placeOrder is set to true (1 order is placed and nothing else happens), the Expert takes 458300ms (7m38sec) to complete. Adding hundreds of lines of code, lots of indicators etc to the Expert without placing an order adds only a few minutes to the time. The time does appear to improve however, when a currency pair is selected that has the same base currency as your account (seems to take approximately half the time - maybe it's the cross currency calculations that also takes a lot of time?).
Firstly, could someone run the above Expert and confirm the results I'm getting so that I know it's not an issue with my computer? I'm running an i7 3.2Mhz quad core so can't see this being the issue but you never know... Oh, and when running this test, please make sure that you've definitely got 1m data going all the way back to 2007 - I've noticed that a number of brokers only provide 1m data going back a couple of years and then expect you to rely on 5m, 15m, 30m, 1h etc data.
Anyone else got any ideas?
The bizarre thing is that speed problems aren't really an issue when using "1 minute OHLC" mode. This is strange as "1 minute OHLC" mode still produces 4 ticks per minute (open, high, low, close price) while whereas "Every Tick" mode produces a maximum of 11 ticks per minute (https://www.mql5.com/en/articles/75). So theoretically, "Every Tick" mode should only be a maximum (assuming EVERY minute would generate 11 ticks which would never be the case) of about 3 times slower than "1 minute OHLC"... ?
placeOrder = false
2013.04.16 10:02:00 Core 1 USDJPY,M1: 51930445 ticks (2130353 bars) generated within 29453 ms (total bars in history 2489491, total time 29516 ms)
placeOrder = true
2013.04.16 10:03:38 Tester USDJPY,M1 (MetaQuotes-Demo): testing of Experts\testcowil.ex5 from 2007.01.01 00:00 to 2013.01.01 00:00
2013.04.16 10:03:39 Core 1 OpenCL device: CPU Intel(R) Corporation Intel(R) Core(TM) i7-2677M CPU @ 1.80GHz with OpenCL 1.1 (4 units, 1800 MHz, 3998 Mb, version 1.1)
2013.04.16 10:03:39 Core 1 common synchronization completed
2013.04.16 10:03:39 Core 1 1490 bytes of tester parameters loaded
2013.04.16 10:03:39 Core 1 708 bytes of input parameters loaded
2013.04.16 10:03:39 Core 1 initial deposit 100000.00 USD, leverage 1:100
2013.04.16 10:03:39 Core 1 successfully initialized
2013.04.16 10:03:39 Core 1 2287 bytes of total initialization data received
2013.04.16 10:03:39 Core 1 Intel Core i7-2677M @ 1.80GHz, 3998 MB
2013.04.16 10:03:39 Core 1 USDJPY: symbol tick base found
2013.04.16 10:03:42 Core 1 USDJPY: load 27 bytes of history data to synchronize
2013.04.16 10:03:42 Core 1 USDJPY: history synchronized from 1971.01.04 to 2013.03.22
2013.04.16 10:03:42 Core 1 USDJPY,M1: history cached from 2006.01.02 00:02
2013.04.16 10:03:42 Core 1 USDJPY,M1 (MetaQuotes-Demo): every tick generating
2013.04.16 10:03:42 Core 1 USDJPY,M1: testing of Experts\testcowil.ex5 from 2007.01.01 00:00 to 2013.01.01 00:00 started with inputs:
2013.04.16 10:03:42 Core 1 placeOrder=true
2013.04.16 10:03:42 Core 1 2007.01.02 00:00:00 instant buy 0.10 USDJPY at 119.010 (118.980 / 119.010 / 118.980)
2013.04.16 10:03:42 Core 1 2007.01.02 00:00:00 deal #2 buy 0.10 USDJPY at 119.010 done (based on order #2)
2013.04.16 10:03:42 Core 1 2007.01.02 00:00:00 deal performed [#2 buy 0.10 USDJPY at 119.010]
2013.04.16 10:03:42 Core 1 2007.01.02 00:00:00 order performed buy 0.10 at 119.010 [#2 buy 0.10 USDJPY at 119.010]
2013.04.16 10:03:53 Tester quality of analyzed history is 100%
2013.04.16 10:05:51 Core 1 2012.12.31 23:59:59 position closed due end of test at 86.610 [buy 0.10 USDJPY 119.010]
2013.04.16 10:05:51 Core 1 2012.12.31 23:59:59 deal #3 sell 0.10 USDJPY at 86.610 done (based on order #3)
2013.04.16 10:05:51 Core 1 2012.12.31 23:59:59 deal performed [#3 sell 0.10 USDJPY at 86.610]
2013.04.16 10:05:51 Core 1 2012.12.31 23:59:59 order performed sell 0.10 at 86.610 [#3 sell 0.10 USDJPY at 86.610]
2013.04.16 10:05:51 Core 1 final balance 96236.13
2013.04.16 10:05:51 Core 1 OnTester result 0
2013.04.16 10:05:51 Core 1 USDJPY,M1: 51930445 ticks (2130353 bars) generated within 132632 ms (total bars in history 2489491, total time 132679 ms)
2013.04.16 10:05:51 Core 1 616 Mb memory used
2013.04.16 10:05:51 Core 1 log file "D:\Forex\MT5\Alpari UK\Tester\Agent-127.0.0.1-3000\logs\20130416.log" written
2013.04.16 10:05:51 Core 1 connection closed
As a side note. You misunderstood the article, there is not a maximum of 11 ticks per minute, but a maximum of 11 support points. Ticks are then generated between these support points.
Hi,
So theoretically, "Every Tick" mode should only be a maximum (assuming EVERY minute would generate 11 ticks which would never be the case) of about 3 times slower than "1 minute OHLC"... ?
I can't run your EA as I don't have 6 years worth of data I only have M1 back to Jan 2009. One thing I can tell you for certain, in the Strategy Tester every tick mode each M1 bar can have more than 11 ticks used to make it.
Running 6 years of data in the Strategy Tester in 13 minutes isn't slow in my experience. Perhaps your Broker has a lot of ticks in their more recent data, I have noticed this and it does slow down the Strategy Tester, you should compared data from a few Brokers and you will see how the tick count can differ significantly. https://www.mql5.com/en/forum/9949/439717#comment_439717
The difference between 2 runs is here :
if (placeOrder && ! PositionSelect(_Symbol)) {
When placeOrder is false the second isn't executed. When placeOrder is true the second test is always executed, for each tick.
The scheme of the so called "brief estimate" is applied to boolean operations, i.e. the calculation of the expression is terminated when the result of the expression can be precisely estimated.
So total time of execution is (132 679 - 29 516) = 103 163 ms for 51 930 445 ticks, that give 1.9866 µs for executing PositionSelect(_Symbol). Seems to me very reasonable.
placeOrder = false
2013.04.16 10:02:00 Core 1 USDJPY,M1: 51930445 ticks (2130353 bars) generated within 29453 ms (total bars in history 2489491, total time 29516 ms)
placeOrder = true
2013.04.16 10:03:38 Tester USDJPY,M1 (MetaQuotes-Demo): testing of Experts\testcowil.ex5 from 2007.01.01 00:00 to 2013.01.01 00:00
2013.04.16 10:03:39 Core 1 OpenCL device: CPU Intel(R) Corporation Intel(R) Core(TM) i7-2677M CPU @ 1.80GHz with OpenCL 1.1 (4 units, 1800 MHz, 3998 Mb, version 1.1)
2013.04.16 10:03:39 Core 1 common synchronization completed
2013.04.16 10:03:39 Core 1 1490 bytes of tester parameters loaded
2013.04.16 10:03:39 Core 1 708 bytes of input parameters loaded
2013.04.16 10:03:39 Core 1 initial deposit 100000.00 USD, leverage 1:100
2013.04.16 10:03:39 Core 1 successfully initialized
2013.04.16 10:03:39 Core 1 2287 bytes of total initialization data received
2013.04.16 10:03:39 Core 1 Intel Core i7-2677M @ 1.80GHz, 3998 MB
2013.04.16 10:03:39 Core 1 USDJPY: symbol tick base found
2013.04.16 10:03:42 Core 1 USDJPY: load 27 bytes of history data to synchronize
2013.04.16 10:03:42 Core 1 USDJPY: history synchronized from 1971.01.04 to 2013.03.22
2013.04.16 10:03:42 Core 1 USDJPY,M1: history cached from 2006.01.02 00:02
2013.04.16 10:03:42 Core 1 USDJPY,M1 (MetaQuotes-Demo): every tick generating
2013.04.16 10:03:42 Core 1 USDJPY,M1: testing of Experts\testcowil.ex5 from 2007.01.01 00:00 to 2013.01.01 00:00 started with inputs:
2013.04.16 10:03:42 Core 1 placeOrder=true
2013.04.16 10:03:42 Core 1 2007.01.02 00:00:00 instant buy 0.10 USDJPY at 119.010 (118.980 / 119.010 / 118.980)
2013.04.16 10:03:42 Core 1 2007.01.02 00:00:00 deal #2 buy 0.10 USDJPY at 119.010 done (based on order #2)
2013.04.16 10:03:42 Core 1 2007.01.02 00:00:00 deal performed [#2 buy 0.10 USDJPY at 119.010]
2013.04.16 10:03:42 Core 1 2007.01.02 00:00:00 order performed buy 0.10 at 119.010 [#2 buy 0.10 USDJPY at 119.010]
2013.04.16 10:03:53 Tester quality of analyzed history is 100%
2013.04.16 10:05:51 Core 1 2012.12.31 23:59:59 position closed due end of test at 86.610 [buy 0.10 USDJPY 119.010]
2013.04.16 10:05:51 Core 1 2012.12.31 23:59:59 deal #3 sell 0.10 USDJPY at 86.610 done (based on order #3)
2013.04.16 10:05:51 Core 1 2012.12.31 23:59:59 deal performed [#3 sell 0.10 USDJPY at 86.610]
2013.04.16 10:05:51 Core 1 2012.12.31 23:59:59 order performed sell 0.10 at 86.610 [#3 sell 0.10 USDJPY at 86.610]
2013.04.16 10:05:51 Core 1 final balance 96236.13
2013.04.16 10:05:51 Core 1 OnTester result 0
2013.04.16 10:05:51 Core 1 USDJPY,M1: 51930445 ticks (2130353 bars) generated within 132632 ms (total bars in history 2489491, total time 132679 ms)
2013.04.16 10:05:51 Core 1 616 Mb memory used
2013.04.16 10:05:51 Core 1 log file "D:\Forex\MT5\Alpari UK\Tester\Agent-127.0.0.1-3000\logs\20130416.log" written
2013.04.16 10:05:51 Core 1 connection closed
As a side note. You misunderstood the article, there is not a maximum of 11 ticks per minute, but a maximum of 11 support points. Ticks are then generated between these support points.
I can't run your EA as I don't have 6 years worth of data I only have M1 back to Jan 2009. One thing I can tell you for certain, in the Strategy Tester every tick mode each M1 bar can have more than 11 ticks used to make it.
Running 6 years of data in the Strategy Tester in 13 minutes isn't slow in my experience. Perhaps your Broker has a lot of ticks in their more recent data, I have noticed this and it does slow down the Strategy Tester, you should compared data from a few Brokers and you will see how the tick count can differ significantly. https://www.mql5.com/en/forum/9949/439717#comment_439717
Hi - Thanks for your prompt reply.
Re: the number of ticks - yeah, after rereading the article and dividing the reported simulation ticks with the number of bars, it's become apparent that there are a lot more than a max of 11 ticks generated per bar.
Re: your second comment. I'm a bit confused - I presume that when you say that my broker has a lot more ticks, you're meaning that the volumes of each of the M1 bars are larger or smaller, depending on the broker (larger 1m volumes would generate more ticks)?
The difference between 2 runs is here :
When placeOrder is false the second isn't executed. When placeOrder is true the second test is always executed, for each tick.
So total time of execution is (132 679 - 29 516) = 103 163 ms for 51 930 445 ticks, that give 1.9866 µs for executing PositionSelect(_Symbol). Seems to me very reasonable.
Thanks for your reply. I am actually aware of how && works but found it hard to believe that one PositionSelect(_Symbol) would slow the code down to such an extent - especially when I'd chopped out large parts of my Expert without much of a change in the Experts running time. So I decided to make a small change to my "Test" Expert as follows:
//+------------------------------------------------------------------+ //| Test.mq5 | //| | //+------------------------------------------------------------------+ input bool placeOrder = false; bool orderNotPlaced = true; int OnInit() { return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ void OnTick() { if (placeOrder && orderNotPlaced) { // Get last tick details... MqlTick lastTick; SymbolInfoTick(_Symbol, lastTick); // Creata the 'MQLTradeRequest' object and place order... MqlTradeRequest request = {0}; request.action = TRADE_ACTION_DEAL; request.symbol = _Symbol; request.volume = 0.1; request.price = lastTick.ask; request.sl = 0; request.tp = 0; request.deviation = 10; request.type = ORDER_TYPE_BUY; request.type_filling = ORDER_FILLING_FOK; MqlTradeResult result = {0}; OrderSend(request, result); orderNotPlaced = false; } }
The above is probably the way I should have written it originally but I was in a bit of a hurry at the time. :) Anyway, this change didn't make a huge difference in the times (See below):
Original "Test" Expert with "PositionSelect(_Symbol)" call - placeOrder = true ======================================== 2013.04.17 10:13:28 Core 1 connection closed 2013.04.17 10:13:28 Core 1 log file "C:\ProgramFiles\MetaTrader\Alpari NZ MT5\Tester\Agent-127.0.0.1-3000\logs\20130417.log" written 2013.04.17 10:13:28 Core 1 626 Mb memory used 2013.04.17 10:13:28 Core 1 USDJPY,M1: 86903435 ticks (2131881 bars) generated within 473417 ms (total bars in history 2448417, total time 473479 ms) 2013.04.17 10:13:28 Core 1 OnTester result 0 2013.04.17 10:13:28 Core 1 final balance 7167.61 2013.04.17 10:13:28 Core 1 2012.12.31 23:59:59 order performed sell 0.10 at 86.613 [#3 sell 0.10 USDJPY at 86.613] 2013.04.17 10:13:28 Core 1 2012.12.31 23:59:59 deal performed [#3 sell 0.10 USDJPY at 86.613] 2013.04.17 10:13:28 Core 1 2012.12.31 23:59:59 deal #3 sell 0.10 USDJPY at 86.613 done (based on order #3) 2013.04.17 10:13:28 Core 1 2012.12.31 23:59:59 position closed due end of test at 86.613 [buy 0.10 USDJPY 118.760] 2013.04.17 10:05:35 Core 1 2007.01.02 08:00:30 order performed buy 0.10 at 118.760 [#2 buy 0.10 USDJPY at 118.760] 2013.04.17 10:05:35 Core 1 2007.01.02 08:00:30 deal performed [#2 buy 0.10 USDJPY at 118.760] 2013.04.17 10:05:35 Core 1 2007.01.02 08:00:30 deal #2 buy 0.10 USDJPY at 118.760 done (based on order #2) 2013.04.17 10:05:35 Core 1 EURJPY: history synchronized from 2004.01.01 to 2013.04.12 2013.04.17 10:05:35 Core 1 EURJPY: load 27 bytes of history data to synchronize 2013.04.17 10:05:35 Core 1 EURJPY: symbol tick base found 2013.04.17 10:05:35 Core 1 2007.01.02 08:00:30 exchange buy 0.10 USDJPY at 118.760 (118.730 / 118.760 / 118.730) 2013.04.17 10:05:35 Core 1 EURUSD: history synchronized from 1999.01.04 to 2013.04.12 2013.04.17 10:05:35 Core 1 EURUSD: load 27 bytes of history data to synchronize 2013.04.17 10:05:35 Core 1 EURUSD: symbol tick base found 2013.04.17 10:05:35 Core 1 placeOrder=true 2013.04.17 10:05:35 Core 1 USDJPY,M1: testing of Experts\Test.ex5 from 2007.01.01 00:00 to 2013.01.01 00:00 started with inputs: ==================== 473479 ms = 7m53sec ====================
New "Test" Expert WITHOUT "PositionSelect(_Symbol)" call - placeOrder = true =============================================================================== 2013.04.17 10:26:00 Core 1 connection closed 2013.04.17 10:25:59 Core 1 log file "C:\ProgramFiles\MetaTrader\Alpari NZ MT5\Tester\Agent-127.0.0.1-3000\logs\20130417.log" written 2013.04.17 10:25:59 Core 1 626 Mb memory used 2013.04.17 10:25:59 Core 1 USDJPY,M1: 86903435 ticks (2131881 bars) generated within 455523 ms (total bars in history 2448417, total time 455601 ms) 2013.04.17 10:25:59 Core 1 OnTester result 0 2013.04.17 10:25:59 Core 1 final balance 7167.61 2013.04.17 10:25:59 Core 1 2012.12.31 23:59:59 order performed sell 0.10 at 86.613 [#3 sell 0.10 USDJPY at 86.613] 2013.04.17 10:25:59 Core 1 2012.12.31 23:59:59 deal performed [#3 sell 0.10 USDJPY at 86.613] 2013.04.17 10:25:59 Core 1 2012.12.31 23:59:59 deal #3 sell 0.10 USDJPY at 86.613 done (based on order #3) 2013.04.17 10:25:59 Core 1 2012.12.31 23:59:59 position closed due end of test at 86.613 [buy 0.10 USDJPY 118.760] 2013.04.17 10:18:25 Core 1 2007.01.02 08:00:30 order performed buy 0.10 at 118.760 [#2 buy 0.10 USDJPY at 118.760] 2013.04.17 10:18:25 Core 1 2007.01.02 08:00:30 deal performed [#2 buy 0.10 USDJPY at 118.760] 2013.04.17 10:18:25 Core 1 2007.01.02 08:00:30 deal #2 buy 0.10 USDJPY at 118.760 done (based on order #2) 2013.04.17 10:18:25 Core 1 EURJPY: history synchronized from 2004.01.01 to 2013.04.12 2013.04.17 10:18:25 Core 1 EURJPY: load 27 bytes of history data to synchronize 2013.04.17 10:18:25 Core 1 EURJPY: symbol tick base found 2013.04.17 10:18:25 Core 1 2007.01.02 08:00:30 exchange buy 0.10 USDJPY at 118.760 (118.730 / 118.760 / 118.730) 2013.04.17 10:18:25 Core 1 EURUSD: history synchronized from 1999.01.04 to 2013.04.12 2013.04.17 10:18:25 Core 1 EURUSD: load 27 bytes of history data to synchronize 2013.04.17 10:18:25 Core 1 EURUSD: symbol tick base found 2013.04.17 10:18:25 Core 1 placeOrder=true 2013.04.17 10:18:25 Core 1 USDJPY,M1: testing of Experts\Test.ex5 from 2007.01.01 00:00 to 2013.01.01 00:00 started with inputs: ===================== 455601 ms = 7m35sec =====================
New "Test" Expert WITHOUT "PositionSelect(_Symbol)" call - placeOrder = false =============================================================================== 2013.04.17 10:29:27 Core 1 connection closed 2013.04.17 10:29:27 Core 1 log file "C:\ProgramFiles\MetaTrader\Alpari NZ MT5\Tester\Agent-127.0.0.1-3000\logs\20130417.log" written 2013.04.17 10:29:27 Core 1 615 Mb memory used 2013.04.17 10:29:27 Core 1 USDJPY,M1: 86903435 ticks (2131881 bars) generated within 87720 ms (total bars in history 2448417, total time 87767 ms) 2013.04.17 10:29:27 Core 1 OnTester result 0 2013.04.17 10:29:27 Core 1 final balance 10000.00 2013.04.17 10:28:17 Tester quality of analyzed history is 98% 2013.04.17 10:28:00 Core 1 placeOrder=false 2013.04.17 10:28:00 Core 1 USDJPY,M1: testing of Experts\Test.ex5 from 2007.01.01 00:00 to 2013.01.01 00:00 started with inputs: ================== 87767 ms = 1m27sec ==================
Removing the PositionSelect(_Symbol) from my code saved all of 18 seconds....
Re: your second comment. I'm a bit confused - I presume that when you say that my broker has a lot more ticks, you're meaning that the volumes of each of the M1 bars are larger or smaller, depending on the broker (larger 1m volumes would generate more ticks)?
Thanks for your reply. I am actually aware of how && works but found it hard to believe that one PositionSelect(_Symbol) would slow the code down to such an extent - especially when I'd chopped out large parts of my Expert without much of a change in the Experts running time. So I decided to make a small change to my "Test" Expert as follows:
The above is probably the way I should have written it originally but I was in a bit of a hurry at the time. :) Anyway, this change didn't make a huge difference in the times (See below):
Removing the PositionSelect(_Symbol) from my code saved all of 18 seconds....
Yes, your Broker's M1 history bars may have unusually large tick counts compared to some other Broker's M1 bars. Yes, the tick count of the M1 bar governs how many ticks will be synthesised by the Strategy Tester, so if the history data has many ticks per M1 bar so will the M1 bars produced by the Strategy Tester.
You are right, I can't see an explanation to this. I think only a developer from MQ who knows how the compiler is implemented can respond.
Yep, it's all very odd... I've opened a bug report on this so it'll be interesting to see what MQ come back with.
Anyway, thanks for your prompt replies and help - much appreciated!
- www.mql5.com
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hi,
I don't know about you guys but I've been experiencing extremely slow performance when using the strategy tester in "Every Tick" mode. One pass (i.e. no optimisation) of my Expert takes approximately 13 minutes (!) when testing on 6 years of data.
It's quite a complex Expert so thinking that the problem was related to my code, I began profiling and optimising the code. However, I wasn't making a lot of headway and began to wonder if there was something else going on. I started eliminating whole chunks of my Expert and found that not a lot of speed was gained. I finally realised that the speed issues I was experiencing came down to the fact that I'D PLACED AN ORDER WITHIN MY EXPERT!!! Yep, it appears that if you open an order within an Expert, the whole strategy testing slows right down by a factor of around 9-10. To demonstrate this, I whipped up the following Expert:
And then ran it in the Strategy Tester using USDJPY data from 2007.1.1->2013.1.1. If "placeOrder" is set to false (i.e. no order is placed), the Expert does absolutely nothing and completes in 53509ms or approx 54 seconds (this can be seen in the journal). If placeOrder is set to true (1 order is placed and nothing else happens), the Expert takes 458300ms (7m38sec) to complete. Adding hundreds of lines of code, lots of indicators etc to the Expert without placing an order adds only a few minutes to the time. The time does appear to improve however, when a currency pair is selected that has the same base currency as your account (seems to take approximately half the time - maybe it's the cross currency calculations that also takes a lot of time?).
Firstly, could someone run the above Expert and confirm the results I'm getting so that I know it's not an issue with my computer? I'm running an i7 3.2Mhz quad core so can't see this being the issue but you never know... Oh, and when running this test, please make sure that you've definitely got 1m data going all the way back to 2007 - I've noticed that a number of brokers only provide 1m data going back a couple of years and then expect you to rely on 5m, 15m, 30m, 1h etc data.
Anyone else got any ideas?
The bizarre thing is that speed problems aren't really an issue when using "1 minute OHLC" mode. This is strange as "1 minute OHLC" mode still produces 4 ticks per minute (open, high, low, close price) while whereas "Every Tick" mode produces a maximum of 11 ticks per minute (https://www.mql5.com/en/articles/75). So theoretically, "Every Tick" mode should only be a maximum (assuming EVERY minute would generate 11 ticks which would never be the case) of about 3 times slower than "1 minute OHLC"... ?