首页 > 提升投资报酬 > 量化分析

运用MQL程序语言来制作显示3条RCI的方式

量化分析 2022-04-24 10:02:54

改写为3条显示


本章的内容虽然并不是MT4的默认指针、但被交易人所广泛使用的RCI。

此处将使用免费公开的「HT_RCI」指标作为模板,并说明其修改的重点。

其本的档案只会显示1条RCI,而此处将修改为显示3条RCI。首先,由于尚未设定缓冲区数量,因此需新增至「3」,并设定其各自的公式、颜色、宽度以及线条种类。宽度以及线条种类可维持不变,颜色则设定为白色、黄色及红色。
 
#property indicator_buffers 3

#property indicator_plots 3

#property indicator_color1 clrWhite

#property indicator_color2 clrYellow

#property indicator_color3 clrRed

#property indicator_width1 1

#property indicator_width2 1

#property indicator_width3 1

#property indicator_style1 STYLE_SOLID

#property indicator_style2 STYLE_SOLID

#property indicator_style3 STYLE_SOLID
RCI周期设定为为短期「10」、中期「20」、长期「50」。
 
input int PERIOD_S = 10; // 短期

input int PERIOD_M = 20; // 中期

input int PERIOD_L = 50; // 长期
缓冲区也新增至可供其个别使用,设定为「0」「1」「2」。
 
double RCI0[], RCI1[], RCI2[];
针对这些缓冲区,需新增其各自的设定。「Label」将改写为可分别显示周期的方式,「string name」则以逗号来连接各个周期。
 
SetIndexBuffer(0, RCI0, INDICATOR_DATA);

SetIndexBuffer(1, RCI1, INDICATOR_DATA);

SetIndexBuffer(2, RCI2, INDICATOR_DATA);

SetIndexLabel(0, “RCI(” + (string)PERIOD_S + “)”);

SetIndexLabel(1, “RCI(” + (string)PERIOD_M + “)”);

SetIndexLabel(2, “RCI(” + (string)PERIOD_L + “)”);

string name = “RCI(” + (string)PERIOD_S + “,” + (string)PERIOD_M + “,” + (string)PERIOD_L + “)”;
计算内容也将分别设定3个种类。
 
for(int i = limit; i >= 0; i–) {

RCI0[i] = iRCI(NULL, 0, PERIOD_S, i);

RCI1[i] = iRCI(NULL, 0, PERIOD_M, i);

RCI2[i] = iRCI(NULL, 0, PERIOD_L, i);
计算的BARS则应避免设定过多的数量。

input int BARS = 500; // 计算条列数量

计算「BARS」的条列数量将暂定为500条列,意指最多不会计算超过500条列。
 
 

设定箭头显示的条件


接下来,将在3条RCI依照短期、中期、长期依序并列时,制作显示符号的条件公式。

首先将从上方开始,照着短期>中期>长期的并列状态设定为「up」。制作「短期大于中期」、以及「中期大于长期」的条件。

此处是为了定义「bool」的条件成立与否,其亦可自前1条列 (i+1)中加以判断。另外,针对与「up」对立排列的「dn」,将以反向符号进行相同的步骤。
 
bool upNow = RCI0[i] > RCI1[i] && RCI1[i] > RCI2[i];

bool upPre = RCI0[i + 1] > RCI1[i + 1] && RCI1[i + 1] > RCI2[i + 1];

bool dnNow = RCI0[i] < RCI1[i] && RCI1[i] < RCI2[i];

bool dnPre = RCI0[i + 1] < RCI1[i + 1] && RCI1[i + 1] < RCI2[i + 1];
此处使用if文法制作,设定为「目前的并列状态成立,前1根K线则不成立」的条件。若添加「!」记号,则将使条件反转,在此处及代表条件不成立。透过如此步骤,将会在并列成立时显示箭头讯号。另外,可在选单的「插入」→「符号类」中,使用箭头对象(Arrow对象)作为显示的箭头。
 
if (upNow && !upPre)

显示箭头


将名称暂定为「3RCI_Sign」,并预先写入这是第「i」根K线的信息。ObjectCreate函数设定为0号(目前显示的图表),对象种类则为「OBJ_ARROW」。由于显示窗口为主要窗口,因此设定为「0」;此处设定「1」将代表第一个窗口分页、「2」则代表第二个窗口分页。虽然亦可设定时间与价格,但本次将先设定为「0」「0」。
 
string name = “3RCI_Sign_” + (string)i;

ObjectCreate(0, name, OBJ_ARROW, 0, 0, 0);
接下来将使用ObjectSetInteger函数来设定时间。

与前述的步骤相同,并选择「OBJPROP_TIME」、将时间信息设定为「i」。
 
ObjectSetInteger(0, name, OBJPROP_TIME, 0, Time[i]);
ObjectSetDouble函数也同样将买进讯号显示为低价方;而「ANCHOR」亦可设定对象基准点的位置。若使用Arrow对象,则可选择「TOP」或「BOTTOM」;由于本次将显示在下方,因此选择TOP。大小设定为「2」、颜色为红色、箭头编码则为「233」。
 
 

重设显示箭头


显示符号的外观已经完成;但由于显示的箭头将延续下去,因此每次切换时间周期便会持续增加。

为了重设显示方式,可使用ObjectsDeleteAll函数;其可在目前的图表中,全部删除已设定的文字序列等对象。透过输入此参数,将能够切换图表、删除旧箭头、显示新箭头。
 
ObjectsDeleteAll(0, “3RCI_Sign_”);
最后删除此指标时,将不会留下任何对象。OnDeinit函数将在切换时间轴、改变参数、结束指标时执行一次。
 
void OnDeinit(const int reason)

{

ObjectsDeleteAll(0, “3RCI_Sign_”);

}
透过此步骤在图表上删除指针时,箭头将会一并消失。
 

原始码


本次制作的原始码如下列所示。
 
//+——————————————————————+

//| 3RCI_Sign |

//| HT FX |

//| http://htfx.blog.fc2.com/ |

//+——————————————————————+

#property copyright “HT FX”

#property link “http://htfx.blog.fc2.com/”

#property description “Copyright (C) 2020 HT FX All Rights Reserved.\n”

#property description “http://htfx.blog.fc2.com/\n”

#property description “htfxjp@gmail.com”

#property version “1.00”

#property strict

#property indicator_separate_window

#property indicator_maximum 1

#property indicator_minimum -1

#property indicator_buffers 3

#property indicator_plots 3

#property indicator_color1 clrWhite

#property indicator_color2 clrYellow

#property indicator_color3 clrRed

#property indicator_width1 1

#property indicator_width2 1

#property indicator_width3 1

#property indicator_style1 STYLE_SOLID

#property indicator_style2 STYLE_SOLID

#property indicator_style3 STYLE_SOLID

//+——————————————————————+

//| Input parameters |

//+——————————————————————+

input int BARS = 500; // 计算条列数量

input int PERIOD_S = 10; // 短期

input int PERIOD_M = 20; // 中期

input int PERIOD_L = 50; // 长期

//— indicator buff

double RCI0[], RCI1[], RCI2[];

//+——————————————————————+

//| Custom indicator initialization function |

//+——————————————————————+

int init()

{

IndicatorSetInteger(INDICATOR_DIGITS, 6);

SetIndexStyle(0, DRAW_LINE);

SetIndexStyle(1, DRAW_LINE);

SetIndexStyle(2, DRAW_LINE);

SetIndexBuffer(0, RCI0, INDICATOR_DATA);

SetIndexBuffer(1, RCI1, INDICATOR_DATA);

SetIndexBuffer(2, RCI2, INDICATOR_DATA);

SetIndexLabel(0, “RCI(” + (string)PERIOD_S + “)”);

SetIndexLabel(1, “RCI(” + (string)PERIOD_M + “)”);

SetIndexLabel(2, “RCI(” + (string)PERIOD_L + “)”);

string name = “RCI(” + (string)PERIOD_S + “,” + (string)PERIOD_M + “,” + (string)PERIOD_L + “)”;

IndicatorSetString(INDICATOR_SHORTNAME, name);

return 0;

}

//+——————————————————————+

//| Custom indicator deinitialization function |

//+——————————————————————+

void OnDeinit(const int reason)

{

ObjectsDeleteAll(0, “3RCI_Sign_”);

}

//+——————————————————————+

//| Custom indicator iteration function |

//+——————————————————————+

int start()

{

int counted_bars = IndicatorCounted();

//—- check for possible errors

if(counted_bars < 0) return -1;

//—- last counted bar will be recounted

if(counted_bars > 0) counted_bars–;

int limit = MathMin(Bars – 1, BARS);

// if (limit < 1) limit = 1;

ObjectsDeleteAll(0, “3RCI_Sign_”);

for(int i = limit; i >= 0; i–) {

RCI0[i] = iRCI(NULL, 0, PERIOD_S, i);

RCI1[i] = iRCI(NULL, 0, PERIOD_M, i);

RCI2[i] = iRCI(NULL, 0, PERIOD_L, i);

bool upNow = RCI0[i] > RCI1[i] && RCI1[i] > RCI2[i];

bool upPre = RCI0[i + 1] > RCI1[i + 1] && RCI1[i + 1] > RCI2[i + 1];

bool dnNow = RCI0[i] < RCI1[i] && RCI1[i] < RCI2[i];

bool dnPre = RCI0[i + 1] < RCI1[i + 1] && RCI1[i + 1] < RCI2[i + 1];

if (upNow && !upPre) {

string name = “3RCI_Sign_” + (string)i;

ObjectCreate(0, name, OBJ_ARROW, 0, 0, 0);

ObjectSetInteger(0, name, OBJPROP_TIME, 0, Time[i]);

ObjectSetDouble(0, name, OBJPROP_PRICE, 0, Low[i]);

ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_TOP);

ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);

ObjectSetInteger(0, name, OBJPROP_COLOR, clrRed);

ObjectSetInteger(0, name, OBJPROP_ARROWCODE, 233);

}

if (dnNow && !dnPre) {

string name = “3RCI_Sign_” + (string)i;

ObjectCreate(0, name, OBJ_ARROW, 0, 0, 0);

ObjectSetInteger(0, name, OBJPROP_TIME, 0, Time[i]);

ObjectSetDouble(0, name, OBJPROP_PRICE, 0, High[i]);

ObjectSetInteger(0, name, OBJPROP_ANCHOR, ANCHOR_BOTTOM);

ObjectSetInteger(0, name, OBJPROP_WIDTH, 2);

ObjectSetInteger(0, name, OBJPROP_COLOR, clrDodgerBlue);

ObjectSetInteger(0, name, OBJPROP_ARROWCODE, 234);

}

}

return 0;

}

//+——————————————————————+
哪些贵金属平台好?不错的贵金属交易汇平台推荐:哪些贵金属平台好?2023年平台最新排名
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。
本文相关:无相关信息

留言与评论(共有 0 条评论)
验证码:

免责声明

特别提示:根据《关于严厉查处非法外汇期货和外汇按金交易活动的通知》(证监发字[1978]105号)规定凡未经批准的机构在大陆境内擅自开展外汇期货交易均属非法,提高意识,谨防损失!

本网站所有刊登内容,以及所提供的信息资料,目的是为了更好地服务我们的访问者,本网站不保证所有信息、文本、图形、链接及其它项目的绝对准确性和完整性,网站没有任何盈利目的,故仅供访问者参照使用。本网站已尽力确保所有资料是准确、完整及最新的。就该资料的针对性、精确性以及特定用途的适合性而言,本网站不能作出最对应的方案。所以因依赖该资料所致的任何损失,本网均不负责。 除特别注明之服务条款外,其他一切因使用本站而引致的任何意外、疏忽、合约毁坏、隐秘汇漏、诽谤、版权或知识产权侵犯及其所造成的损失,本站概不负责,亦不承担任何法律责任。如您(单位或个人)认为本网站某部分内容有侵权嫌疑,敬请立即通知我们,我们将在第一时间予以更改或删除。以上声明之解释权归牛犇财经网站所有。法律上有相关解释的,以中国法律之解释为基准。如有争议限在我方所在地司法部门解决。