请观看如何免费下载自动交易
请在Twitter上找到我们!
加入我们粉丝页
有趣的脚本?
因此发布一个链接 -
让其他人评价
喜欢这个脚本? 在MetaTrader 5客户端尝试它
脚本

从 X 到时间、从 Y 到价格的函数,反之亦然 - MetaTrader 5脚本

显示:
147
等级:
(4)
已发布:
MQL5自由职业者 需要基于此代码的EA交易或指标吗?请在自由职业者服务中订购 进入自由职业者服务

标准 API 函数 ChartXYToTimePrice 和 ChartTimePriceToXY 有很大的缺点。例如,ChartXYToTimePrice 只有在输入参数 X 和 Y 位于图表窗口可见区域内时才能正常工作 ,在窗口外函数返回零。ChartTimePriceToXY 在某些情况下工作也不正确这两个函数的运行速度都很慢。

我将介绍在所有输入参数范围内都能正确工作的函数:

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

演示函数工作正确性的脚本。其工作原理是将生成的 X 坐标和 Y 坐标转换为时间和价格,然后再转换回X 坐标和 Y 坐标。如果输入的X 坐标和 Y 坐标与输出的坐标不同,说明函数有问题,脚本将打印出差异。如果一切正常,脚本在工作过程中不会打印任何内容,但在最后会打印结果

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)//检查在坐标从一个系统转移到另一个系统再返回的过程中,图表的比例尺和位置是否发生变化
        {
         ++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;
  }
//+------------------------------------------------------------------+


    由MetaQuotes Ltd译自俄语
    原代码: https://www.mql5.com/ru/code/48325

    开发多币种智能交易系统 - 系列文章中的源代码 开发多币种智能交易系统 - 系列文章中的源代码

    在开发库过程中编写的源代码,用于创建结合不同交易策略的多个实例的多币种智能交易系统。

    Price Channel 价格通道 Price Channel 价格通道

    This is a simple price channel indicator allowing user to customize period and line colors. Often used in channel break strategies.

    Simple Bar Timer Simple Bar Timer

    这是一个脚本,用于显示下一个条形图到达前的剩余时间。

    TimeGMT library for the strategy tester TimeGMT library for the strategy tester

    静态类,用于在策略测试器测试过程中修复 TimeGMT() 函数。