自定义指标-价格密集指标
一、指标原理
价格密集指标用于衡量市场价格的噪声程度,其值越高表示价格在特定周期内的波动越密集(噪声大),适合震荡交易;值越低表示价格波动越稀疏(噪声小),适合趋势交易。
计算公式:
- 计算周期内每根K线的高低价差(最高价-最低价)。
- 累加所有K线的高低价差,得到总和
Σ(High-Low)
。 - 计算周期内的整体价格区间(周期内最高价-周期内最低价),即
MaxHigh - MinLow
。 - 价格密度 =
Σ(High-Low) / (MaxHigh - MinLow)
。
二、代码实现
cpp
/*
#property indicator_separate_window
#property indicator_chart_window
*/
#property indicator_separate_window
#property indicator_buffers 4
#property indicator_plots 1
#property indicator_type1 DRAW_LINE // 画线
#property indicator_color1 clrDarkOrange // 颜色
#property indicator_level1 5
#property indicator_levelwidth 1
#property indicator_levelstyle STYLE_DOT
input int InpPeriod = 20; // 周期
input double InpNoiseThresholdLevel = 5; // 水平线
double PriceDensityBuffer[];
double SumOfIndHighLowsBuffer[];
double HighestHighBuffer[];
double LowestLowBuffer[];
int OnInit(){
// 绑定指定的指标缓冲区
SetIndexBuffer(0,PriceDensityBuffer,INDICATOR_DATA);
// 辅助计算缓冲区
SetIndexBuffer(1,SumOfIndHighLowsBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(2,HighestHighBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(3,LowestLowBuffer,INDICATOR_CALCULATIONS);
// 设置指标值的精度
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
// 从那根K线开始画
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpPeriod);
IndicatorSetString(INDICATOR_SHORTNAME,"价格密度指标("+IntegerToString(InpPeriod) + ")");
IndicatorSetDouble(INDICATOR_LEVELVALUE,0,InpNoiseThresholdLevel);
IndicatorSetInteger(INDICATOR_LEVELCOLOR,0,clrYellow);
IndicatorSetString(INDICATOR_LEVELTEXT,0,"High values=high noise");
return INIT_SUCCEEDED;
}
int OnCalculate(const int rates_total, // 当前可用的K线数量
const int prev_calculated, // 上次调用OnCalculate的返回值
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[])
{
// 判断K线总数是否足够
if(rates_total <= InpPeriod) return (0);
// 确定计算的其实位置, 从哪一根K线开始计算
// 如果prev_calculated为0, 说明是第一次调用, 从InpPeriod开始计算
// 否则 从上次计算的K线位置开始计算
int limit =0 ;
if(prev_calculated == 0) limit = InpPeriod;
else limit = prev_calculated;
for(int i=limit; i<rates_total; i++)
{
// 初始化当前索引i的累积高低差, 最高高价, 最低低价
SumOfIndHighLowsBuffer[i] = 0;
HighestHighBuffer[i] = DBL_MIN;
LowestLowBuffer[i] = DBL_MAX;
// 在给定周期InpPeriod内 累加每个周期的高低差,并更新最高高价和最低低价
for(int iLoop= i-1;iLoop>i-InpPeriod;iLoop--){
SumOfIndHighLowsBuffer[i] += high[iLoop] - low[iLoop];
if(high[iLoop] > HighestHighBuffer[i]){
HighestHighBuffer[i] = high[iLoop];
}
if(low[iLoop] < LowestLowBuffer[i]){
LowestLowBuffer[i] = low[iLoop];
}
}
// 更新最高高价和 最低低价
double highestHigh = MathMax(HighestHighBuffer[i],high[i]);
double lowestLow = MathMin(LowestLowBuffer[i],low[i]);
// 计算价格密度
if(highestHigh-lowestLow !=0){
PriceDensityBuffer[i] = (SumOfIndHighLowsBuffer[i] + (high[i]-low[i])) / (highestHigh-lowestLow);
}else{
PriceDensityBuffer[i] = 0.0;
}
}
return (rates_total);
}