MT5端末の問題解決に役立つ。
mql4からmql5へ製品を移行することにした。
XY座標上に描かれた矩形を使用します。
MT4では、垂直スケールを変更する際にカクカクせず非常にスムーズですが、MT5では同じ方法でフリーズすることがあり、「非スムーズ」さが目立ちます。
その効果を実証するために、特別に簡略化した試作品を作りました。MT4、MT5でも同じです。縦軸の目盛りを変えたときの違いを比べてみてください(価格目盛りの上にマウスを乗せた状態)。
MT5では全てノーブレーキになるが、再描画がぎくしゃくする。オブジェクトが多ければ多いほど、悪い。しかし、MT4ではすべてがスムーズです。
mq4とmq5のソースファイルを添付し、mq5のコードを貼り付けています。
スムーズにできるよう、よろしくお願いします。
私は理解したい:それは "このような" MT5または "このような" MT5用の私のコードです。
ああ、4つの非同期関数が全時間の99.76%を占めているんだな。 ...そして、前時代のMQL4では、この問題は最小です。 。
はい、MT4では何でも飛びます。
もしよろしければ、より良い方法を例として教えていただけませんか?
はい、MT4では何でも飛びます。
差し支えなければ、もっとスマートにできる例を教えてください。
最短の方法は、私のiCanvasのbiblioを添付することで、ループ内で非同期関数を使用しないようにすることです。
キャンバスそのものを使用する必要はありません。ずっとチャートに飾っておくのですが、空っぽで透明なものになります。
iCanvasを使わずにもっと長い方法なら、このバイブルに実装されているので、そこでまた調べる必要がありますが、気の弱い人には無理でしょう。:))
iCanvas が何をするものなのか、簡単に説明したいと思います。
OnChartEventという 内部ハンドラがあり、CHARTEVENT_CHART_CHANGE イベントをキャッチして、同じ非同期ChartGet関数を使って内部構造体をW充填しますが、このイベントの発生時に一度だけ行います。
これによって多少なりとも速度を最適化できます。
このライブラリには、画面全体を広げ、画面が変わるとそれに合わせるCanvasオブジェクトもぶらさがっています。
ここでは、例えば3行のコードが追加され、多くの行が破棄されています。
#property indicator_chart_window #include <Canvas\iCanvas.mqh> //https://www.mql5.com/ru/code/22164 #property indicator_buffers 0 #property indicator_plots 0 string obj_name = "Asd_"; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { if(NewBar()) { DrawObj(); } return(rates_total); } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(id == CHARTEVENT_CHART_CHANGE) { DrawObj(); } } //+------------------------------------------------------------------+ //| Выводим на график | //+------------------------------------------------------------------+ void DrawObj() { string GenName = obj_name; double startPricePos = SymbolInfoDouble(Symbol(),SYMBOL_BID); int step_Pips = 50; for(int i=1; i<=20; i++) { double stp = (step_Pips*i)*SymbolInfoDouble(Symbol(),SYMBOL_POINT); RectLabelCreate(GenName+"UP_"+IntegerToString(i),startPricePos + stp); RectLabelCreate(GenName+"DN_"+IntegerToString(i),startPricePos - stp); } ChartRedraw(0); } //+------------------------------------------------------------------+ //| Создает прямоугольную метку | //+------------------------------------------------------------------+ void RectLabelCreate(string name, // имя метки double price // цена ) { const long chart_ID=0; // ID графика int sub_window=0; // номер подокна int x=0; // координата по оси X int y=0; // координата по оси Y x=W.Width/2; y = Round(Canvas.Y(price)); //x=(int)(ChartGetInteger(chart_ID,CHART_WIDTH_IN_PIXELS,sub_window)/2); //ChartXYToTimePrice(chart_ID,x,y,sub_window,time_pos_X_centr,price_pos_Y_tmp); //ChartTimePriceToXY(chart_ID,sub_window,time_pos_X_centr,price,x,y); const int width=50; // ширина const int height=10; // высота const color back_clr=C'236,233,216'; // цвет фона const ENUM_BORDER_TYPE border=BORDER_SUNKEN; // тип границы const ENUM_BASE_CORNER corner=CORNER_LEFT_UPPER; // угол графика для привязки const color clr=clrRed; // цвет плоской границы (Flat) const ENUM_LINE_STYLE style=STYLE_SOLID; // стиль плоской границы const int line_width=1; // толщина плоской границы const bool back=false; // на заднем плане const bool selection=false; // выделить для перемещений const bool hidden=true; // скрыт в списке объектов const long z_order=0; // приоритет на нажатие мышью if(ObjectCreate(chart_ID,name,OBJ_RECTANGLE_LABEL,sub_window,0,0)) { ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x); ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y); ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width); ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height); ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr); ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_TYPE,border); ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner); ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style); ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,line_width); ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); } else Print(_LastError); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool NewBar() { static int countLastBar=0; int curBars = iBars(Symbol(),PERIOD_CURRENT); bool flg = false; if(countLastBar!=curBars) { countLastBar=curBars; flg=true; } return(flg); } //+------------------------------------------------------------------+いずれにせよ、このアルゴリズムでオブジェクトの数を増やしても、性能にはあまり影響しないでしょう。
それとも、バグではなく、機能なのでしょうか?何かというと、グラフィックが最適化されているのです。そして、すべてのものを本来の目的のために使うことが望ましいので、悪い方向に作用してしまうのです。価格 座標に関連する特殊なグラフィックオブジェクトがあるので、このタスクに使用する必要があります。
理由は明白で、「考え不足」です。
どこかの「権威」が最初(10年くらい前)にミスをしたのですが、今でも誰も「ミスをしたかもしれない」と思っていません。
https://www.mql5.com/ru/forum/1111/page2780#comment_16886162
同意して改善を約束したようにさえ見えますが、いや~終わってますね。まだあるんだ。
https://www.mql5.com/ru/forum/1111/page2781#comment_16904132
最短の方法は、私のiCanvas bibbletを添付することで、ループ内で非同期関数を使わなくて済むようにすることです。
キャンバスそのものを使う必要は全くありません。ずっとチャートに飾っておくのですが、空っぽで透明なものになります。
iCanvasを使わずにもっと長い方法なら、このバイブルに実装されているので、そこでまた調べる必要がありますが、気の弱い人には無理でしょう。:))
iCanvas が何をするものなのか、簡単に説明したいと思います。
OnChartEventという 内部ハンドラがあり、CHARTEVENT_CHART_CHANGE イベントをキャッチして、同じ非同期ChartGet関数を使って内部構造体をW充填しますが、このイベントの発生時に一度だけ行います。
これによって多少なりとも速度を最適化できます。
このライブラリには、画面全体を広げ、画面が変わるとそれに合わせるCanvasオブジェクトもぶらさがっています。
例えば、ここでは3行のコードが追加され、多くの行が破棄されています。
同じような問題を解決してくれてありがとうございました。確かに、描画速度は向上しています。図書館を極めるしかないようだ。
また、次のようなニュアンスで明記したいと思います。この処方でコンパイルすると、警告が出ます。
y = Canvas.Y(price);
で、これだと警告も出ずにコンパイルされますが、速度は少し落ちますね。
y = (int)Canvas.Y(price);
どちらが正しいのでしょうか)
このような形で問題を解決していただき、ありがとうございました。確かに、描画速度は向上しています。図書館の勉強をしなければならないようだ。
また、次のようなニュアンスも明確にしたいと思います。この処方でコンパイルすると、警告が出ます。
で、これだと警告も出ずにコンパイルされますが、速度は少し落ちますね。
何がより正しいのか)
Y "の種類は?
なぜなら、直感的・客観的に「速度が少し落ちる」なら、これはBAGだからです。
![MQL5 - MetaTrader 5クライアントターミナルにビルトインされたトレードストラテジーの言語](https://c.mql5.com/i/registerlandings/logo-2.png)
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索
MT5端末の問題解決に役立つ。
mql4からmql5へ製品を移行することにした。
XY座標上に描かれた矩形を使用します。
MT4では、垂直スケールを変更する際にカクカクせず非常にスムーズですが、MT5では同じ方法でフリーズすることがあり、「非スムーズ」さが目立ちます。
その効果を実証するために、特別に簡略化した試作品を作りました。MT4、MT5でも同じです。縦軸の目盛りを変えたときの違いを比べてみてください(価格目盛りの上にマウスを乗せた状態)。
MT5では全てノーブレーキになるが、再描画がぎくしゃくする。オブジェクトが多ければ多いほど、悪い。しかし、MT4ではすべてがスムーズです。
mq4とmq5のソースファイルを添付し、mq5のコードを貼り付けています。
スムーズにできるよう、よろしくお願いします。
これはMT5です」または「これはMT5用の私のコードです」ということを理解したいのです。