当前位置:   article > 正文

MQL5学习之RSI指标编写_mql5 经典程序

mql5 经典程序

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

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

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

  1. //+------------------------------------------------------------------+
  2. //| RSI.mq5 |
  3. //| Copyright 2000-2024, MetaQuotes Ltd. |
  4. //| https://www.mql5.com |
  5. //+------------------------------------------------------------------+
  6. #property copyright "Copyright 2000-2024, MetaQuotes Ltd."
  7. #property link "https://www.mql5.com"
  8. #property description "Relative Strength Index"
  9. //--- indicator settings
  10. #property indicator_separate_window
  11. #property indicator_minimum 0
  12. #property indicator_maximum 100
  13. #property indicator_level1 30
  14. #property indicator_level2 70
  15. #property indicator_buffers 3
  16. #property indicator_plots 1
  17. #property indicator_type1 DRAW_LINE
  18. #property indicator_color1 DodgerBlue
  19. //--- input parameters
  20. input int InpPeriodRSI=14; // Period
  21. //--- indicator buffers
  22. double ExtRSIBuffer[];
  23. double ExtPosBuffer[];
  24. double ExtNegBuffer[];
  25. int ExtPeriodRSI;
  26. //+------------------------------------------------------------------+
  27. //| Custom indicator initialization function |
  28. //+------------------------------------------------------------------+
  29. void OnInit()
  30. {
  31. //--- check for input
  32. if(InpPeriodRSI<1)
  33. {
  34. ExtPeriodRSI=14;
  35. PrintFormat("Incorrect value for input variable InpPeriodRSI = %d. Indicator will use value %d for calculations.",
  36. InpPeriodRSI,ExtPeriodRSI);
  37. }
  38. else
  39. ExtPeriodRSI=InpPeriodRSI;
  40. //--- indicator buffers mapping
  41. SetIndexBuffer(0,ExtRSIBuffer,INDICATOR_DATA);
  42. SetIndexBuffer(1,ExtPosBuffer,INDICATOR_CALCULATIONS);
  43. SetIndexBuffer(2,ExtNegBuffer,INDICATOR_CALCULATIONS);
  44. //--- set accuracy
  45. IndicatorSetInteger(INDICATOR_DIGITS,2);
  46. //--- sets first bar from what index will be drawn
  47. PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodRSI);
  48. //--- name for DataWindow and indicator subwindow label
  49. IndicatorSetString(INDICATOR_SHORTNAME,"RSI("+string(ExtPeriodRSI)+")");
  50. }
  51. //+------------------------------------------------------------------+
  52. //| Relative Strength Index |
  53. //+------------------------------------------------------------------+
  54. int OnCalculate(const int rates_total,
  55. const int prev_calculated,
  56. const int begin,
  57. const double &price[])
  58. {
  59. if(rates_total<=ExtPeriodRSI)
  60. return(0);
  61. //--- preliminary calculations
  62. int pos=prev_calculated-1;
  63. if(pos<=ExtPeriodRSI)
  64. {
  65. double sum_pos=0.0;
  66. double sum_neg=0.0;
  67. //--- first RSIPeriod values of the indicator are not calculated
  68. ExtRSIBuffer[0]=0.0;
  69. ExtPosBuffer[0]=0.0;
  70. ExtNegBuffer[0]=0.0;
  71. for(int i=1; i<=ExtPeriodRSI; i++)
  72. {
  73. ExtRSIBuffer[i]=0.0;
  74. ExtPosBuffer[i]=0.0;
  75. ExtNegBuffer[i]=0.0;
  76. double diff=price[i]-price[i-1];
  77. sum_pos+=(diff>0?diff:0);
  78. sum_neg+=(diff<0?-diff:0);
  79. }
  80. //--- calculate first visible value
  81. ExtPosBuffer[ExtPeriodRSI]=sum_pos/ExtPeriodRSI;
  82. ExtNegBuffer[ExtPeriodRSI]=sum_neg/ExtPeriodRSI;
  83. if(ExtNegBuffer[ExtPeriodRSI]!=0.0)
  84. ExtRSIBuffer[ExtPeriodRSI]=100.0-(100.0/(1.0+ExtPosBuffer[ExtPeriodRSI]/ExtNegBuffer[ExtPeriodRSI]));
  85. else
  86. {
  87. if(ExtPosBuffer[ExtPeriodRSI]!=0.0)
  88. ExtRSIBuffer[ExtPeriodRSI]=100.0;
  89. else
  90. ExtRSIBuffer[ExtPeriodRSI]=50.0;
  91. }
  92. //--- prepare the position value for main calculation
  93. pos=ExtPeriodRSI+1;
  94. }
  95. //--- the main loop of calculations
  96. for(int i=pos; i<rates_total && !IsStopped(); i++)
  97. {
  98. double diff=price[i]-price[i-1];
  99. ExtPosBuffer[i]=(ExtPosBuffer[i-1]*(ExtPeriodRSI-1)+(diff>0.0?diff:0.0))/ExtPeriodRSI;
  100. ExtNegBuffer[i]=(ExtNegBuffer[i-1]*(ExtPeriodRSI-1)+(diff<0.0?-diff:0.0))/ExtPeriodRSI;
  101. if(ExtNegBuffer[i]!=0.0)
  102. ExtRSIBuffer[i]=100.0-100.0/(1+ExtPosBuffer[i]/ExtNegBuffer[i]);
  103. else
  104. {
  105. if(ExtPosBuffer[i]!=0.0)
  106. ExtRSIBuffer[i]=100.0;
  107. else
  108. ExtRSIBuffer[i]=50.0;
  109. }
  110. }
  111. //--- OnCalculate done. Return new prev_calculated.
  112. return(rates_total);
  113. }
  114. //+------------------------------------------------------------------+

嗯,这个代码量有点大,看起来挺头晕的,不过好在只有两个函数,一个为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定义,整理出公式如下:

  1. //+------------------------------------------------------------------+
  2. //| Relative Strength Index                                          |
  3. // 设每天向上变动为U,向下变动为D。
  4. // 在价格上升的日子:
  5. // U = 是日收市价 - 昨日收市价;D = 0
  6. // 在价格下跌的日子:
  7. // U = 0;D = 昨日收市价 - 是日收市价
  8. // 任何情况下,U及D皆不可能为负数;若两天价格相同,则U及D皆等于零。)
  9. // RS=EMA(U, n)/EMA(D, n)
  10. // RSI=(100-100/(1+RS))
  11. //+------------------------------------------------------------------+

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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/199627
推荐阅读
相关标签
  

闽ICP备14008679号