尼古拉!你的哪个孩子最不容易出错?
Makser:
这是个问题,所以是问题。我在十字星上使用 JFatlSpeed,最近又在其他方面使用。但只在四小时标记上使用。我在 X2MA_BBx9 上捕捉五分钟交易的反弹。
尼古拉!你的孩子中,哪一个的滞后性最小,错误信号最少(当然,如果能确定的话)。
所以,这绝对不是我的编程风格。
只见树木不见森林 = 只见代码不见注释。
此外,输入参数 "shift "根本没有使用。
我已经按照自己的风格重新编写了程序,也许 "超级程序员 "可以借鉴一下。
//+------------------------------------------------------------------+ //|超级趋势。mq5 //| 原始代码可在 https://www.mql5.com/zh/code/527 | 找到。 //| 原始代码来自 Jason Robinson,由 Nikolay Kositsin 重写。 //| 由化名为 Kronenchakra 的奥托-保泽尔工程师改进。 //+------------------------------------------------------------------+ //--- inckudes #include <Utils.mqh> //--- 一般属性 #property copyright COPY #property link LINK #property version "1.00" //--- 指示器属性 #property indicator_chart_window #property indicator_buffers 4 #property indicator_plots 4 //--- 输入参数 input int CCIPeriod = 50; // CCI 指标周期 input int ATRPeriod = 5; // ATR 指标周期 input int Level = 0; // CCI 启动级别 //---- 指示器缓冲区 double ATR[], CCI[]; double TrendUp[], TrendDn[]; double SignUp[], SignDn[]; //---- 全局变量 int min_rates_total; int ATR_Handle, CCI_Handle; //+------------------------------------------------------------------+ //| 自定义指示器初始化函数 //+------------------------------------------------------------------+ int OnInit() { min_rates_total=MathMax(CCIPeriod,ATRPeriod); CCI_Handle=iCCI(NULL,0,CCIPeriod,PRICE_TYPICAL); if(InvalidHandle(CCI_Handle,"iCCI")) return(INIT_FAILED); ATR_Handle=iATR(NULL,0,ATRPeriod); if(InvalidHandle(ATR_Handle,"iATR")) return(INIT_FAILED); string shortname=IndiShortName("Supertrend",CCIPeriod,ATRPeriod); IndicatorSetString(INDICATOR_SHORTNAME,shortname); IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1); InitBuffer(TrendUp,DRAW_LINE ,"Supertrend Up" ,clrLime,min_rates_total,0 ,2,true); InitBuffer(TrendDn,DRAW_LINE ,"Supertrend Down" ,clrRed ,min_rates_total,0 ,2,true); InitBuffer(SignUp ,DRAW_ARROW,"Supertrend signal Buy" ,clrLime,min_rates_total,108,1,true); InitBuffer(SignDn ,DRAW_ARROW,"Supertrend signal Sell",clrRed ,min_rates_total,108,1,true); ArraySetAsSeries(ATR,true); ArraySetAsSeries(CCI,true); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 自定义指标迭代函数 //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double& high[], const double& low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { if // 检查 ( BarsCalculated(CCI_Handle)<rates_total || // 检查 CCI 指标 BarsCalculated(ATR_Handle)<rates_total || // 检查 ATR 指标 rates_total<min_rates_total // 检查条数是否足够 ) return(0); // 尝试下一个刻度 int limit,to_copy,bar; ArraySetAsSeries(high,true); // 必须在每个刻度设置 AsSeries ArraySetAsSeries(low ,true); if(prev_calculated>rates_total || prev_calculated<=0) // 检查指标计算是否首次开始 limit=rates_total-min_rates_total; // 计算所有条形图的起始指数 else limit=rates_total-prev_calculated; // 计算新条形的起始指数 to_copy=limit+1; // 将 ATR 数据复制到缓冲区 if(CopyBuffer(ATR_Handle,0,0,to_copy,ATR)<=0) return(0); to_copy++; // 将 CCI 数据复制到缓冲区 if(CopyBuffer(CCI_Handle,0,0,to_copy,CCI)<=0) return(0); for(bar=limit; bar>=0; bar--) // 计算主循环 { TrendUp[bar]=NULL; // 清除所有缓冲区 TrendDn[bar]=NULL; SignUp [bar]=NULL; SignDn [bar]=NULL; // 计算线条 if(CCI[bar]>=Level && CCI[bar+1]<Level) TrendUp[bar]=TrendDn[bar+1]; if(CCI[bar]<=Level && CCI[bar+1]>Level) TrendDn[bar]=TrendUp[bar+1]; if(CCI[bar]>Level) { TrendUp[bar]=low[bar]-ATR[bar]; if(TrendUp[bar]<TrendUp[bar+1] && CCI[bar+1]>=Level) TrendUp[bar]=TrendUp[bar+1]; } if(CCI[bar]<Level) { TrendDn[bar]=high[bar]+ATR[bar]; if(TrendDn[bar]>TrendDn[bar+1] && CCI[bar+1]<=Level) TrendDn[bar]=TrendDn[bar+1]; } if(TrendDn[bar+1]!=0.0 && TrendUp[bar]!=0.0) SignUp[bar]=TrendUp[bar]; // 检查信号 UP if(TrendUp[bar+1]!=0.0 && TrendDn[bar]!=0.0) SignDn[bar]=TrendDn[bar]; // 检查信号 DOWN } return(rates_total); }
//+------------------------------------------------------------------+ //|Utils.mqh //| Copyright © 2018, Ing.奥托-保泽尔 //|https://www.mql5.com/zh/users/kronenchakra| //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| 定义| //+------------------------------------------------------------------+ #define COPY "版权所有 © 2018,奥托-保泽尔工程师" #define LINK "https://www.mql5.com/zh/users/kronenchakra" #define SPACER "---------------------" //+------------------------------------------------------------------+ // 缩略语| //+------------------------------------------------------------------+ #define PRICE ENUM_APPLIED_PRICE #define TIMEF ENUM_TIMEFRAMES //+------------------------------------------------------------------+ //| 辅助功能| //+------------------------------------------------------------------+ void InitBuffer(double &_buffer[], ENUM_DRAW_TYPE _type, string _label, color _color, int _begin, int _arrow=159, int _width=1, bool _series=false) { static int idx=0; // 将缓冲区索引初始化为 0 SetIndexBuffer (idx,_buffer); // 初始化缓冲区 ArrayInitialize (_buffer ,NULL); // 初始化缓冲区 ArraySetAsSeries (_buffer ,_series); // 设置 AsSeries // 设置属性 PlotIndexSetInteger(idx,PLOT_DRAW_TYPE ,_type ); PlotIndexSetInteger(idx,PLOT_LINE_COLOR ,_color); PlotIndexSetInteger(idx,PLOT_LINE_WIDTH ,_width); PlotIndexSetInteger(idx,PLOT_DRAW_BEGIN ,_begin); PlotIndexSetInteger(idx,PLOT_ARROW ,_arrow); PlotIndexSetString (idx,PLOT_LABEL ,_label); PlotIndexSetDouble (idx,PLOT_EMPTY_VALUE,NULL ); idx++; // 为下一次调用增加缓冲区索引 } bool InvalidHandle(int _handle, string _msg) { if(_handle==INVALID_HANDLE) // 检查句柄 Alert("*ERROR* creating "+_msg+" handle."); // 信息 return(_handle==INVALID_HANDLE); // 如果无效,则返回 true } string IndiShortName(string _name, int val_1, int val_2=NULL, int val_3=NULL) { string result=_name+"("+IntegerToString(val_1); if(val_2!=NULL) result=result+","+IntegerToString(val_2); if(val_3!=NULL) result=result+","+IntegerToString(val_3); return(result+")"); } //+------------------------------------------------------------------+ //| 计算功能| //+------------------------------------------------------------------+ double StdDeviation(int position,const double &price[],const double &MAprice[],int period) { int i; double StdDev_dTmp=0.0; if(position<period) return(StdDev_dTmp); // 检查位置 for(i=0;i<period;i++) // 计算标准差 StdDev_dTmp+=MathPow(price[position-i]-MAprice[position],2); StdDev_dTmp=MathSqrt(StdDev_dTmp/period); return(StdDev_dTmp); // 返回计算值 }
它看起来非常清晰。
也许 MetaQutes 可以借鉴一二,比如如何在一行中定义绘图缓冲区。
附加的文件:
supertrend.mq5
11 kb
Utils.mqh
7 kb
奥托
这:
TrendUp[bar]=NULL; // 清除所有缓冲区 TrendDn[bar]=NULL; SignUp [bar]=NULL; SignDn [bar]=NULL;
是危险的。NULL 属于"void"类型。以后,为了让 MT5 运行得更快,或许可以不分配任何值(那么旧值就会保留),或者在内存位置发生变化时创建一个随机值。
我认为最好使用_symbol 来表示符号,而直接使用EMPTY_VALUE 或 0 来表示值。这样一来,虚无就有了存在的意义;)
如何获得
我想使用这个指标
ka03ht8096:
如何获取
如何获取
步骤 1:
第二步:
哪个输入是乘数和 ATR 值?
是否有适用于 mt4 的软件
SuperTrend:
SuperTrend 趋势指标。
作者: Nikolay Kositsin