量化交易之MQL4篇 - 自定义指标基础

//+------------------------------------------------------------------+
//|                                                          foo.mq4 |
//|                                      Copyright 2018, Tang Qizhe. |
//|                                            https://www.baidu.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, Tang Qizhe."
#property link      "https://www.baidu.com"
#property version   "1.00"
#property strict
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots   4

//--- plot shortPeriodLine
const string shortPeriodLine = "shortPeriodLine";
#property indicator_label1  "shortPeriodLine"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
double shortPeriodLineBuffer[];

//--- plot longPeriodLine
const string longPeriodLine = "longPeriodLine";
#property indicator_label2  "longPeriodLine"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrWhite
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
double longPeriodLineBuffer[];

//--- plot buyArrow
const string buyArrow = "buyArrow";
#property indicator_label3  "buyArrow"
#property indicator_type3   DRAW_ARROW;
#property indicator_color3  clrRed
#property indicator_style3  STYLE_SOLID
#property indicator_width3  1
double buyArrowBuffer[];

//--- plot sellArrow
const string sellArrow = "sellArrow";
#property indicator_label4  "sellArrow"
#property indicator_type4   DRAW_ARROW
#property indicator_color4  clrLime
#property indicator_style4  STYLE_SOLID
#property indicator_width4  1
double sellArrowBuffer[];

//--- input parameters
input int shortPeriodDay = 10;
input int longPeriodDay = 20;


int OnInit() {
   
    // 设置buffer数组与指标的一一对应关系
    SetIndexBuffer(0,shortPeriodLineBuffer);
    SetIndexBuffer(1,longPeriodLineBuffer);
    SetIndexBuffer(2,buyArrowBuffer);
    SetIndexBuffer(3,sellArrowBuffer);
    
    
    // 设置箭头类型(225、226为箭头的类型)
    SetIndexArrow(2, 225);
    SetIndexArrow(3, 226);
    
    
    /** 指标准备工作的另一种形式
    SetIndexBuffer(0,shortPeriodLineBuffer);
    SetIndexLabel(0, "shortPeriodLine");
    SetIndexStyle(0, DRAW_LINE, STYLE_SOLID, 1, clrRed);
    */
    
    return(INIT_SUCCEEDED);
}



int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[]) {
    
   // 异常处理:如果当前k线数目过少, 则不执行之后的代码
   if(rates_total < MathMax(shortPeriodDay, longPeriodDay)) return 0;
   
   // 优化程序的执行效率:只操作之前没操作过的k线.(limit: 需要跟新的k线个数)
   int limit = rates_total - prev_calculated;
   
   // 最后一根k线有新的价格来时, 仅刷新最后一根k线
   if(limit == 0) limit++;
   
   
   // 根据系统自带指标MA, 画两条线
   for(int i = 0; i < limit; i++) {
      shortPeriodLineBuffer[i] = iMA(Symbol(), PERIOD_CURRENT, shortPeriodDay, 0, MODE_SMA, PRICE_CLOSE, i);
      longPeriodLineBuffer[i] = iMA(Symbol(), PERIOD_CURRENT, longPeriodDay, 0, MODE_SMA, PRICE_CLOSE, i);
   }
   
   
   // 在两条线的交叉处画箭头
   for(int i = 0; i < limit; i++) {
      if(shortPeriodLineBuffer[i] > longPeriodLineBuffer[i] && shortPeriodLineBuffer[i+1] < longPeriodLineBuffer[i+1]) {
         buyArrowBuffer[i] = shortPeriodLineBuffer[i];
  } else if(shortPeriodLineBuffer[i]<longPeriodLineBuffer[i] && shortPeriodLineBuffer[i+1]>longPeriodLineBuffer[i+1]) {
         sellArrowBuffer[i] = longPeriodLineBuffer[i];
      }
   }
              
   return(rates_total);

}


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页