// Fast Analog ChartXYToTimePrice function (https://www.mql5.com/ru/docs/chart_operations/chartxytotimeprice)
int XYToTimePrice(int x,int y,datetime &time,double &price,int id=0) // возвращает номер подокна в котором находится X,Y (курсор), если -1 - то вне окна
{
staticint left_bar; // номер самого левого бара на экранеstaticint Wid;
staticint Hei[10];
staticdouble y_min[10];
staticdouble y_max[10];
staticint PerSec=PeriodSeconds();
staticbool ChartChange=true;
staticint windowsTotal=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
staticint Cur_wind=-1;
staticint WidthBar=int(1<<ChartGetInteger(0,CHART_SCALE));
if(id==CHARTEVENT_CHART_CHANGE) if(!ChartChange) {ChartChange=true; return(Cur_wind);}
if(ChartChange) // если было изменение чатра после последнего вычисления
{
windowsTotal=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
if(windowsTotal>10) {Print("Too many subwindows"); return(-1);}
for(int i=0;i<windowsTotal;i++) if(i>0) Hei[i]=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,i)+Hei[i-1]+2;
else Hei[0]=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0);
left_bar=(int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR, 0); // номер самого левого бара на экране
Wid=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS, 0); // ширина экрана в пикселях
WidthBar=int(1<<ChartGetInteger(0,CHART_SCALE)); // растояние между барами в пикселяхfor(int i=0;i<windowsTotal;i++)
{
y_min[i]=ChartGetDouble(0,CHART_PRICE_MIN, i); // макс. цена на экране
y_max[i]=ChartGetDouble(0,CHART_PRICE_MAX, i); // мин. цена на экране
}
}
if(x>(Wid+1) || x<0 || y<0 || y>=(Hei[windowsTotal-1]+1)) return(-1); // выходим если точка (x,y) за пределами экрана
Cur_wind=-1;
if(y>=0 && y<=Hei[0]) Cur_wind=0;
elseif(windowsTotal>1) for(int i=1;i<windowsTotal;i++) if(y>(Hei[i-1]+1) && y<=Hei[i]) { Cur_wind=i; break; }
if(Cur_wind>=0)
{
if(Cur_wind>0) y=y-Hei[Cur_wind-1]-2;
int hh=Hei[Cur_wind];
if(Cur_wind>0) hh-=Hei[Cur_wind-1]+2;
price=y_min[Cur_wind]+(hh-y)*(y_max[Cur_wind]-y_min[Cur_wind])/hh;
double NrBar=left_bar-(double)x/(double)WidthBar;
datetime TT[2];
if(NrBar>0) { CopyTime(NULL,0,(int)NrBar,2,TT); time=TT[0]+(datetime)((TT[1]-TT[0])*(1.0-NrBar+(int)NrBar)); }
else { CopyTime(NULL,0,0,1,TT); time=TT[0]+(datetime)(fabs(NrBar)*PerSec); }
}
ChartChange=false;
return(Cur_wind);
}
CopyTicks的一个变种,它有时比原来的速度快几个数量级(从>0)。
Build 1432--CopyTicks的替代方案已不再适用。
1432号文件是怎么来的?我在MetaQuotes-Demo上有最新的1430号文件
1432号文件是怎么来的?我在MetaQuotes-Demo上得到了最后的1430。
他是通过贿赂得到的...
你不应该笑。我曾经得到过一个。
你不应该笑。我曾经得到过一个。
你怎么会认为我在笑?
关于交易、自动交易系统和交易策略测试的论坛
mql5语言的特点、微妙之处以及技巧
fxsaber, 2018.04.16 13:23
这个选项快得多(发布,而不是调试)。
当解析大量的数据时,你会得到一个显著的速度提升。
我们回到了将大量简单的系统函数原生嵌入到所产生的MQL5代码中的想法,这使我们能够通过在所产生的代码的全局优化中使用这些函数来加快它们的速度。
好的。
好的。
欢迎回来!
ChartXYToTimePrice 模拟
它不是完全的模拟(就参数而言),但这种变体在我看来甚至更方便和实用。它的速度也更快(几个数量级的速度)。
从功能上看,它是完全类似的,甚至更多,因为它返回(与原函数不同)子窗口号码,其中有X,Y(光标),如果-1,则在窗口(子窗口)之外。
这个类似物不包含输入参数chart_id 和sub_window,因为我看不出这个函数怎么能在当前窗口之外使用。此外,sub_window 参数甚至不清楚,因为不管它的值是多少,原函数的操作方式完全相同。
这个函数可以在没有id参数的情况下在任何地方运行,但它必须总是出现在OnChartEvent中(有id参数),以便明确更新这个函数的内部变量的必要性。
例如,如果该函数不是从OnChartEvent中使用,必须在OnChartEvent主体中添加一行才能正常工作。
当这个功能被经常使用时,这种模拟会带来明显的好处。在一次性应用中使用这种类似物是没有意义的。