#property description "The indicator highlights the candlesticks that are local" #property description "highs and lows. Interval length for finding" #property description "extreme values should be found using an input parameters." //--- 指标设置 #property indicator_chart_window #property indicator_buffers 5 #property indicator_plots 1 //---- 绘制 #property indicator_label1 "Extremums" #property indicator_type1 DRAW_COLOR_CANDLES #property indicator_color1 clrLightSteelBlue,clrRed,clrBlue #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- 预定义常量 #define INDICATOR_EMPTY_VALUE 0.0 //--- 输入参数 input int InpNum=4; // 半区间长度 //--- 指标缓冲区 double ExtOpen[]; double ExtHigh[]; double ExtLow[]; double ExtClose[]; double ExtColor[]; //--- 全局变量 int ExtStart=0; // 第一个蜡烛图的指数不是一个极值 int ExtCount=0; // 区间的非极值数量 //+------------------------------------------------------------------+ //| 填写非极值蜡烛图 | //+------------------------------------------------------------------+ void FillCandles(const double &open[],const double &high[], const double &low[],const double &close[]) { //--- 填写蜡烛图 ArrayCopy(ExtOpen,open,ExtStart,ExtStart,ExtCount); ArrayCopy(ExtHigh,high,ExtStart,ExtStart,ExtCount); ArrayCopy(ExtLow,low,ExtStart,ExtStart,ExtCount); ArrayCopy(ExtClose,close,ExtStart,ExtStart,ExtCount); } //+------------------------------------------------------------------+ //| 自定义指标初始化函数 | //+------------------------------------------------------------------+ int OnInit() { //--- 指标缓存映射 SetIndexBuffer(0,ExtOpen); SetIndexBuffer(1,ExtHigh); SetIndexBuffer(2,ExtLow); SetIndexBuffer(3,ExtClose); SetIndexBuffer(4,ExtColor,INDICATOR_COLOR_INDEX); //--- 指定值,不显示 PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,INDICATOR_EMPTY_VALUE); //--- 指定用于在数据窗口显示的指标缓存名称 PlotIndexSetString(0,PLOT_LABEL,"Open;High;Low;Close"); //--- 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[]) { //--- 在时间序列设置直接索引 ArraySetAsSeries(open,false); ArraySetAsSeries(high,false); ArraySetAsSeries(low,false); ArraySetAsSeries(close,false); //--- 柱形变量计算开始 int start=prev_calculated; //--- 开始的InpNum*2柱不执行计算 if(start==0) { start+=InpNum*2; ExtStart=0; ExtCount=0; } //--- 如果只形成柱,检查下一个潜在极值 if(rates_total-start==1) start--; //--- 检查极值的柱形索引 int ext; //--- 指标值计算循环 for(int i=start;i<rates_total-1;i++) { //--- 在i柱上无初始绘制 ExtOpen[i]=0; ExtHigh[i]=0; ExtLow[i]=0; ExtClose[i]=0; //--- 用于检查的极值指数 ext=i-InpNum; //--- 检查本地最大值 if(IsMax(high,ext)) { //--- 强调极值蜡烛图 ExtOpen[ext]=open[ext]; ExtHigh[ext]=high[ext]; ExtLow[ext]=low[ext]; ExtClose[ext]=close[ext]; ExtColor[ext]=1; //--- 用中间色突出其他蜡烛图直至极值 FillCandles(open,high,low,close); //--- 改变变量颜色 ExtStart=ext+1; ExtCount=0; //--- 传递到下一个迭代 continue; } //--- 检查本地最小值 if(IsMin(low,ext)) { //--- 突出极值蜡烛图 ExtOpen[ext]=open[ext]; ExtHigh[ext]=high[ext]; ExtLow[ext]=low[ext]; ExtClose[ext]=close[ext]; ExtColor[ext]=2; //--- 用中间色突出其他蜡烛图直至极值 FillCandles(open,high,low,close); //--- 改变变量值 ExtStart=ext+1; ExtCount=0; //--- 传递到下一个迭代 continue; } //--- 增加无极值间隔数量 ExtCount++; } //--- 为下次调用返回 prev_calculated 值 return(rates_total); } //+------------------------------------------------------------------+ //| 检查当前数组元素是否本地最高 | //+------------------------------------------------------------------+ bool IsMax(const double &price[],const int ind) { //--- 间隔开始变量 int i=ind-InpNum; //--- 间隔时间结束 int finish=ind+InpNum+1; //--- 检查上半部间隔 for(;i<ind;i++) { if(price[ind]<=price[i]) return(false); } //--- 检查下半部间隔 for(i=ind+1;i<finish;i++) { if(price[ind]<=price[i]) return(false); } //--- 这是一个极值 return(true); } //+------------------------------------------------------------------+ //| 检查当前数组元素是否是本地最低 | //+------------------------------------------------------------------+ bool IsMin(const double &price[],const int ind) { //--- 间隔开始变量 int i=ind-InpNum; //--- 间隔时间结束 int finish=ind+InpNum+1; //--- 检查上半部间隔 for(;i<ind;i++) { if(price[ind]>=price[i]) return(false); } //--- 检查下半部间隔 for(i=ind+1;i<finish;i++) { if(price[ind]>=price[i]) return(false); } //--- 这是一个极值 return(true); } |