Single OnTimer() limitation?

 

Hello everyone.

Backtest ticks frequency is not accurate, I'm trying to find out how much inaccurate it is exactly.

In JavaScript I could use another OnTimer but here I'm having a hard time trying to figure out a way. I know there's a way, I'm just lacking enough skill. So please help.

//+------------------------------------------------------------------+
//|   1 Second onTimer()                                             |
//+------------------------------------------------------------------+
void OnTimer()
{
//Here I calculate the average points per a second

   if(!IsTheHour())//Start calculation beginning of this hour
     {after=0; return;}
      
   double new_ = SymbolInfoDouble(_Symbol, SYMBOL_BID);
   if(after == 0)now = 0;
   else
      now = NormalizeDouble(new_ - after, _Digits);
   if(now < 0)now = now * -1;   
   Speed(now);//Calculate the average here
   
   after = new_;
   now = 0; 
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

void record()
{
// Now How do I record this after a minute? or 60 seconds without using OnTick()????

      MqlDateTime tm;
   TimeCurrent(tm);
   
   if(Seconds() >= 60) {
   Print(tm.hour, ":0", tm.min-1);
      Print(NormalizeDouble(Speed(),_Digits));
   } 

}
Testing trading strategies on real ticks
Testing trading strategies on real ticks
  • www.mql5.com
The article provides the results of testing a simple trading strategy in three modes: "1 minute OHLC", "Every tick" and "Every tick based on real ticks" using actual historical data.
 

https://www.mql5.com/en/code/19859

https://www.mql5.com/en/code/26025

These are just suggestions. I am not sure how they were realized. In other words "use the search function."

you could make an int or double array of sixty fields where you might store the "point speed" of every second  inserting the new value at the zero bar every second and use a for loop to shift them back to the past each time before you add a new current value.Then use the array for various average calculations?

There could be an object oriented approach with second objects storing price speed and other things. Or a structure.

AccurateTimer
AccurateTimer
  • www.mql5.com
Increased accuracy of the standard timer.
 
Ndumiso Mavuso: Backtest ticks frequency is not accurate, I'm trying to find out how much inaccurate it is exactly. 

Can you explain in more detail what exactly you are trying to achieve regarding your statement: "backtest ticks frequency is not accurate"?

Why would the ticks frequency need to be accurate? It's not even accurate in live trading either. Ticks arrive at any irregular time and their frequency continually varies depending on the volatility of the trading.

 
Fernando Carreiro #:

Can you explain in more detail what exactly you are trying to achieve regarding your statement: "backtest ticks frequency is not accurate"?

Why would the ticks frequency need to be accurate? It's not even accurate in live trading either. Ticks arrive at any irregular time and their frequency continually varies depending on the volatility of the trading.

They should be stored exactly as they came? exactly, otherwise they're not 100%. I'm not into trading but I'm thinking data should be accurate or close to accurate as possible.


Imagine this 1 minute bar, at 13:01 candle, bid price went as follows: 123 122 121 124 128 126 129 121 & closed at 130. But on Backtest bid price will go as follows: 123 122 121 124 128 129  closing at 130.

The difference is  that live bar price move back and forth to 130 but on backtest is move smoothly from 121 to 131 without making retracements. I hope you get the point I'm trying to make. I tried to draw a graph :)

Maybe this is done on backtest purposefully. So I'm trying to do some research into it


Image is upside down, sorry I couldn't rotate it


 
pennyhunter #:

https://www.mql5.com/en/code/19859

https://www.mql5.com/en/code/26025

These are just suggestions. I am not sure how they were realized. In other words "use the search function."

you could make an int or double array of sixty fields where you might store the "point speed" of every second  inserting the new value at the zero bar every second and use a for loop to shift them back to the past each time before you add a new current value.Then use the array for various average calculations?

There could be an object oriented approach with second objects storing price speed and other things. Or a structure.

I already use an accurate OnTimer to calculate average speed of Bid prices per second. Now I want to record that average, either by print or on a file. Problem is, I can't use OnTick() because OnTick only works per incoming ticks, if there's is no new tick at 00:00:01 millisecond, and this I'm trying to avoid.

 
Ndumiso Mavuso #: They should be stored exactly as they came? exactly, otherwise they're not 100%. I'm not into trading but I'm thinking data should be accurate or close to accurate as possible.

Imagine this 1 minute bar, at 13:01 candle, bid price went as follows: 123 122 121 124 128 126 129 121 & closed at 130. But on Backtest bid price will go as follows: 123 122 121 124 128 129  closing at 130.

The difference is  that live bar price move back and forth to 130 but on backtest is move smoothly from 121 to 131 without making retracements. I hope you get the point I'm trying to make. I tried to draw a graph :)

Maybe this is done on backtest purposefully. So I'm trying to do some research into it.

In the Strategy Tester, you can choose between generated virtual ticks or real ticks. So, choose the Real Ticks for the backtest — "Modeling: Every tick based on real ticks"

In live trading, the OnTick() event handler can skip ticks because your code execution can take longer than the tick frequency. You can simulate this in the Strategy Tester by setting a "Delay:".

 
Ndumiso Mavuso #:

They should be stored exactly as they came? exactly, otherwise they're not 100%. I'm not into trading but I'm thinking data should be accurate or close to accurate as possible.


Imagine this 1 minute bar, at 13:01 candle, bid price went as follows: 123 122 121 124 128 126 129 121 & closed at 130. But on Backtest bid price will go as follows: 123 122 121 124 128 129  closing at 130.

The difference is  that live bar price move back and forth to 130 but on backtest is move smoothly from 121 to 131 without making retracements. I hope you get the point I'm trying to make. I tried to draw a graph :)

Maybe this is done on backtest purposefully. So I'm trying to do some research into it


Image is upside down, sorry I couldn't rotate it


What you are saying is that ticks will be in a different order, well they won't... ticks come into the terminal as price changes and the order of them is nothing to do with time.

The tester has different modes of simulating ticks or using real ticks, simultated ticks will never match the order of the real ticks, again regardless of time.

 
Paul Anscombe #:

What you are saying is that ticks will be in a different order, well they won't... ticks come into the terminal as price changes and the order of them is nothing to do with time.

The tester has different modes of simulating ticks or using real ticks, simultated ticks will never match the order of the real ticks, again regardless of time.

This is not true...

The ticks might be accurate I don't know. But their frequency in time is way different on the tester vs Live.

Here's how I can prove it...

Say I record how much it took price to move from 123 to 120. On live, it would have taken 500 milliseconds. But on the Tester is might say it took 2 seconds.

And here's how I can prove it:

The code below will record in print at what time a point below price was hit during live. and when you go on Test during the same time, you will find that the times will not match. infact live will have more hits than on Tester. Which means Live is faster than Tester.

//--- The SymbolInfo Class
#include <Trade\SymbolInfo.mqh>

//--- The SymbolInfo Class Object
CSymbolInfo mysymbol;


uint ExpirationTime = 1000; // Millisecond
uint set_time = 0;
double Price_below = 0.0;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   if(!TimeRange())
      return;
   expireTime(); //Move point every 1 second.
   Set_();// Set point below price
   if(Price_below != 0 && mysymbol.Bid() <= Price_below) {
      Print("Hit at time: |", TimeCurrent());
      Price_below = 0;
   }
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void Set_()
{
//Set a point below price
   double dis = 30;//Points below Bid
   if(_Digits == 5 || _Digits == 3) dis = dis * 10;
   if(Price_below == 0) {
      Price_below = NormalizeDouble(mysymbol.Bid() - dis * _Point, _Digits);
      set_time = GetTickCount();
   }
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void expireTime()
{
//Move the point below price every 1 second.
   uint dif = GetTickCount();
   if(Price_below != 0)
      if(dif - set_time >= ExpirationTime) {
         Price_below = 0;
      }
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool TimeRange()
{
   MqlDateTime last_date;
   TimeTradeServer(last_date);
   if(last_date.hour != 22) {
      return(false);
   }
//--- Within the allowed time range
   return(true);
}
//+------------------------------------------------------------------+
 
Ndumiso Mavuso #:

This is not true...

The ticks might be accurate I don't know. But their frequency in time is way different on the tester vs Live.

Here's how I can prove it...

Say I record how much it took price to move from 123 to 120. On live, it would have taken 500 milliseconds. But on the Tester is might say it took 2 seconds.

And here's how I can prove it:

The code below will record in print at what time a point below price was hit during live. and when you go on Test during the same time, you will find that the times will not match. infact live will have more hits than on Tester. Which means Live is faster than Tester.

I wouldn't expect the tester to be as fast as a live stream of prices, as it has a lot more to do.

I am a very experienced trader (30 years) and I don't really see what different it makes as follows:

1) the only price that counts at any given point in time is the current price - as it is the only price you can trade at.

2) the notion of time in trading is over rated, as you can only trade at current time and price.

3) when testing systems, the speed of test is irrelevent, it is the sequence of price changes that is important and the time gap between the price changes is irrelevent.

just my opinion. 

 
Ndumiso Mavuso: Backtest ticks frequency is not accurate, I'm trying to find out how much inaccurate it is exactly.

In JavaScript I could use another OnTimer but here I'm having a hard time trying to figure out a way. I know there's a way, I'm just lacking enough skill. So please help.

  1. Timer does not work in the testers.
  2. The test sends ticks as fast as it can. There is no frequency.
Reason: