Canvas is cool! - page 97

 
Doerk Hilger #:

why is there no structure with all metrics data at once?

Unfortunately, this is almost nowhere: PositionGet*, OrderGet*, HistoryOrderGet*, HistoryDealGet*, SymbolInfoGet*, ChartGet*, ....

It is not possible to get a guaranteed snapshot of open positions/orders, Market Watch snapshot in the trading terminal. MT5...

 
Реter Konow #:
Seconded. I also encountered a delay in CHARTEVENT_CHART_CHANGE events. Also, when switching charts, the standard ChartGetInteger function returns incorrect chart sizes. It happens as follows: when switching the chart, the CHARTEVENT_CHART_CHANGE event comes to the OnChartEvent() function more than once and returns incorrect chart sizes in one of the calls of this function. I will write a code to reproduce it in my spare time.

All you can do is check the chart frequently by yourself, buffer all the data, compare it to the current and fire the event by yourself. I do that every second, and in case the mouse button is down, every 100ms. 
There is no other way out, as long MetaQuotes does not fix that stuff. I bother with that since years and gave up up, that ever anyone will take care. 

 
fxsaber #:

Unfortunately, this is almost nowhere: PositionGet*, OrderGet*, HistoryOrderGet*, HistoryDealGet*, SymbolInfoGet*, ChartGet*, ....

It is not possible to get a guaranteed snapshot of open positions/orders, Market Watch snapshot in the trading terminal. MT5...

Also, yes. It should be the general way anyway. I guess this comes from code-compatibility to MT4 where it all was in one thread once, but makes no sense in MT5 at all. 

 
Doerk Hilger #:

Canvas is cool , but only in theory!

Why? None of the above examples is realistic, because in the code you have to check the chart yourself often, actually every tick, because in many cases CHARTEVENT_CHART_CHANGE is not triggered when the chart changes. One of such cases is the growth of new candles at the very bottom of the chart downwards or at the very top upwards. At this point and in the case of using CCanvas in the chart area, everything becomes invalid, no price matches anymore.

And to maintain accuracy, you need to use ChartGetInteger or ChartGetDouble for max- or min-price and even other chart metric data, every tick. BUT: A single call to this function takes up to a thousand milliseconds. And a bunch of calls naturally takes seconds and just freezes everything.

I don't understand why this thing still hasn't been fixed. Neither the missing events, nor the timing problem. And why for fundamentally important things like graph metrics, which are needed just for visual accuracy, why isn't there a structure with all metrics data at once, if it's a fact that there's a timing problem with every call?

Check this out - six years ago, nobody cares.

https://www.mql5.com/en/forum/326220

Forum on trading, automated trading systems and testing of trading strategies

Errors, bugs, questions

Renat Fatkhullin, 2020.06.14 13:40

Work (Get/Set methods) with the chart in MQL5 programmes is done through the transaction queue.

This allows you to decouple the work of GUI and the terminal itself from the inevitable blocking, which would suit (suit) MQL5 programmes.

Transactional asynchrony allows massively fast writing or reading in separated modes and instantly switches on the synchronisation mode when mixing Set and Get methods.

That is, it's better to do asynchronous Set 1000 times and then Get 1000 times instead of doing alternating Get & Set, turning the queue into a synchronous process. Because you have to make sure that the previous asynchronous Set was overlapped exactly and now you can read it.


You need to use system functions carefully and cache them if possible.

Renat suggested caching the chart parameters yourself.

I consider MQ's reluctance to create cached parameter tables on the user thread side (including for chart parameters) a colossal mistake.

The secret of success of Google's V8 engine lies in the creation of such tables.

As a result, MT5 often looks laggy even for experienced programmers.
 
Nikolai Semko #:

Renat suggested caching the chart parameters yourself.

I consider MQ's reluctance to create cached parameter tables on the user thread side (including for chart parameters) a colossal mistake.

The secret of success of Google's V8 engine lies in the creation of such tables.

As a result, MT5 often looks laggy even for experienced programmers.

Its not the caching, its the verification and validation. Even if its not cached by MQL, it should be invalidated and thus - the CHARTEVENT_CHART_CHANGE is ineviteable. I cannot verify the chart metrics efficiently by myself, that would need a timer at 1ms to frequently check, therefore the  CHARTEVENT_CHART_CHANGE is provided, but it simply does not reflect all changes. Sometimes it also just forgets them. This is a bug, proven and easy to test. 

Besides that: When someone needs the max price, they also need the minimal price and the min-time and max time etc. You never need only one value, you need them all. Therefore a function should be provided, which fills a struct will all data at once. That way it would also be so easy to cache and to find changes. 

Anything else, especially the way it is right now with the missing events, is a pure - and massive - waste of performance. 

Fact. 

Efficient code would be:
ChartMetricsStruct cm;	// Shoud be a datatype of MQL!

OnChartEvent(int id, .....)
        {
        if (id==CHARTEVENT_CHART_CHANGE)
                {
                ChartMetricsStruct cm_new;
		// Missing function of MQL
                ChartGetStruct(chart_id, cm_new);	
                if (cm!=cm_new)
                        {
                        cm=cm_new;
                        // Do whatever is necessary when metrics have changed
                        }
                }
        }
... whereby the current workaround consists of OnTimer(), usage of 20 times of ChartGetDouble() and ChartGetInteger() within the timer, comparing value by value, filling struct by single values etc. Almost 200 lines of code within the timer just figure out if the chart metrics have changed or not. 

Its simply horrible.
 
Is Renat still active in this thread?
 
Friends, I see here is a rare branch where professionals gathered, not amateurs chatting. My question is as follows: I need to create a trading panel that would work in the tester. As you know, MQL5 does not handle OnChartEvent in the tester, unlike the outdated MT4. I searched the market yesterday and almost all TPs have a warning that they don't work in the tester. I thought maybe I could do it not via
<Controls\Dialog.mqh>

but through drawing in Canvas and tracking mouse clicks on coordinates? The idea is raw, so don't kick me too much.

 
Alexey Volchanskiy OnChartEvent in the tester, unlike the outdated MT4. I searched the market yesterday and almost all TPs have a warning that they don't work in the tester. I thought, maybe I can do it not through

but through drawing in Canvas and tracking mouse clicks on the coordinates? The idea is raw, so don't kick me too much.

If you do it through a DLL, it works :-))

but Canvas has nothing to do with it...

PS/ more precisely - it works exactly up to the moments of interactions with the chart. Dialogues of any kind, even in the browser, but it is impossible to interactively move a line on the chart...ChartEvent and everything that is with it is cut off...

 
Alexey Volchanskiy #:

don't kick me too hard.

Based on MT5 there are homemade testers (based on the terminal, not a regular tester), where you can not only press buttons, but also use all indicators, graphical objects and even go back in time and control the price. I.e. the capabilities are far superior to MT4 and solutions outside of the MQ system. Without DLL, of course.

 
Doerk Hilger #:

It's not about caching, it's about verification and validation. Even if MQL does not cache the chart, it must be invalidated, hence CHARTEVENT_CHART_CHANGE is inevitable. I can't effectively check the chart metrics myself, it requires a 1ms timer for frequent checking, so CHARTEVENT_CHART_CHANGE is provided, but it just doesn't reflect all the changes. Sometimes it also just forgets about them. This is a bug, proven and easily tested.

Also: When someone needs the maximum price, they also need the minimum price, the minimum time, the maximum time, etc. You never need just one value, you need all of them. So you need to provide a function that fills struct with all the data at once. This way it will be easy to cache and find changes.

Anything else, especially as it is now, with missing events, is a pure - and huge - waste of performance.

Fact.

Efficient code would be this:

I've had this implemented in the iCanvas library for a long time.

one instance of the Window structure W is automatically populated with each CHARTEVENT_CHART_CHANGE event

struct Window {
   long              ChartId;     // current window identifier
   uint              Color;       // window background color
   int               Width;       // window width
   int               Height;      // window height
   int               height[];    // sub_windows height
   int               Left_bar;    // number of the leftmost bar in the window
   double            Right_bar;   // number of the rightmost bar in the window
   double            Total_bars;  // the maximum number of bars in the window
   int               BarsInWind;  // number of visible bars in the window
   double            Y_min;       // The minimum value of the price in the window
   double            Y_max;       // The maximum value of the price in the window
   double            dy_pix;      // price change for one pixel
   int               dx_pix;      // changing the number of bars per pixel
   int               MouseX;      // coordinate X of the current position of the mouse pointer
   int               MouseY;      // coordinate Y of the current position of the mouse pointer
   double            MouseBar;    // the current bar position of the mouse pointer
   double            MousePrice;  // the current price of the mouse pointer
   datetime          MouseTime;   // the current time of the mouse pointer
   mouse_status      MouseStatus; // 5 values: NO_PRESSED, LEFT_BUTTON_PRESSED,RIGHT_BUTTON_PRESSED, LEFT_AND_RIGHT_BUTTONS_PRESSED, KEY_PRESSED
   int               IdEvent;     // id value of the last event
   long              lparam;      // last lparam
   int               MouseSubWin; // number of the subwindow in which the mouse pointer is located
   int               WindowsTotal;// total subwindows, including the main window
   int               SubWin;      // current subwindow
   int               DPI;         // Screen DPI
   bool              ActiveWin;   // Active window
   bool              ChangeActive;// if true ActiveWin was changed in last CHARTEVENT_CHART_CHANGE
   datetime          time[];      // array of opening time of all visible bars in the window
};