#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);
}
|