MQL5学习之RSI指标编写

研究MT5时发现MQL5这个指标编写功能很强大,应该是碾压国内所有的指标系统,不过这个东西相对复杂很多,比通达信公式不知复杂几许,看起来和C++语法接近,倒是比较适合自己。试着玩一下,发现还是有点难度的。索性记录一下。

学习最快的方式就是拿相对简单的东西七改八改一下,然后看呈现出来的是什么样。

RSI指标是能想到的最简单的指标系统,示例里面有代码,贴出来看看:

cpp 复制代码
//+------------------------------------------------------------------+
//|                                                          RSI.mq5 |
//|                             Copyright 2000-2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "Copyright 2000-2024, MetaQuotes Ltd."
#property link        "https://www.mql5.com"
#property description "Relative Strength Index"
//--- indicator settings
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_level1 30
#property indicator_level2 70
#property indicator_buffers 3
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  DodgerBlue
//--- input parameters
input int InpPeriodRSI=14; // Period
//--- indicator buffers
double    ExtRSIBuffer[];
double    ExtPosBuffer[];
double    ExtNegBuffer[];

int       ExtPeriodRSI;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- check for input
   if(InpPeriodRSI<1)
     {
      ExtPeriodRSI=14;
      PrintFormat("Incorrect value for input variable InpPeriodRSI = %d. Indicator will use value %d for calculations.",
                  InpPeriodRSI,ExtPeriodRSI);
     }
   else
      ExtPeriodRSI=InpPeriodRSI;
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtRSIBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,ExtPosBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,ExtNegBuffer,INDICATOR_CALCULATIONS);
//--- set accuracy
   IndicatorSetInteger(INDICATOR_DIGITS,2);
//--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodRSI);
//--- name for DataWindow and indicator subwindow label
   IndicatorSetString(INDICATOR_SHORTNAME,"RSI("+string(ExtPeriodRSI)+")");
  }
//+------------------------------------------------------------------+
//| Relative Strength Index                                          |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   if(rates_total<=ExtPeriodRSI)
      return(0);
//--- preliminary calculations
   int pos=prev_calculated-1;
   if(pos<=ExtPeriodRSI)
     {
      double sum_pos=0.0;
      double sum_neg=0.0;
      //--- first RSIPeriod values of the indicator are not calculated
      ExtRSIBuffer[0]=0.0;
      ExtPosBuffer[0]=0.0;
      ExtNegBuffer[0]=0.0;
      for(int i=1; i<=ExtPeriodRSI; i++)
        {
         ExtRSIBuffer[i]=0.0;
         ExtPosBuffer[i]=0.0;
         ExtNegBuffer[i]=0.0;
         double diff=price[i]-price[i-1];
         sum_pos+=(diff>0?diff:0);
         sum_neg+=(diff<0?-diff:0);
        }
      //--- calculate first visible value
      ExtPosBuffer[ExtPeriodRSI]=sum_pos/ExtPeriodRSI;
      ExtNegBuffer[ExtPeriodRSI]=sum_neg/ExtPeriodRSI;
      if(ExtNegBuffer[ExtPeriodRSI]!=0.0)
         ExtRSIBuffer[ExtPeriodRSI]=100.0-(100.0/(1.0+ExtPosBuffer[ExtPeriodRSI]/ExtNegBuffer[ExtPeriodRSI]));
      else
        {
         if(ExtPosBuffer[ExtPeriodRSI]!=0.0)
            ExtRSIBuffer[ExtPeriodRSI]=100.0;
         else
            ExtRSIBuffer[ExtPeriodRSI]=50.0;
        }
      //--- prepare the position value for main calculation
      pos=ExtPeriodRSI+1;
     }
//--- the main loop of calculations
   for(int i=pos; i<rates_total && !IsStopped(); i++)
     {
      double diff=price[i]-price[i-1];
      ExtPosBuffer[i]=(ExtPosBuffer[i-1]*(ExtPeriodRSI-1)+(diff>0.0?diff:0.0))/ExtPeriodRSI;
      ExtNegBuffer[i]=(ExtNegBuffer[i-1]*(ExtPeriodRSI-1)+(diff<0.0?-diff:0.0))/ExtPeriodRSI;
      if(ExtNegBuffer[i]!=0.0)
         ExtRSIBuffer[i]=100.0-100.0/(1+ExtPosBuffer[i]/ExtNegBuffer[i]);
      else
        {
         if(ExtPosBuffer[i]!=0.0)
            ExtRSIBuffer[i]=100.0;
         else
            ExtRSIBuffer[i]=50.0;
        }
     }
//--- OnCalculate done. Return new prev_calculated.
   return(rates_total);
  }
//+------------------------------------------------------------------+

嗯,这个代码量有点大,看起来挺头晕的,不过好在只有两个函数,一个为void OnInit(), 看起来像是初始化的地方,一个为int OnCalculate()看起来就是指标计算的地方。

首先要明确我们想针对RSI搞清楚几样:怎样画线,数据从哪里来,怎样显示计算的指标值。这几个搞清楚了,再学其它的应该就很容易了。

首先看:

int OnCalculate(const int rates_total,

const int prev_calculated,

const int begin,

const double &price[])

{

PrintFormat("rates_total=%d, prev_calculated=%d, begin=%d, price[%d]=%f",

rates_total,prev_calculated, begin, rates_total-1, price[rates_total-1]);

很明显,rates_total表示为K线总数量,price[rates_total-1])表示的为最后一根K线的收盘价

查看RSI定义,整理出公式如下:

cpp 复制代码
//+------------------------------------------------------------------+

//| Relative Strength Index                                          |

// 设每天向上变动为U,向下变动为D。

// 在价格上升的日子:

// U = 是日收市价 - 昨日收市价;D = 0

// 在价格下跌的日子:

// U = 0;D = 昨日收市价 - 是日收市价

// 任何情况下,U及D皆不可能为负数;若两天价格相同,则U及D皆等于零。)

// RS=EMA(U, n)/EMA(D, n)

// RSI=(100-100/(1+RS))

//+------------------------------------------------------------------+

由此可见ExtRSIBuffer即为计算所得的RSI值

不过一直没搞清楚指标是怎么画出来的,即圈中所标的蓝线:

虽然颜色是由#property indicator_color1 C'45,30,255'进行改变弄清楚了,看来得研究一下macd,那个画的多一些才能搞明折

相关推荐
夜瞬4 小时前
NLP学习笔记01:文本预处理详解——从清洗、分词到词性标注
笔记·学习·自然语言处理
-Springer-5 小时前
STM32 学习 —— 个人学习笔记11-1(SPI 通信协议及 W25Q64 简介 & 软件 SPI 读写 W25Q64)
笔记·stm32·学习
LN花开富贵5 小时前
【ROS】鱼香ROS2学习笔记一
linux·笔记·python·学习·嵌入式·ros·agv
克里斯蒂亚诺·罗纳尔达6 小时前
智能体学习23——资源感知优化(Resource-Aware Optimization)
人工智能·学习
小夏子_riotous7 小时前
Docker学习路径——2、安装
linux·运维·分布式·学习·docker·容器·云计算
SteveSenna7 小时前
Trossen Arm MuJoCo自定义1:改变目标物体
人工智能·学习·算法·机器人
U盘失踪了8 小时前
go 环境配置
学习
Stella Blog8 小时前
狂神Java基础学习笔记Day03
java·笔记·学习
夜瞬10 小时前
NLP学习笔记02:文本表示方法——从词袋模型到 BERT
笔记·学习·自然语言处理
xuhaoyu_cpp_java10 小时前
MySql学习(二)
经验分享·笔记·学习·mysql