Function of X to time, Y to price and vice versa - Script for MetaTrader 5 - MT4/MT5 Resources
The standard API functions ChartXYToTimePrice and ChartTimePriceToXY have obvious shortcomings. For example, ChartXYToTimePrice works correctly only if the input parameters are ChartXYToTimePrice and X and Y are within the visible area of the chart window, outside the window the function returns zero. ChartTimePriceToXY also doesn't work properly in some cases. Both functions are very slow.
I introduced the function that works fine in all input parameter ranges:
Integer Get X( datetimetime ) from time { Integer number of pixels per bar = ( integer ) chart gets integer ( 0 , CHART_WIDTH_IN_PIXELS ) / ( integer ) chart gets integer ( 0 , CHART_WIDTH_IN_BARS ) + 1 ; Double pixels per time = ( double ) pixels_per_bar / period seconds (); integer first bar = ( integer ) chart getinteger ( 0 , CHART_FIRST_VISIBLE_BAR ); datetimetime_first_column = lovetime ( symbol (), period (),first_bar); DateTimeTime_0 = LoveTime ( symbol (), Period (), 0 ); if (time<=time_0) { integer nearestbar = iBarShift ( symbol (), period (), time); datetime nearest time bar = lovetime ( symbol (), period (), nearest_bar); Date time time_remaining = time - time_nearest_bar; time remaining -= ( integer ) math floor (time remaining/ cycleseconds ()) * cycleseconds (); return (first column - nearest column) * number of pixels per column + ( integer ) math wheel (time remaining * number of pixels per time); } Else returns first column * number of pixels per column + ( integer ) math wheel ((time - time_0) *pixels_per_time); } //+------------------------------------------------------------------+ Integer gets Y from price ( double the price) { Double Maximum Price = ChartGetDouble ( 0 , CHART_PRICE_MAX ); double minimum price = chartgetDouble ( 0 , CHART_PRICE_MIN ); Double pixels per price = CHART GET INTEGER ( 0 , CHART_HEIGHT_IN_PIXELS ) / (MAXPrice - MinimumPrice); Return ( integer ) math wheel ((maxprice - price) * pixels per price); } //+------------------------------------------------------------------+ DateTime Get time from X ( integer x_distance) { integer first bar = ( integer ) chart getinteger ( 0 , CHART_FIRST_VISIBLE_BAR ); datetimetime_first_column = lovetime ( symbol (), period (),first_bar); Integer number of pixels per bar = ( integer ) chart gets integer ( 0 , CHART_WIDTH_IN_PIXELS ) / ( integer ) chart gets integer ( 0 , CHART_WIDTH_IN_BARS ) + 1 ; Double the time per pixel = ( double ) period seconds ()/pixels_per_bar; Date and time remaining time = ( integer )((( double )x_dist / number of pixels per strip - ( integer )(x_dist / number of pixels per strip)) * number of pixels per strip * time per pixel); Integer nearest column = first column - ( integer )(x_dist / number of pixels per bar); Date time time_nearest_bar = {}; if (nearest column < 0 ) { datetimetime_0 =When in love(="functions">symbol(), period (), 0 ); datetime delta_time_start = time_0 - time_first_bar; datetime delta timestop = ( 0 - nearest_bar) * period seconds (); time_nearest_bar = time_first_bar + delta_time_start + delta_time_stop; } else nearest timebar = lovetime ( symbol (), period (), nearest_bar); return time_nearest_bar + time_remaining; } //+------------------------------------------------------------------+ double get price from Y ( integer y_distance) { double price per pixel = ( chart get double ( 0 , CHART_PRICE_MAX ) -- chart get double ( 0 , CHART_PRICE_MIN )) / chart get integer ( 0 , CHART_HEIGHT_IN_PIXELS ); double maximum price = chart get double ( 0 , CHART_PRICE_MAX ); return maximum price - price per pixel * y_dist; } //+--------------------------------------------------------------------------------+
A script that demonstrates the correct working of the function. The essence of its work is to convert the generated X and Y coordinates into time and price, and then return X and Y. If the input X and Y coordinates are different from the output, it means there is a problem with the function and the script will print the difference. If all goes well, the script won't print anything while it's working, but at the end it will print the result
blank start () { Integer Generation_total = {}; integer_bias_total = {}; Unit time start script = get tick number (); Although (! stop ()) { integer x_input = 16383 - math rand (); integer y_input = 16383 - math rand (); Integer first column_download = terminal information integer ( TERMINAL_MAXBARS )-- 1 ; Date time time_first_bar_downloaded = love time ( symbol (), period (), first_bar_downloaded); double maximum price start = chart getDouble ( 0 , CHART_PRICE_MAX ); DoubleMinimumStartPrice = ChartGetDouble ( 0 , CHART_PRICE_MIN ); Integer first bar start = ( integer ) Chart Get Integer ( 0 , CHART_FIRST_VISIBLE_BAR ); Integer ChartScaleStart = ( Integer ) ChartGetInteger ( 0 , CHART_SCALE ); Integer x_0 = GetXFromTime(time_first_bar_downloaded); Integer y_0 = GetYFromPrice( 0 ); if (x_input < x_0) x_input = x_0; if (y_input > y_0) y_input = y_0; DateTimeTime = GetTimeFromX(x_input); Double price = GetPriceFromY(y_input); Integer x_output = GetXFromTime(time); Integer y_output = GetYFromPrice(price); DOUBLE PRICE_MAX_STOP = CHART GET DOUBLE ( 0 , CHART_PRICE_MAX ); Double the minimum stop price = ChartGetDouble ( 0 , CHART_PRICE_MIN ); integer first bar stop = ( integer ) chart getinteger ( 0 , CHART_FIRST_VISIBLE_BAR ); integer ChartScaleStop = ( Integer ) ChartGetInteger ( 0 , CHART_SCALE ); if (price_max_start ==price_max_stop &&price_min_start ==price_min_stop &&first_bar_start ==first_bar_stop &&chart_scale_start ==chart_scale_stop) // Check that the scale and position of the chart does not change when coordinates are transferred from one system to another and back { ++ algebra total; if (x_input!= x_output || y_input!= y_output) { ++bias_total; print ( "!!!Deviation detected!!!" ); print ( "x_input=" , x_input, "y_input=" , y_input); print ( "x_out=" , x_out, "y_out=" , y_out); } } } print ( "Test is over" , deviation_total, "deviation" ); if (bias_total == 0 ) print ( "everything is fine" ); print ( "total generations =" , generations_total); Integer algebra rate = total number of algebras / (( double )( get number of ticks () - time_start_script) / 1000 ); print ( "generation rate = " , generation rate , "generations/second" ); } //+------------------------------------------------------------------+ > Integer getX from time ( datetimetime ) { integer pixels per bar = ( integer ) chart get integer ( 0 , CHART_WIDTH_IN_PIXELS ) / ( integer ) chart get integer ( 0 , CHART_WIDTH_IN_BARS ) + 1 ; double pixels per time = ( double )pixels_per_bar/ period seconds (); integer first bar = ( integer ) Chart GetInteger ( 0 , CHART_FIRST_VISIBLE_BAR ); datetimetime_first_bar = iBarShift ( symbol (), period (), first_bar); datetimetime_0 = lovetime ( symbol (), period (), 0 ); if (time <= time_0) { integer nearest column = iBarShift ( symbol (), period (), first_bar), time); datetime nearest_bar = lovetime ( symbol (), period (), nearest_bar); datetime time_remaining = time - time_nearest_bar; remaining time - = ( integer ) math floor (time remaining/ period seconds ()) * period seconds (); return (first column - nearest column) * number of pixels per bar + ( integer ) math wheel (remaining time * number of pixels per time); } else return first column * Number of pixels per bar + ( integer ) math wheel ((time - time_0) *pixels_per_time); } //+------------------------------------------------------------------+ integer get Y from price ( double the price) { double the highest price = chart gets double (0 , CHART_PRICE_MAX ); double the lowest price = chart gets double ( 0 , CHART_PRICE_MIN ); double the pixels per price = chart gets integer ( 0) , CHART_HEIGHT_IN_PIXELS ) / (max_price - min_price); return ( integer ) math wheel (( max_price - price ) * pixels per price ); } //+----------------------------------------------------------------------------------+ DateTime Get time from ); date time time_first_bar = love time ( symbol (), period (), first_bar); integer number of pixels per bar = ( integer ) chart get integer ( 0 , CHART_WIDTH_IN_PIXELS ) / ( integer ) chart get integer ( 0 , CHART_WIDTH_IN_BARS ) + 1 ; double time per pixel = ( double ) period seconds ()/pixels_per_bar; datetime remaining time = ( integer )((( double )x_dist / pixels per bar - ( integer )(x_dist / pixels per bar)) * pixels per bar * time per pixel); integer nearest bar = first bar - ( integer )(x_dist / pixels per bar); datetime time_nearest_bar = {}; if (nearest bar < 0 ) { datetimetime_0 =When in love( symbol (),nctions">time(), 0 ); datetime delta_time_start = time_0 - time_first_bar; datetime delta timestop = ( 0 - nearest_bar) * period seconds (); time_nearest_bar = time_first_bar + delta_time_start + delta_time_stop; } else nearest timebar = lovetime ( symbol (), time (),nearest_bar); return time_nearest_bar + time_remaining; } //+------------------------------------------------------------------+ double get price from Y ( integer y_distance) { double price per pixel = ( chart get double ( 0 , CHART_PRICE_MAX ) -- chart get double ( 0 , CHART_PRICE_MIN ))) / chart get integer ( 0 , CHART_HEIGHT_IN_PIXELS ); double maximum price = chart get double ( 0 , CHART_HEIGHT_IN_PIXELS ); CHART_PRICE_MAX ); Return maximum price - price per pixel * y_dist; } //+----------------------------------------------------------------------------------+
Source code written during the development of the library for creating multi-currency Expert Advisors combining multiple instances of different trading strategies.
This indicator allows you to estimate the probability of the price reaching a maximum or minimum.
DeltaFusion Lite is a simplified version of the MT4 DeltaFusionPro indicator. It calculates and displays cumulative delta and net delta, allowing traders to clearly understand the buying and selling pressure within each candle. By analyzing the volume distribution between bid and ask prices, it helps identify changes in market sentiment, potential reversals, and various types of divergences between price and volume.
Example of adding a button for an advisor. In this example, a button has been implemented to close all active positions for all instruments. In addition to the button event handling function, a method for closing positions relative to the symbol name and a method for calculating the position quantity relative to the symbol name are also implemented.
Attachment download
📎 check_coord_conversion.mq5 (11.17 KB)
Source: MQL5 #48325
💡 Featured Recommendations
✍️ Latest by the author
- •
- •
- •
- •
- •
- •
📌 Popular topics
- •
- •
- •
- •
- •
- •
- •
- •
🔗 You May Be Interested In
- •
- •
- •
- •
- •
- •