Since build 1847 of MT5 the bug of hanging in Bars function has been fixed. Also the standard iBarShift function was added.
Therefore, to increase the performance of these functions (somewhere in times 10) it is better now to use this code variant :
int fBars(string symbol_name,ENUM_TIMEFRAMES timeframe,datetime start_time,datetime stop_time) { static string LastSymb=NULL; static ENUM_TIMEFRAMES LastTimeFrame=0; static datetime LastTime=0; static datetime LastTime0=0; static int PerSec=0; static int PreBars=0; static datetime LastBAR=0; static datetime LastTimeCur=0; static bool flag=true; static int max_bars=TerminalInfoInteger(TERMINAL_MAXBARS); datetime TimeCur; if(timeframe==0) timeframe=_Period; const bool changeTF=LastTimeFrame!=timeframe; const bool changeSymb=LastSymb!=symbol_name; const bool change=changeTF || changeSymb || flag; LastTimeFrame=timeframe; LastSymb=symbol_name; if(changeTF) PerSec=::PeriodSeconds(timeframe); if(PerSec==0) { flag=true; return(0);} if(stop_time<start_time) { TimeCur=stop_time; stop_time=start_time; start_time=TimeCur; } if(changeSymb) { if(!SymbolInfoInteger(symbol_name,SYMBOL_SELECT)) { SymbolSelect(symbol_name,true); ChartRedraw(); } } TimeCur=TimeCurrent(); if(timeframe==PERIOD_W1) TimeCur-=(TimeCur+345600)%PerSec; // 01.01.1970 - Thursday. Minus 4 days. if(timeframe<PERIOD_W1) TimeCur-=TimeCur%PerSec; if(start_time>TimeCur) { flag=true; return(0);} if(timeframe==PERIOD_MN1) { MqlDateTime dt; TimeToStruct(TimeCur,dt); TimeCur=dt.year*12+dt.mon; } if(changeTF || changeSymb || TimeCur!=LastTimeCur) LastBAR=(datetime)SeriesInfoInteger(symbol_name,timeframe,SERIES_LASTBAR_DATE); LastTimeCur=TimeCur; if(start_time>LastBAR) { flag=true; return(0);} datetime tS,tF=0; if(timeframe==PERIOD_W1) tS=start_time-(start_time+345599)%PerSec-1; else if(timeframe<PERIOD_MN1) tS=start_time-(start_time-1)%PerSec-1; else // PERIOD_MN1 { MqlDateTime dt; TimeToStruct(start_time-1,dt); tS=dt.year*12+dt.mon; } if(stop_time<=LastBAR) { if(timeframe<PERIOD_W1) tF=stop_time-(stop_time)%PerSec; else if(timeframe==PERIOD_W1) tF=stop_time-(stop_time+345600)%PerSec; else // PERIOD_MN1 { MqlDateTime dt0; TimeToStruct(stop_time-1,dt0); tF=dt0.year*12+dt0.mon; } } if(change || tS!=LastTime || tF!=LastTime0) { PreBars=Bars(symbol_name,timeframe,start_time,stop_time); LastTime=tS; LastTime0=tF; } flag=false; return(PreBars); } int fBarShift(string symb,ENUM_TIMEFRAMES TimeFrame,datetime time,bool exact=false) { int Res=fBars(symb,TimeFrame,time+1,UINT_MAX); if(exact) if((TimeFrame!=PERIOD_MN1 || time>TimeCurrent()) && Res==fBars(symb,TimeFrame,time-PeriodSeconds(TimeFrame)+1,UINT_MAX)) return(-1); return(Res); }
From build 1847 MT5 the bug of hanging in Bars function has been fixed. Also the standard iBarShift function was added.
Therefore, to increase the performance of these functions (somewhere in times 10) it is better now to use this code variant :
Send the code to servicedesk, let them implement it as standard in the platform
Send the code to servicedesk and have them implement it into the platform as standard
Who am I to tell them.
This code is cross-platform. And the most interesting thing is that there is no gain on MT4, so the Bars function is optimally written in MT4.
Who am I to tell them.
This code is cross-platform. And the interesting thing is that there is no gain on MT4, so the Bars function is written optimally in MT4.
This thread is being followed. Insert via pocket your post.
- 2016.09.01
- www.mql5.com
Okay. But for some reason it's not working through the pocket. It's not working. It's through the link.
Therefore, in order to increase the speed of these functions (somewhere in times 10) it is better now to use this code variant :
Aren't you being a bit rash about speed? Especially considering the huge number of all sorts of checks in your code. I'm too lazy to get into the essence of it, but I find it hard to believe that such a mess works fast.
Aren't you overreacting about speed? Especially considering the huge number of all sorts of checks in your code. I'm too lazy to get into the essence of it, but I find it hard to believe that such a mess works fast.
You'd better be too lazy to write this message. ))
I specifically attached an indicator for speed test to these functions.
The Bars function is executed in microseconds, and checks, arithmetic operations(even calculating the square root of a binary number) in less than a nanosecond:
void OnStart() { ulong t; double sum=0; t=GetMicrosecondCount(); for (double i=1; i<2;i+=0.000001 ) sum+=sqrt(i); t=GetMicrosecondCount()-t; Print("Sum of 1,000,000 roots = " + DoubleToString(sum,18)+ " for " + IntegerToString((int)t) + " microseconds."); } 2018.06.14 19:23:31.188 SpeedSQRT (EURUSD,M4) Сумма 1 000 000 корней = 1218952.6235881459433586 за 1990 микросекунд 2018.06.14 19:26:30.814 SpeedSQRT (EURUSD,M4) Сумма 1 000 000 корней = 1218952.6235881459433586 за 1946 микросекунд 2018.06.14 19:26:34.188 SpeedSQRT (EURUSD,M4) Сумма 1 000 000 корней = 1218952.6235881459433586 за 1946 микросекунд 2018.06.14 19:26:36.344 SpeedSQRT (EURUSD,M4) Сумма 1 000 000 корней = 1218952.6235881459433586 за 1973 микросекунд
From this speed test we can see that 1 million cycles to calculate sums of roots of binary numbers is executed in 2000 microseconds.
So one cycle is executed in 2 nanoseconds. One cycle is 1 check, two sums of binary numbers, one calculation of the square root of a binary number.
You better be too lazy to write this post. ))
I specifically attached a speed test indicator to these functions.
The Bars function is executed in microseconds, while checks, arithmetic operations(even calculating the square root of a binary number) are less than a nanosecond:
From this speed test we can see that 1 million cycles to calculate sums of roots of binary numbers is executed in 2000 microseconds.
So one cycle is executed in 2 nanoseconds. One cycle is 1 check, two sums of binary numbers, one calculation of the square root of a binary number.
I haven't put new builds yet, so I can't reproduce it. I understand that your function is optimised for a special case, which is represented in your indicator. The symbol doesn't change, the timeframe doesn't change either, etc. That's why, I suppose, the Bars function is called once there, and both the symbol and the timeframe are stupidly set as constants. That's why it's quite possible that the compiler has optimised your whole function, throwing out everything unnecessary.
In short, the tests are incorrect. There should be an array of symbols and an array of periods, and you should run your function over all of them. Then we can talk about something.
I haven't installed new builds yet, so I can't reproduce it. I understand that your function is optimised for a special case, which is represented in your indicator. The symbol doesn't change, the timeframe doesn't change either, etc. Therefore, I suppose, the Bars function is called once. And both the symbol and the timeframe are stupidly set as constants. Therefore, it is quite possible that the compiler has optimised your whole function, throwing out everything unnecessary.
In short, the tests are performed incorrectly. There should be an array of characters and an array of periods. You should run your function through all of them. Then we can talk about something.
None of this is a special case: "The symbol does not change, the timeframe does not change either"!
Why - do you have a lot of such indicators or Expert Advisors, which constantly change TF and symbols?
Of course, you are right. If every call of Bars will be accompanied by a change of TF or symbol, then the standard one will work faster. Although in this case you just need to replace static variables with an array of static variables of the same size as the number of TFs. But I consider this as a special case. But this solution of this special case has a right to live if it is necessary. Perhaps it makes sense to amend the code for such cases. А ... That's probably what you were talking about.
And about constants - thank you for noticing. I corrected it because the parameters in the original function are not constants. Nothing has changed in terms of speed.
Do you have a lot of such indicators or Expert Advisors, which constantly change TFs and symbols?
Well, yes, quite a lot. I am focused on portfolio analysis and portfolio trading. However, when it comes to large calculations, iBarShift is inappropriate there, because we work with arrays. In fact, iBarShift and other similar functions are intended for rare calls.It is irrational to loop them. We just get the array in CopyTime and quickly find everything. That's why the test example is of little use in real practice. Unless the coder is a dummy of course ) And I don't think it's worth bothering for the sake of dummies ).
I think it would be more logical to wrap your function into a class. Then you won't have to check the symbol/period at each call. You will have a separate object for each time series.
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Fast iBarShift and Bars for MT5:
Complete and fast functions similar to Bars and iBarShift from MQL4.
Author: Nikolai Semko