// 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);
}
この関数は id パラメータがなくてもどこでも実行できますが、この関数の内部変数を更新する必要性を明確にするため、OnChartEvent には必ず(id パラメータがある)存在しなければなりません。
CopyTicks の亜種で、オリジナルより数桁速いこともある (from > 0)
Build 1432 - CopyTicksの代替はもう意味がありません。
1432はどこから来たのか?MetaQuotes-Demoで最新の1430を持っています。
1432はどこから来たのか?MetaQuotes-Demoで最後の1430を取得しました。
賄賂で手に入れたのだから...。
笑っちゃいけない。一度、手に入れたことがあるんです。
笑っちゃいけない。一度いただいたことがあります。
なんで俺が笑ってると思う?
トレーディング、自動売買システム、トレーディング戦略のテストに関するフォーラム
mql5言語の特徴、微妙なニュアンスとコツ
fxsaber さん 2018.04.16 13:23
このオプションは非常に高速 です。
大量のデータを解析する場合、大幅なスピードアップが得られます。
私たちは、大量のシンプルなシステム関数を、結果として得られるMQL5のコードにネイティブに埋め込むというアイデアに立ち返り、それを結果としてのコードの全体最適に利用することで、何倍ものスピードアップを実現したのです。
OKです。
OKです。
お帰りなさい
ChartXYToTimePrice アナログ
完全なアナログ(パラメータ)ではないのですが、このバリエーションはさらに便利で実用的なように思います。また、速度も(2桁ほど)速くなりました。
機能的には完全なアナログで、さらに、(元の関数と違って)X, Y(カーソル)のあるサブウィンドウの番号を返し、もし-1ならウィンドウ(サブウィンドウ)の外側を返します。
このアナログは、入力パラメータchart_id とsub_window を含んでいないため、この関数が現在のウィンドウの外でどのように使用されるかがわかりません。また、sub_window パラメータは、その値に関係なく、元の関数が全く同じように動作するため、さらに不明確である。
この関数は id パラメータがなくてもどこでも実行できますが、この関数の内部変数を更新する必要性を明確にするため、OnChartEvent には必ず(id パラメータがある)存在しなければなりません。
例えば、OnChartEvent からこの関数を使用しない場合、OnChartEvent 本体に行を追加しないと正常に動作しません。
このアナログは、この機能を頻繁に使用する場合に顕著な効果を発揮します。このアナログを単発のアプリケーションに使う意味はない。