#property description "The indicator analyzes data for the last month and draws all candlesticks with small"
#property description "and large tick volumes. The tick volume array is sorted out"
#property description "to define such candlesticks. The candlesticks having the volumes comprising the first InpSmallVolume"
#property description "per cent of the array are considered small. The candlesticks having the tick volumes comprising "
#property description "the last InpBigVolume per cent of the array are considered large."
//--- 指标设置
#property indicator_chart_window
#property indicator_buffers 5
#property indicator_plots 1
//--- 图
#property indicator_label1 "VolumeFactor"
#property indicator_type1 DRAW_COLOR_CANDLES
#property indicator_color1 clrDodgerBlue,clrOrange
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- 预定义常量
#define INDICATOR_EMPTY_VALUE 0.0
//--- 输入参数
input int InpSmallVolume=15; // 小型交易量的百分比值 (<50)
input int InpBigVolume=20; // 大型交易量的百分比值 (<50)
//--- 分析起始时间 (将会改变)
datetime ExtStartTime;
//--- 指标缓存区
double ExtOpenBuff[];
double ExtHighBuff[];
double ExtLowBuff[];
double ExtCloseBuff[];
double ExtColorBuff[];
//--- 显示蜡烛图的交易量边界值
long ExtLeftBorder=0;
long ExtRightBorder=0;
//+------------------------------------------------------------------+
//| 接收跳动量的边界值 |
//+------------------------------------------------------------------+
bool GetVolumeBorders(void)
{
//--- 变量
datetime stop_time; // 复制结束时间
long buff[]; // 用于复制的缓冲区
//--- 结束时间是当前时间
stop_time=TimeCurrent();
//--- 起始时间比当前时间早一个月
ExtStartTime=GetStartTime(stop_time);
//--- 接收跳动量的值
ResetLastError();
if(CopyTickVolume(Symbol(),Period(),ExtStartTime,stop_time,buff)==-1)
{
//--- 接收数据失败,返回false启动重新计算的命令
PrintFormat("Failed to receive tick volume values. Error code = %d",GetLastError());
return(false);
}
//--- 计算数组大小
int size=ArraySize(buff);
//--- 分类数组
ArraySort(buff);
//--- 定义跳动量左侧和右侧的边界值
ExtLeftBorder=buff[size*InpSmallVolume/100];
ExtRightBorder=buff[(size-1)*(100-InpBigVolume)/100];
//--- 成功执行
return(true);
}
//+------------------------------------------------------------------+
//| 接收比已过月份少一个月的数据 |
//+------------------------------------------------------------------+
datetime GetStartTime(const datetime stop_time)
{
//--- 转换结束时间到MqlDateTime类型结构变量
MqlDateTime temp;
TimeToStruct(stop_time,temp);
//--- 接收少一个月的数据
if(temp.mon>1)
temp.mon-=1; // 当前月份不是今年的第一个月,因此之前月份减一
else
{
temp.mon=12; // 当前月份是今年的第一个月,因此,前一个月是12月,
temp.year-=1; // 而年份数减一
}
//--- 天数将不会超过28
if(temp.day>28)
temp.day=28;
//--- 返回获得的日期
return(StructToTime(temp));
}
//+------------------------------------------------------------------+
//| 自定义指标初始函数 |
//+------------------------------------------------------------------+
int OnInit()
{
//--- 检查是否输入参数满足条件
if(InpSmallVolume<0 || InpSmallVolume>=50 || InpBigVolume<0 || InpBigVolume>=50)
{
Print("Incorrect input parameters");
return(INIT_PARAMETERS_INCORRECT);
}
//--- 指标缓冲区映射
SetIndexBuffer(0,ExtOpenBuff);
SetIndexBuffer(1,ExtHighBuff);
SetIndexBuffer(2,ExtLowBuff);
SetIndexBuffer(3,ExtCloseBuff);
SetIndexBuffer(4,ExtColorBuff,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[])
{
//--- 检查未处理的柱形是否仍然存在
if(prev_calculated<rates_total)
{
//--- 接收交易量右侧和左侧的新边界值
if(!GetVolumeBorders())
return(0);
}
//--- 启动柱形计算的变量
int start=prev_calculated;
//--- 如果在前一个订单号已经计算指标值,那么使用最近的柱形
if(start>0)
start--;
//--- 设置时间序列的直接标引
ArraySetAsSeries(time,false);
ArraySetAsSeries(open,false);
ArraySetAsSeries(high,false);
ArraySetAsSeries(low,false);
ArraySetAsSeries(close,false);
ArraySetAsSeries(tick_volume,false);
//--- 计算指标值的循环
for(int i=start;i<rates_total;i++)
{
//--- 从初始日期填写蜡烛图
if(ExtStartTime<=time[i])
{
//--- 如果值不少于右侧边界,则填写蜡烛图
if(tick_volume[i]>=ExtRightBorder)
{
//--- 接收数据绘制蜡烛图
ExtOpenBuff[i]=open[i];
ExtHighBuff[i]=high[i];
ExtLowBuff[i]=low[i];
ExtCloseBuff[i]=close[i];
//--- 闪蓝色
ExtColorBuff[i]=0;
//--- 继续循环
continue;
}
//--- 如果值不超过左侧边界,则填写蜡烛图
if(tick_volume[i]<=ExtLeftBorder)
{
//--- 接收数据绘制蜡烛图
ExtOpenBuff[i]=open[i];
ExtHighBuff[i]=high[i];
ExtLowBuff[i]=low[i];
ExtCloseBuff[i]=close[i];
//--- 桔色
ExtColorBuff[i]=1;
//--- 继续循环
continue;
}
}
//--- 为计算中不包含的柱设置空值
ExtOpenBuff[i]=INDICATOR_EMPTY_VALUE;
ExtHighBuff[i]=INDICATOR_EMPTY_VALUE;
ExtLowBuff[i]=INDICATOR_EMPTY_VALUE;
ExtCloseBuff[i]=INDICATOR_EMPTY_VALUE;
}
//--- 返回prev_calculated的值以便下次调用
return(rates_total);
}
|