Guarda come scaricare robot di trading gratuitamente
Ci trovi su Telegram!
Unisciti alla nostra fan page
Script interessante?
Pubblica il link!
lasciare che altri lo valutino
Ti è piaciuto lo script? Provalo nel Terminale MetaTrader 5
Script

Funzioni per X al tempo, Y al prezzo e viceversa - script per MetaTrader 5

Visualizzazioni:
60
Valutazioni:
(4)
Pubblicato:
Freelance MQL5 Hai bisogno di un robot o indicatore basato su questo codice? Ordinalo su Freelance Vai a Freelance

Le funzioni API standard ChartXYToTimePrice e ChartTimePriceToXY presentano notevoli inconvenienti. Ad esempio, ChartXYToTimePrice funziona correttamente solo se i parametri di input X e Y si trovano nell'area visibile della finestra del grafico; al di fuori della finestra la funzione restituisce degli zeri. Anche ChartTimePriceToXY funziona in modo errato in alcuni casi. Entrambe le funzioni sono lente.

Vi presento le funzioni che funzionano correttamente in tutti gli intervalli di parametri di input:

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;
  }
//+------------------------------------------------------------------+

Uno script che dimostra la correttezza del lavoro delle funzioni. L'essenza del suo lavoro consiste nel fatto che le coordinate X e Y generate vengono convertite in tempo e prezzo, e poi nuovamente in X e Y. Se le coordinate X e Y in ingresso differiscono da quelle in uscita, significa che le funzioni hanno dei problemi e lo script stamperà la discrepanza. Se tutto va bene, lo script non stampa nulla durante il lavoro, ma alla fine stamperà il risultato

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)//verificare che al momento del trasferimento delle coordinate da un sistema all'altro e viceversa, la scala e la posizione del grafico non cambino.
        {
         ++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;
  }
//+------------------------------------------------------------------+


    Tradotto dal russo da MetaQuotes Ltd.
    Codice originale https://www.mql5.com/ru/code/48325

    Sviluppo di un Expert Advisor multicurrency - codici sorgente della serie di articoli Sviluppo di un Expert Advisor multicurrency - codici sorgente della serie di articoli

    Codici sorgenti scritti durante il processo di sviluppo di una libreria per la creazione di Expert Advisor multivaluta che combinano istanze multiple di diverse strategie di trading.

    AutoNK AutoNK

    Indicatore che crea un canale inclinato e consente un'ulteriore regolazione con regolazione automatica.

    DeltaFusionLite DeltaFusionLite

    DeltaFusion Lite è la versione semplificata dell’indicatore DeltaFusionPro per MT4. Calcola e visualizza Cumulative Delta e Net Delta, offrendo ai trader una chiara panoramica della pressione di acquisto e vendita all’interno di ogni candela. Analizzando la distribuzione del volume tra bid e ask, aiuta a individuare cambiamenti nel sentiment di mercato, possibili inversioni e diverse forme di divergenza tra prezzo e volume.

    DeltaFusionLite DeltaFusionLite

    DeltaFusion Lite is the simplified version of the DeltaFusionPro indicator for MT4. It calculates and displays Cumulative Delta and Net Delta, giving traders a clear view of buying and selling pressure within each candle. By analyzing the distribution of volume between bid and ask, it helps identify market sentiment shifts, potential reversals, and various types of divergences between price and volume.