Participe de nossa página de fãs
Coloque um link para ele, e permita que outras pessoas também o avaliem
Avalie seu funcionamento no terminal MetaTrader 5
- Visualizações:
- 70
- Avaliação:
- Publicado:
-
Precisa de um robô ou indicador baseado nesse código? Solicite-o no Freelance Ir para Freelance
As funções padrão da API ChartXYToTimePrice e ChartTimePriceToXY têm desvantagens significativas. Por exemplo, ChartXYToTimePrice funciona corretamente somente se os parâmetros de entrada X e Y estiverem na área visível da janela do gráfico; fora da janela, a função retorna zeros. ChartTimePriceToXY também funciona incorretamente em alguns casos. Ambas as funções são lentas.
Apresento as funções que funcionam corretamente em todos os intervalos de parâmetros de entrada:
int GetXFromTime(datetime time) { int pixels_per_bar = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) / (int)ChartGetInteger(0, CHART_WIDTH_IN_BARS) + 1; double pixels_per_time = (double)pixels_per_bar / PeriodSeconds(); int first_bar = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR); datetime time_first_bar = iTime(Symbol(), Period(), first_bar); datetime time_0 = iTime(Symbol(), Period(), 0); if(time <= time_0) { int nearest_bar = iBarShift(Symbol(), Period(), time); datetime time_nearest_bar = iTime(Symbol(), Period(), nearest_bar); datetime time_remaining = time - time_nearest_bar; time_remaining -= (int)MathFloor(time_remaining / PeriodSeconds()) * PeriodSeconds(); return (first_bar - nearest_bar) * pixels_per_bar + (int)MathRound(time_remaining * pixels_per_time); } else return first_bar * pixels_per_bar + (int)MathRound((time - time_0) * pixels_per_time); } //+------------------------------------------------------------------+ int GetYFromPrice(double price) { double price_max = ChartGetDouble(0, CHART_PRICE_MAX); double price_min = ChartGetDouble(0, CHART_PRICE_MIN); double pixels_per_price = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS) / (price_max - price_min); return (int)MathRound((price_max - price) * pixels_per_price); } //+------------------------------------------------------------------+ datetime GetTimeFromX(int x_dist) { int first_bar = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR); datetime time_first_bar = iTime(Symbol(), Period(), first_bar); int pixels_per_bar = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) / (int)ChartGetInteger(0, CHART_WIDTH_IN_BARS) + 1; double time_per_pixel = (double)PeriodSeconds() / pixels_per_bar; datetime time_remaining = (int)(((double)x_dist / pixels_per_bar - (int)(x_dist / pixels_per_bar)) * pixels_per_bar * time_per_pixel); int nearest_bar = first_bar - (int)(x_dist / pixels_per_bar); datetime time_nearest_bar = {}; if(nearest_bar < 0) { datetime time_0 = iTime(Symbol(), Period(), 0); datetime delta_time_start = time_0 - time_first_bar; datetime delta_time_stop = (0 - nearest_bar) * PeriodSeconds(); time_nearest_bar = time_first_bar + delta_time_start + delta_time_stop; } else time_nearest_bar = iTime(Symbol(), Period(), nearest_bar); return time_nearest_bar + time_remaining; } //+------------------------------------------------------------------+ double GetPriceFromY(int y_dist) { double price_per_pixel = (ChartGetDouble(0, CHART_PRICE_MAX) - ChartGetDouble(0, CHART_PRICE_MIN)) / ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS); double price_max = ChartGetDouble(0, CHART_PRICE_MAX); return price_max - price_per_pixel * y_dist; } //+------------------------------------------------------------------+
Um script que demonstra a exatidão do trabalho das funções. A essência de seu trabalho é que as coordenadas X e Y geradas são convertidas em tempo e preço e, em seguida, novamente em X e Y. Se as coordenadas X e Y de entrada forem diferentes das de saída, isso significa que as funções têm problemas e o script imprimirá a discrepância. Se tudo estiver bem, o script não imprimirá nada durante o trabalho, mas, no final, imprimirá o resultado
void OnStart() { int generations_total = {}; int deviations_total = {}; uint time_start_script = GetTickCount(); while(!IsStopped()) { int x_input = 16383 - MathRand(); int y_input = 16383 - MathRand(); int first_bar_downloaded = TerminalInfoInteger(TERMINAL_MAXBARS) - 1; datetime time_first_bar_downloaded = iTime(Symbol(), Period(), first_bar_downloaded); double price_max_start = ChartGetDouble(0, CHART_PRICE_MAX); double price_min_start = ChartGetDouble(0, CHART_PRICE_MIN); int first_bar_start = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR); int chart_scale_start = (int)ChartGetInteger(0, CHART_SCALE); int x_0 = GetXFromTime(time_first_bar_downloaded); int y_0 = GetYFromPrice(0); if(x_input < x_0) x_input = x_0; if(y_input > y_0) y_input = y_0; datetime time = GetTimeFromX(x_input); double price = GetPriceFromY(y_input); int x_output = GetXFromTime(time); int y_output = GetYFromPrice(price); double price_max_stop = ChartGetDouble(0, CHART_PRICE_MAX); double price_min_stop = ChartGetDouble(0, CHART_PRICE_MIN); int first_bar_stop = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR); int chart_scale_stop = (int)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)//verifique se, no momento da transferência de coordenadas de um sistema para outro e vice-versa, a escala e a posição do gráfico não mudam { ++generations_total; if(x_input != x_output || y_input != y_output) { ++deviations_total; Print("!!! deviation detected !!!"); Print("x_input= ", x_input, " y_input= ", y_input); Print("x_output= ", x_output, " y_output= ", y_output); } } } Print("Test ended up with ", deviations_total, " deviations"); if(deviations_total == 0) Print("Everything is Ok"); Print("generations_total= ", generations_total); int generations_rate = generations_total / ((double)(GetTickCount() - time_start_script) / 1000); Print("generations rate= ", generations_rate, " generations / sec"); } //+------------------------------------------------------------------+ int GetXFromTime(datetime time) { int pixels_per_bar = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) / (int)ChartGetInteger(0, CHART_WIDTH_IN_BARS) + 1; double pixels_per_time = (double)pixels_per_bar / PeriodSeconds(); int first_bar = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR); datetime time_first_bar = iTime(Symbol(), Period(), first_bar); datetime time_0 = iTime(Symbol(), Period(), 0); if(time <= time_0) { int nearest_bar = iBarShift(Symbol(), Period(), time); datetime time_nearest_bar = iTime(Symbol(), Period(), nearest_bar); datetime time_remaining = time - time_nearest_bar; time_remaining -= (int)MathFloor(time_remaining / PeriodSeconds()) * PeriodSeconds(); return (first_bar - nearest_bar) * pixels_per_bar + (int)MathRound(time_remaining * pixels_per_time); } else return first_bar * pixels_per_bar + (int)MathRound((time - time_0) * pixels_per_time); } //+------------------------------------------------------------------+ int GetYFromPrice(double price) { double price_max = ChartGetDouble(0, CHART_PRICE_MAX); double price_min = ChartGetDouble(0, CHART_PRICE_MIN); double pixels_per_price = ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS) / (price_max - price_min); return (int)MathRound((price_max - price) * pixels_per_price); } //+------------------------------------------------------------------+ datetime GetTimeFromX(int x_dist) { int first_bar = (int)ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR); datetime time_first_bar = iTime(Symbol(), Period(), first_bar); int pixels_per_bar = (int)ChartGetInteger(0, CHART_WIDTH_IN_PIXELS) / (int)ChartGetInteger(0, CHART_WIDTH_IN_BARS) + 1; double time_per_pixel = (double)PeriodSeconds() / pixels_per_bar; datetime time_remaining = (int)(((double)x_dist / pixels_per_bar - (int)(x_dist / pixels_per_bar)) * pixels_per_bar * time_per_pixel); int nearest_bar = first_bar - (int)(x_dist / pixels_per_bar); datetime time_nearest_bar = {}; if(nearest_bar < 0) { datetime time_0 = iTime(Symbol(), Period(), 0); datetime delta_time_start = time_0 - time_first_bar; datetime delta_time_stop = (0 - nearest_bar) * PeriodSeconds(); time_nearest_bar = time_first_bar + delta_time_start + delta_time_stop; } else time_nearest_bar = iTime(Symbol(), Period(), nearest_bar); return time_nearest_bar + time_remaining; } //+------------------------------------------------------------------+ double GetPriceFromY(int y_dist) { double price_per_pixel = (ChartGetDouble(0, CHART_PRICE_MAX) - ChartGetDouble(0, CHART_PRICE_MIN)) / ChartGetInteger(0, CHART_HEIGHT_IN_PIXELS); double price_max = ChartGetDouble(0, CHART_PRICE_MAX); return price_max - price_per_pixel * y_dist; } //+------------------------------------------------------------------+
Traduzido do russo pela MetaQuotes Ltd.
Publicação original: https://www.mql5.com/ru/code/48325
Desenvolvimento do Expert Advisor Multimoedas - códigos-fonte da série de artigos
Códigos-fonte escritos no processo de desenvolvimento de uma biblioteca para a criação de Expert Advisors em várias moedas, combinando várias instâncias de diferentes estratégias de negociação.
Desenvolvimento de um Expert Advisor multimoeda - códigos-fonte de uma série de artigos
Os códigos-fonte escritos durante o desenvolvimento da biblioteca para a criação de Expert Advisors em várias moedas que combinam muitas instâncias de várias estratégias de negociação.
Simple Bar Timer
É um script para exibir o tempo restante até a chegada da próxima barra.
TimeGMT library for the strategy tester
Classe estática para corrigir a função TimeGMT() durante o teste no testador de estratégias.