Aiuta a risolvere un problema sul terminale MT5.
Ho deciso di trasferire il mio prodotto da mql4 a mql5.
Utilizza rettangoli che sono disegnati su coordinate XY.
In MT4 è molto fluido e senza scatti quando si cambia la scala verticale, ma in MT5 lo stesso approccio porta ad alcuni blocchi e una notevole "non fluidità".
Ho fatto appositamente un prototipo semplificato per dimostrare l'effetto. È lo stesso per MT4 e MT5. Confronta la differenza quando cambi la scala verticale (con il mouse sulla scala dei prezzi).
In MT5 tutto sarà senza freni, ma il ridisegno è a scatti. Più oggetti ci sono, peggio è. Ma in MT4 tutto è liscio.
Allego i file sorgente mq4 e mq5 e incollo il codice mq5.
Per favore, aiutatemi a renderlo fluido.
Voglio capire: è "tale e quale" MT5 o "tale e quale" il mio codice per MT5.
Ho cercato di dimostrare a MQ per anni che queste funzioni non dovrebbero essere asincrone, perché la tabella delle proprietà del grafico esiste già ed è sufficiente prendere quelle proprietà e non ha senso eseguire un processo asincrono.
Ma tutti gli sforzi sono vani.
Questo puzza davvero di idiozia.
So di cosa sto parlando, perché sto programmando in molti linguaggi tra cui Kanvas e utilizzando attivamente il modello event-driven.
E nel preistorico MQL4 questo problema è minimo.
Sì, hai 4 funzioni asincrone che impiegano il 99,76% del tempo.
...
E nel preistorico MQL4 questo problema è minimo.
Sì, tutto vola in MT4.
Se non ti dispiace, puoi darmi un esempio di come farlo meglio?
Sì, tutto vola in MT4.
Se non ti dispiace, puoi farmi un esempio di come farlo in modo più intelligente?
La via più breve è quella di allegare il mio iCanvas biblio, che permetterà di non usare funzioni asincrone in loop.
Non c'è bisogno di usare la tela stessa. Sarà appeso nel tuo grafico per tutto il tempo, ma sarà vuoto e trasparente.
Se un metodo più lungo senza usare iCanvas, allora dovrete cercarlo di nuovo in questa bibbia, poiché è implementato lì, ma non è per i deboli di cuore. :))
Cercherò di spiegare brevemente cosa fa iCanvas.
Ha un gestore internoOnChartEvent, che cattura l'eventoCHARTEVENT_CHART_CHANGE e riempie la sua struttura interna W, usando tutte le stesse funzioni asincrone ChartGet, ma lo fa solo una volta al verificarsi di questo evento.
Questo permette più o meno di ottimizzare la velocità.
Anche in questa libreria è appeso l'oggetto Canvas, che estende l'intero schermo e si adatta ad esso quando lo schermo cambia.
Qui, per esempio, sono state aggiunte tre linee di codice e molte linee sono state scartate:
#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); } //+------------------------------------------------------------------+In ogni caso, è possibile aumentare il numero di oggetti con questo algoritmo e non influenzerà troppo le prestazioni.
O forse non è un bug ma una caratteristica? C'è qualcosa di ottimizzato con la grafica. E funziona male perché è auspicabile utilizzare tutte le cose per il loro scopo. Ci sono oggetti grafici specializzati che sono legati alle coordinate dei prezzi - quindi dovrebbero essere usati per questo compito.
Lo pensavo anch'io, finché non ho acquisito maggiori conoscenze sull'argomento.
La ragione è inequivocabile - il sottopensiero.
Qualche "autorità" ha commesso un errore all'inizio (circa 10 anni fa) e nessuno pensa ancora che possa aver commesso un errore.
https://www.mql5.com/ru/forum/1111/page2780#comment_16886162
Sembra persino che siano stati d'accordo e abbiano promesso di migliorarlo, ma no - è finita. È ancora lì.
https://www.mql5.com/ru/forum/1111/page2781#comment_16904132
Il modo più breve è quello di allegare il mio iCanvas bibblet, che vi permetterà di evitare l'uso di funzioni asincrone nel ciclo.
Non c'è bisogno di usare la tela stessa. Sarà appeso nel tuo grafico per tutto il tempo, ma sarà vuoto e trasparente.
Se un modo più lungo senza usare iCanvas, allora dovrete cercarlo di nuovo in questa bibbia, poiché è implementato lì, ma non è per i deboli di cuore. :))
Cercherò di spiegare brevemente cosa fa iCanvas.
Ha un gestore internoOnChartEvent, che cattura l'eventoCHARTEVENT_CHART_CHANGE e riempie la sua struttura interna W, usando tutte le stesse funzioni asincrone ChartGet, ma lo fa solo una volta al verificarsi di questo evento.
Questo permette più o meno di ottimizzare la velocità.
Anche in questa libreria è appeso l'oggetto Canvas, che estende l'intero schermo e si adatta ad esso quando lo schermo cambia.
Qui, per esempio, sono state aggiunte tre linee di codice e molte linee sono state scartate:
Grazie per una soluzione simile al problema. In effetti, la velocità di rendering è aumentata. Sembra che dovrò padroneggiare la biblioteca.
Vorrei anche specificare la seguente sfumatura. Si compila con questa formulazione con un avvertimento:
y = Canvas.Y(price);
E si compila con questo senza un avvertimento, ma la velocità è un po' più lenta.
y = (int)Canvas.Y(price);
Cosa è più corretto?).
Grazie per questo tipo di soluzione al problema. In effetti, la velocità di rendering è migliorata. Sembra che dovrò imparare la biblioteca.
Vorrei anche chiarire la seguente sfumatura. Si compila con questa formulazione con un avvertimento:
E si compila con questo senza un avvertimento, ma la velocità è un po' più lenta.
Cos'è più corretto?)
Che tipo di "y" avete?
perché se int e oggettivamente"la velocità scende un po'" questa è una BORSA
- App di trading gratuite
- Oltre 8.000 segnali per il copy trading
- Notizie economiche per esplorare i mercati finanziari
Accetti la politica del sito e le condizioni d’uso
Aiuta a risolvere un problema sul terminale MT5.
Ho deciso di trasferire il mio prodotto da mql4 a mql5.
Utilizza rettangoli che sono disegnati su coordinate XY.
In MT4 è molto fluido e senza scatti quando si cambia la scala verticale, ma in MT5 lo stesso approccio porta ad alcuni blocchi e una notevole "non fluidità".
Ho fatto appositamente un prototipo semplificato per dimostrare l'effetto. È lo stesso per MT4 e MT5. Confronta la differenza quando cambi la scala verticale (con il mouse sulla scala dei prezzi).
In MT5 tutto sarà senza freni, ma il ridisegno è a scatti. Più oggetti ci sono, peggio è. Ma in MT4 tutto è liscio.
Allego i file sorgente mq4 e mq5 e incollo il codice mq5.
Per favore, aiutatemi a renderlo fluido.
Voglio capire: "questo è" MT5 o "questo è" il mio codice per MT5.