可以编写一个实用程序,根据视频中显示的原理改变任意指标的任意线/柱状图(等)。
干得好Thank you!
我修改了代码,加入了线重和样式设置:
//+------------------------------------------------------------------+ //| Custom Moving Average Input Colour.mq5 | 自定义移动平均输入颜色.mq5 //| 2009-2017, MetaQuotes Software Corp.版权所有。 //|http://www.mql5.com | | //+------------------------------------------------------------------+ #property copyright "2009-2017, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.001" //--- 指示器设置 #property indicator_chart_window #property indicator_buffers 1 #property indicator_plots 1 #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed //--- 输入参数 input int InpMAPeriod=13; // 期间 input int InpMAShift=0; // 移位 input ENUM_MA_METHOD InpMAMethod=MODE_SMMA; // 方法 input color InpColor=clrYellow; // 颜色 input ENUM_LINE_STYLE InpMAStyle=STYLE_SOLID; // 风格 input int InpMAWidth=1; // 宽度 //--- 指示器缓冲区 double ExtLineBuffer[]; //+------------------------------------------------------------------+ //| 简单移动平均线| //+------------------------------------------------------------------+ void CalculateSimpleMA(int rates_total,int prev_calculated,int begin,const double &price[]) { int i,limit; //--- 第一次计算或条数发生变化 if(prev_calculated==0)// 第一次计算 { limit=InpMAPeriod+begin; //--- 为第一个限幅条设置空值 for(i=0;i<limit-1;i++) ExtLineBuffer[i]=0.0; //--- 计算第一个可见值 double firstValue=0; for(i=begin;i<limit;i++) firstValue+=price[i]; firstValue/=InpMAPeriod; ExtLineBuffer[limit-1]=firstValue; } else limit=prev_calculated-1; //--- 主循环 for(i=limit;i<rates_total && !IsStopped();i++) ExtLineBuffer[i]=ExtLineBuffer[i-1]+(price[i]-price[i-InpMAPeriod])/InpMAPeriod; //--- } //+------------------------------------------------------------------+ //| 指数移动平均线| //+------------------------------------------------------------------+ void CalculateEMA(int rates_total,int prev_calculated,int begin,const double &price[]) { int i,limit; double SmoothFactor=2.0/(1.0+InpMAPeriod); //--- 第一次计算或条数发生变化 if(prev_calculated==0) { limit=InpMAPeriod+begin; ExtLineBuffer[begin]=price[begin]; for(i=begin+1;i<limit;i++) ExtLineBuffer[i]=price[i]*SmoothFactor+ExtLineBuffer[i-1]*(1.0-SmoothFactor); } else limit=prev_calculated-1; //--- 主循环 for(i=limit;i<rates_total && !IsStopped();i++) ExtLineBuffer[i]=price[i]*SmoothFactor+ExtLineBuffer[i-1]*(1.0-SmoothFactor); //--- } //+------------------------------------------------------------------+ //| 线性加权移动平均线| //+------------------------------------------------------------------+ void CalculateLWMA(int rates_total,int prev_calculated,int begin,const double &price[]) { int i,limit; static int weightsum; double sum; //--- 第一次计算或条数发生变化 if(prev_calculated==0) { weightsum=0; limit=InpMAPeriod+begin; //--- 为第一个限幅条设置空值 for(i=0;i<limit;i++) ExtLineBuffer[i]=0.0; //--- 计算第一个可见值 double firstValue=0; for(i=begin;i<limit;i++) { int k=i-begin+1; weightsum+=k; firstValue+=k*price[i]; } firstValue/=(double)weightsum; ExtLineBuffer[limit-1]=firstValue; } else limit=prev_calculated-1; //--- 主循环 for(i=limit;i<rates_total && !IsStopped();i++) { sum=0; for(int j=0;j<InpMAPeriod;j++) sum+=(InpMAPeriod-j)*price[i-j]; ExtLineBuffer[i]=sum/weightsum; } //--- } //+------------------------------------------------------------------+ //| 平滑移动平均线| //+------------------------------------------------------------------+ void CalculateSmoothedMA(int rates_total,int prev_calculated,int begin,const double &price[]) { int i,limit; //--- 第一次计算或条数发生变化 if(prev_calculated==0) { limit=InpMAPeriod+begin; //--- 为第一个限幅条设置空值 for(i=0;i<limit-1;i++) ExtLineBuffer[i]=0.0; //--- 计算第一个可见值 double firstValue=0; for(i=begin;i<limit;i++) firstValue+=price[i]; firstValue/=InpMAPeriod; ExtLineBuffer[limit-1]=firstValue; } else limit=prev_calculated-1; //--- 主循环 for(i=limit;i<rates_total && !IsStopped();i++) ExtLineBuffer[i]=(ExtLineBuffer[i-1]*(InpMAPeriod-1)+price[i])/InpMAPeriod; //--- } //+------------------------------------------------------------------+ //| 自定义指示器初始化函数 //+------------------------------------------------------------------+ void OnInit() { //--- 指示器缓冲区映射 SetIndexBuffer(0,ExtLineBuffer,INDICATOR_DATA); //--- 设置精确度 IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1); //--- 设置从哪个索引开始绘制第一个条形图 PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpMAPeriod); //---- 绘制时线条移动 PlotIndexSetInteger(0,PLOT_SHIFT,InpMAShift); //--- 颜色线 PlotIndexSetInteger(0,PLOT_LINE_COLOR,InpColor); //--- 样式行 PlotIndexSetInteger(0,PLOT_LINE_STYLE,InpMAStyle); //--- 宽线 PlotIndexSetInteger(0,PLOT_LINE_WIDTH,InpMAWidth); //--- 数据窗口的名称 string short_name="unknown ma"; switch(InpMAMethod) { case MODE_EMA : short_name="EMA"; break; case MODE_LWMA : short_name="LWMA"; break; case MODE_SMA : short_name="SMA"; break; case MODE_SMMA : short_name="SMMA"; break; } IndicatorSetString(INDICATOR_SHORTNAME,short_name+"("+string(InpMAPeriod)+")"); //---- sets drawing line empty value-- PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0); //---- 初始化完成 } //+------------------------------------------------------------------+ //| 移动平均线| //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { //--- 检查条数 if(rates_total<InpMAPeriod-1+begin) return(0);// 计算的条数不够 //--- 第一次计算或条数发生变化 if(prev_calculated==0) ArrayInitialize(ExtLineBuffer,0); //--- 设置将从哪个索引开始绘制第一个条形图 PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpMAPeriod-1+begin); //--- 计算 switch(InpMAMethod) { case MODE_EMA: CalculateEMA(rates_total,prev_calculated,begin,price); break; case MODE_LWMA: CalculateLWMA(rates_total,prev_calculated,begin,price); break; case MODE_SMMA: CalculateSmoothedMA(rates_total,prev_calculated,begin,price); break; case MODE_SMA: CalculateSimpleMA(rates_total,prev_calculated,begin,price); break; } //--- 为下一次调用返回 prev_calculated 的值 return(rates_total); } //+------------------------------------------------------------------+
我们能否增加修改 EA 中线条粗细的可能性?
它是如何从 EA 代码中修改出来的?
有颜色参数的自定义移动平均:
对"自定义移动平均"指标的修改: 现在,线的颜色可以通过输入参数来传入了,
作者: Vladimir Karputov