• MQL5学习之RSI指标编写


    研究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; iIsStopped(); 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,那个画的多一些才能搞明折

  • 相关阅读:
    Mysql优化整理(持续更新)
    Git报错:git@github.com: Permission denied (publickey)
    回归分析:逻辑斯蒂模型,多分类任务
    JAVA+MySQL 图书馆借阅信息管理系统
    从另外一个进程中读取数据
    Zookeeper常见命令
    Foodpanda API连接的艺术:无代码开发如何集成营销系统和广告推广工具
    计算机毕业设计ssm+vue基本微信小程序的校园二手商城系统
    Java学习笔记之----I/O(输入/输出)二
    QT 使用百度语音识别--生成文本
  • 原文地址:https://blog.csdn.net/luhouxiang/article/details/136420430