Hilfe bei der Lösung eines Problems auf dem MT5-Terminal.
Ich habe beschlossen, mein Produkt von mql4 auf mql5 zu übertragen.
Sie verwendet Rechtecke, die auf XY-Koordinaten gezeichnet werden.
In MT4 ist es sehr glatt und ohne Ruckeln, wenn man die vertikale Skala ändert, aber in MT5 führt der gleiche Ansatz zu einigen Einfrierungen und spürbarer "Ungeschmeidigkeit".
Ich habe extra einen vereinfachten Prototyp angefertigt, um die Wirkung zu demonstrieren. Das gilt auch für MT4 und MT5. Vergleichen Sie den Unterschied, wenn Sie die vertikale Skala ändern (mit der Maus auf der Preisskala).
In MT5 wird alles ungebremst sein, aber die Neuberechnung ist ruckartig. Je mehr Objekte, desto schlimmer. Aber in MT4 läuft alles glatt.
Ich füge die mq4- und mq5-Quelldateien bei und füge den mq5-Code ein.
Bitte helfen Sie mir, es reibungslos zu gestalten.
Ich möchte verstehen: ist es "so und so" MT5 oder "so und so" mein Code für MT5.
Ich versuche seit Jahren, MQ zu beweisen, dass diese Funktionen nicht asynchron sein sollten, weil die Tabelle mit den Diagrammeigenschaften bereits existiert und es ausreicht, diese Eigenschaften zu übernehmen, und es keinen Sinn hat, einen asynchronen Prozess auszuführen.
Aber alle Bemühungen sind vergeblich.
Das stinkt wirklich nach Idiotie.
Ich weiß, wovon ich spreche, denn ich programmiere in vielen Sprachen, einschließlich Kanvas, und verwende aktiv das ereignisgesteuerte Modell.
Und im prähistorischen MQL4 ist dieses Problem minimal.
Ja, Sie haben 4 asynchrone Funktionen, die 99,76% der Zeit benötigen.
...
Und im prähistorischen MQL4 ist dieses Problem minimal.
Ja, im MT4 fliegt alles.
Wenn Sie nichts dagegen haben, können Sie mir ein Beispiel dafür geben, wie man es besser machen kann?
Ja, im MT4 fliegt alles.
Wenn Sie nichts dagegen haben, können Sie mir ein Beispiel dafür geben, wie man es intelligenter machen kann?
Der kürzeste Weg ist es, meine iCanvas biblio, die nicht auf asynchrone Funktionen in der Schleife verwenden können, zu befestigen.
Sie müssen nicht die Leinwand selbst verwenden. Es wird die ganze Zeit über in Ihrem Horoskop hängen, aber es wird leer und transparent sein.
Wenn eine längere Methode ohne iCanvas, dann müssen Sie es in dieser Bibel wieder nachschlagen, wie es dort implementiert ist, aber es ist nichts für schwache Nerven. :))
Ich werde versuchen, kurz zu erklären, was iCanvas tut.
Es hat einen internen HandlerOnChartEvent, der dasCHARTEVENT_CHART_CHANGE-Ereignis abfängt und seine interne Struktur W füllt, indem er die gleichen asynchronen ChartGet-Funktionen verwendet, dies aber nur einmal beim Auftreten dieses Ereignisses tut.
Dies erlaubt es, die Geschwindigkeit mehr oder weniger zu optimieren.
Auch in dieser Bibliothek hängt ein Canvas-Objekt, das den gesamten Bildschirm ausdehnt und sich anpasst, wenn sich der Bildschirm ändert.
Hier wurden beispielsweise drei Codezeilen hinzugefügt und viele Zeilen gestrichen:
#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); } //+------------------------------------------------------------------+Auf jeden Fall können Sie die Anzahl der Objekte mit diesem Algorithmus erhöhen, ohne dass dies die Leistung allzu sehr beeinträchtigt.
Oder handelt es sich vielleicht nicht um einen Fehler, sondern um eine Funktion? Dort wird etwas mit Grafiken optimiert. Und es funktioniert schlecht, weil es wünschenswert ist, alle Dinge für ihren Zweck zu nutzen. Es gibt spezialisierte grafische Objekte, die an Preiskoordinaten gebunden sind - sie sollten also für diese Aufgabe verwendet werden.
Das dachte ich auch, bis ich mehr Wissen über dieses Thema erlangte.
Der Grund ist eindeutig: zu wenig Denken.
Irgendeine "Behörde" hat am Anfang (vor etwa 10 Jahren) einen Fehler gemacht, und niemand denkt mehr daran, dass er einen Fehler gemacht haben könnte.
https://www.mql5.com/ru/forum/1111/page2780#comment_16886162
Sie scheinen sogar zugestimmt und versprochen zu haben, es zu verbessern, aber nein - es ist vorbei. Sie ist noch da.
https://www.mql5.com/ru/forum/1111/page2781#comment_16904132
Der kürzeste Weg ist, mein iCanvas-Bibblet anzuhängen, wodurch Sie die Verwendung asynchroner Funktionen in der Schleife vermeiden können.
Sie müssen die Leinwand selbst gar nicht verwenden. Es wird die ganze Zeit über in Ihrem Horoskop hängen, aber es wird leer und transparent sein.
Wenn eine längere Methode ohne iCanvas, dann müssen Sie es in dieser Bibel wieder nachschlagen, wie es dort implementiert ist, aber es ist nichts für schwache Nerven. :))
Ich werde versuchen, kurz zu erklären, was iCanvas tut.
Es hat einen internen HandlerOnChartEvent, der dasCHARTEVENT_CHART_CHANGE-Ereignis abfängt und seine interne Struktur W füllt, indem er die gleichen asynchronen ChartGet-Funktionen verwendet, dies aber nur einmal beim Auftreten dieses Ereignisses tut.
Dies erlaubt es, die Geschwindigkeit mehr oder weniger zu optimieren.
Auch in dieser Bibliothek hängt ein Canvas-Objekt, das den gesamten Bildschirm ausdehnt und sich anpasst, wenn sich der Bildschirm ändert.
Hier wurden beispielsweise drei Codezeilen hinzugefügt und viele Zeilen gestrichen:
Vielen Dank für eine ähnliche Lösung des Problems. Die Rendering-Geschwindigkeit hat sich in der Tat erhöht. Sieht aus, als müsste ich die Bibliothek meistern.
Ich möchte auch auf folgende Nuance hinweisen. Es kompiliert mit dieser Formulierung mit einer Warnung:
y = Canvas.Y(price);
Und es kompiliert mit diesem ohne eine Warnung, aber die Geschwindigkeit ist ein bisschen langsamer.
y = (int)Canvas.Y(price);
Was ist richtiger?)
Ich danke Ihnen für diese Art der Problemlösung. Die Rendering-Geschwindigkeit hat sich in der Tat verbessert. Sieht so aus, als müsste ich die Bibliothek lernen.
Ich möchte auch die folgende Nuance klarstellen. Es kompiliert mit dieser Formulierung mit einer Warnung:
Und es kompiliert mit diesem ohne eine Warnung, aber die Geschwindigkeit ist ein bisschen langsamer.
Was ist richtiger?)
Welchen Typ von "y" haben Sie?
denn wenn int und objektiv"die Geschwindigkeit ein wenig sinkt", ist das ein BAG
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Hilfe bei der Lösung eines Problems auf dem MT5-Terminal.
Ich habe beschlossen, mein Produkt von mql4 auf mql5 zu übertragen.
Sie verwendet Rechtecke, die auf XY-Koordinaten gezeichnet werden.
In MT4 ist es sehr glatt und ohne Ruckeln, wenn man die vertikale Skala ändert, aber in MT5 führt der gleiche Ansatz zu einigen Einfrierungen und spürbarer "Ungeschmeidigkeit".
Ich habe extra einen vereinfachten Prototyp angefertigt, um die Wirkung zu demonstrieren. Das gilt auch für MT4 und MT5. Vergleichen Sie den Unterschied, wenn Sie die vertikale Skala ändern (mit der Maus auf der Preisskala).
In MT5 wird alles ungebremst sein, aber die Neuberechnung ist ruckelig. Je mehr Objekte, desto schlimmer. Aber in MT4 läuft alles glatt.
Ich füge die mq4- und mq5-Quelldateien bei und füge den mq5-Code ein.
Bitte helfen Sie mir, es reibungslos zu gestalten.
Ich möchte verstehen: "das ist" MT5 oder "das ist" mein Code für MT5.