MQL5学习之RSI指标编写

news/2025/2/14 6:56:38/

研究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 inputif(InpPeriodRSI<1){ExtPeriodRSI=14;PrintFormat("Incorrect value for input variable InpPeriodRSI = %d. Indicator will use value %d for calculations.",InpPeriodRSI,ExtPeriodRSI);}elseExtPeriodRSI=InpPeriodRSI;
//--- indicator buffers mappingSetIndexBuffer(0,ExtRSIBuffer,INDICATOR_DATA);SetIndexBuffer(1,ExtPosBuffer,INDICATOR_CALCULATIONS);SetIndexBuffer(2,ExtNegBuffer,INDICATOR_CALCULATIONS);
//--- set accuracyIndicatorSetInteger(INDICATOR_DIGITS,2);
//--- sets first bar from what index will be drawnPlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodRSI);
//--- name for DataWindow and indicator subwindow labelIndicatorSetString(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 calculationsint 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 calculatedExtRSIBuffer[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 valueExtPosBuffer[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;elseExtRSIBuffer[ExtPeriodRSI]=50.0;}//--- prepare the position value for main calculationpos=ExtPeriodRSI+1;}
//--- the main loop of calculationsfor(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;elseExtRSIBuffer[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,那个画的多一些才能搞明折


http://www.ppmy.cn/news/1368633.html

相关文章

持安科技孙维伯:零信任在攻防演练下的最佳实践|DISCConf 2023

近日&#xff0c;在2023数字身份安全技术大会上&#xff0c;持安科技联合创始人孙维伯应主办方的特别邀请&#xff0c;发表了主题为“零信任在攻防演练下的最佳实践”的演讲。 孙维伯在2023数字身份安全技术大会上发表演讲 以下为本次演讲实录&#xff1a; 我是持安科技的联合…

N皇后问题详解:回溯算法的应用与实践(dfs)

目录 一.问题描述二.思路分析1.DFS三.代码实现与解析1.分析2.完整代码 一.问题描述 题目如上图所示&#xff0c;在一个n*n的国际象棋棋盘上怎么摆放能使得皇后互相攻击不到&#xff08;也就是在任意一列、一行、一条对角线上都不存在两个皇后&#xff09; 二.思路分析 1.DFS …

SQL 练习题目(入门级)

今天发现了一个练习SQL的网站--牛客网。里面题目挺多的&#xff0c;按照入门、简单、中等、困难进行了分类&#xff0c;可以直接在线输入SQL语句验证是否正确&#xff0c;并且提供了测试表的创建语句&#xff0c;也可以方便自己拓展练习&#xff0c;感觉还是很不错的一个网站&a…

Qt下使用modbus-c库实现PLC线圈/保持寄存器的读写

系列文章目录 提示&#xff1a;这里是该系列文章的所有文章的目录 第一章&#xff1a;Qt下使用ModbusTcp通信协议进行PLC线圈/保持寄存器的读写&#xff08;32位有符号数&#xff09; 第二章&#xff1a;Qt下使用modbus-c库实现PLC线圈/保持寄存器的读写 文章目录 系列文章目录…

IEEE SGL与NVMe SGL的区别?

在HBA&#xff08;Host Bus Adapter&#xff09;驱动程序中&#xff0c;IEEE SGL&#xff08;Institute of Electrical and Electronics Engineers Scatter-Gather List&#xff09;和NVMe SGL&#xff08;Non-Volatile Memory Express Scatter-Gather List&#xff09;是两种不…

【MATLAB】 ICEEMDAN信号分解+FFT傅里叶频谱变换组合算法

有意向获取代码&#xff0c;请转文末观看代码获取方式~ 展示出图效果 1 ICEEMDAN信号分解算法 ICEEMDAN 分解又叫改进的自适应噪声完备集合经验模态分解&#xff0c;英文全称为 Improved Complete Ensemble Empirical Mode Decomposition with Adaptive Noise。 ICEEMDAN (I…

Docker 使用原理流程

# docker 是如何来的&#xff1f; a. linux 内核本身支持容器技术&#xff0c;LXC (市面上有很多基于 LXC 开发的容器管理软件&#xff0c;如创建容器&#xff0c;查看容器&#xff0c;管理容器&#xff0c; docker 作为管理容器的一款代表工具软件) b. 容器的作用&#xff0c;…

《TCP/IP详解 卷一》第9章 广播和组播

目录 9.1 引言 9.2 广播 9.2.1 使用广播地址 9.2.2 发送广播数据报 9.3 组播 9.3.1 将组播IP地址转换为组播MAC地址 9.3.2 例子 9.3.3 发送组播数据报 9.3.4 接收组播数据报 9.3.5 主机地址过滤 9.4 IGMP协议和MLD协议 9.4.1 组成员的IGMP和MLD处理 9.4.2 组播路由…