I currently have my EA calculate values on the last x amount of bars - this however creates a huge lag during back testing - because of the "for loop" it looks like it executes on every tick.
This is how the value check stars:
//CHECK ID10T VALUES FOR BUY OR SELL
if(BUY_ORDER == 0 && SELL_ORDER == 0 && Bars!=BarCount)
{
for(int shift = Bars - ID10Tp; shift >= 0; shift--)
{
HighestBar = iHighest(NULL,0,MODE_HIGH,ID10Tp - 1,shift);
LowestBar = iLowest (NULL,0,MODE_LOW, ID10Tp - 1,shift);
I already bypass the value checking if any order is open (BUY_ORDER == 0 && SELL_ORDER == 0) so that the checking only happens if I want to open a new trade.
If I change the Bars!=BarCount to Bars == BarCount then the for loop is bypassed and I do not get any values :(
So my question to somebody willing to assist: How can I force the EA to check for new values only when a bar is completed and new bar is starting. I need each tick mode for accuracy so that must stay - only this part of the code must execute ONCE per bar.
Thank you in advance
Barry
Very easy & simple
datetime Last_Candle_Open_Time=0; //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { if(Last_Candle_Open_Time!=Time[0]) { //---Put the logic in this space, to calculate the logic only once per bar Print(TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES)+", Only print this message once per bar"); Last_Candle_Open_Time=Time[0]; } }
Very easy & simple
Soheil - THANK YOU for your reply! I have tried to copy your solution but I am running into an error I do not know how to solve.
Error: OnTick function can only be declared in the Global scope
I am no coder/programmer but a brilliant copy & paster :)
So where exactly must I copy & paste your solution?
int Init() section - Gives the Global scope error
int Start() section - Gives the Global scope error
This is how I tried to copy your solution: (Pasted in Init then tried Start but both ways gives an error.
void OnTick()
{
if(CandleTime!=Time[0]){CountedNow = CountedNow + 1;}
CandleTime=Time[0];
}
I will compare 2 values CountedNow and CountedPrev to see if I must execute the value checking loop or not
OK - found a solution: This idea in my head sparked the solution ....
"I will compare 2 values CountedNow and CountedPrev to see if I must execute the value checking loop or not"
Added a variable: double Bar0_Open = iOpen (Symbol(),0,Current + 0);
and on Global declared another variable: double BarPrevious = 0;
Then changed my original code to this:
if(BUY_ORDER == 0 && SELL_ORDER == 0 && BarPrevious!= Bar0_Open)
{
for(int shift = Bars - ID10Tp; shift >= 0; shift--)
{
HighestBar = iHighest(NULL,0,MODE_HIGH,ID10Tp - 1,shift);
LowestBar = iLowest (NULL,0,MODE_LOW, ID10Tp - 1,shift);
And added this after the for loop:
BarPrevious = Bar0_Open;
Now the code executes only once per bar - additional benefit is that this can be used on any time frame, from M1 to W1 without having to change any code :)
From this horrible time consuming back test result ...
2018.12.11 12:57:56.645 EURUSD,M5: 2286856 tick events (6186 bars, 2287857 bar states) processed in 0:30:25.250 (total time 0:30:31.500)
to this!
2018.12.11 12:25:39.329 EURUSD,M5: 2286856 tick events (6186 bars, 2287857 bar states) processed in 0:01:08.828 (total time 0:01:14.703)
Thanks once again Soheil - much appreciated!
I am an amateur coder too. But a question for the experts, related to the OP's smart solution...
Does the OP need to have the loop now? OR... can he improve or make the loop more efficient?
for(int shift = Bars - ID10Tp; shift >= 0; shift--)
Does this code continue being executed on every new tick? or only on first tick of new candle, like the OP said?
It seems to me, and please correct me if my statement in incorrect, that this loop should be...
for(int shift = Bars - ID10Tp; shift >= 1; shift--)
You have been given the correct solution by @Soheil Kord but you changed it so that it stops working.
I am an amateur coder too. But a question for the experts, related to the OP's smart solution...
Does the OP need to have the loop now? OR... can he improve or make the loop more efficient?
Does this code continue being executed on every new tick? or only on first tick of new candle, like the OP said?
It seems to me, and please correct me if my statement in incorrect, that this loop should be...
Hi Revo
As I understand it you should almost always start with 0 (zero) - with zero being the current value, one the previous value and so on ... :)
You have been given the correct solution by @Soheil Kord but you changed it so that it stops working.
Copy paste had worked in this case.
But you changed it so that's not exactly copy paste.
Hi Revo
As I understand it you should almost always start with 0 (zero) - with zero being the current value, one the previous value and so on ... :)
int shift = Bars - ID10Tp;
starts from 0, as you say. Or am i wrong? Sorry if I have hijacked your thread.
Marco? is my statement correct?
![MQL5 - Language of trade strategies built-in the MetaTrader 5 client terminal](https://c.mql5.com/i/registerlandings/logo-2.png)
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
I currently have my EA calculate values on the last x amount of bars - this however creates a huge lag during back testing - because of the "for loop" it looks like it executes on every tick.
This is how the value check stars:
//CHECK ID10T VALUES FOR BUY OR SELL
if(BUY_ORDER == 0 && SELL_ORDER == 0 && Bars!=BarCount)
{
for(int shift = Bars - ID10Tp; shift >= 0; shift--)
{
HighestBar = iHighest(NULL,0,MODE_HIGH,ID10Tp - 1,shift);
LowestBar = iLowest (NULL,0,MODE_LOW, ID10Tp - 1,shift);
I already bypass the value checking if any order is open (BUY_ORDER == 0 && SELL_ORDER == 0) so that the checking only happens if I want to open a new trade.
If I change the Bars!=BarCount to Bars == BarCount then the for loop is bypassed and I do not get any values :(
So my question to somebody willing to assist: How can I force the EA to check for new values only when a bar is completed and new bar is starting. I need each tick mode for accuracy so that must stay - only this part of the code must execute ONCE per bar.
Thank you in advance
Barry