赞
踩
研究MT5时发现MQL5这个指标编写功能很强大,应该是碾压国内所有的指标系统,不过这个东西相对复杂很多,比通达信公式不知复杂几许,看起来和C++语法接近,倒是比较适合自己。试着玩一下,发现还是有点难度的。索性记录一下。
学习最快的方式就是拿相对简单的东西七改八改一下,然后看呈现出来的是什么样。
RSI指标是能想到的最简单的指标系统,示例里面有代码,贴出来看看:
- //+------------------------------------------------------------------+
- //| 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定义,整理出公式如下:
- //+------------------------------------------------------------------+
-
- //| 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,那个画的多一些才能搞明折
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。