策略逻辑:跌破布林线下轨有回升至下轨,开多单,至中轨处平仓,如跌破开仓价格的N倍atr(14),止损。开空的情况反之。每一个开平均做了plot,如图,开仓的手数设置为20。但在十字星处,未出现平仓开仓信号,为什么出现了平仓开仓,且手数为什么变成21手,请协助排查。代码如下:
//------------------------------------------------------------------------
// 简称: MeanReversion_Bollinger
// 名称: 均值回归_布林带通道
// 类别: 公式应用
// 类型: 用户应用
// 输出: Void
//------------------------------------------------------------------------
Params
Numeric ma_period(20); // 均线周期
Numeric stddev_multiple(2); // 标准差倍数
Numeric positionlots(20); // 开仓手数
Numeric atr_period(14); // ATR周期
Numeric atr_multiple(2); // 止损ATR倍数
Vars
Series<Numeric> mean_line(0); // 均值线
Series<Numeric> stddev_val(0); // 标准差序列,需回溯[1]
Series<Numeric> high_rail(0); // 上轨,需回溯[1]
Series<Numeric> low_rail(0); // 下轨,需回溯[1]
Series<Numeric> atr_val(0); // ATR序列,用于回溯开仓前一根K线的ATR
Numeric entry_atr; // 开仓位置ATR
Numeric long_stop_price; // 多单止损价
Numeric short_stop_price; // 空单止损价
Numeric long_entry_price;
Numeric short_entry_price;
Events
OnInit()
{
Range[0:DataCount - 1]
{
AddDataFlag(Enum_Data_RolloverBackWard()); //设置后复权
AddDataFlag(Enum_Data_RolloverRealPrice()); //真实价格
AddDataFlag(Enum_Data_AutoSwapPosition()); //自动换仓
AddDataFlag(Enum_Data_IgnoreSwapSignalCalc()); //忽略换仓信号计算
}
}
OnBar(ArrayRef<Integer> indexs)
{
If(CurrentBar <ma_period Or CurrentBar < ma_period) //防御性检查
{
Return;
}
mean_line = Average(Close, ma_period);
stddev_val = StandardDev(Close, ma_period, 1);
high_rail = mean_line + stddev_multiple * stddev_val;
low_rail = mean_line - stddev_multiple * stddev_val;
atr_val = AvgTrueRange(ma_period);
PlotNumeric("mean_line", mean_line);
PlotNumeric("high_rail", high_rail);
PlotNumeric("low_rail", low_rail);
If(MarketPosition <> 0 And BarsSinceEntry == 0) //取值开仓位置的atr值
{
entry_atr = atr_val;
}
If(MarketPosition <> 0 And entry_atr <= 0) //异常检查,如有异常,重新弄赋值
{
entry_atr = atr_val;
}
long_stop_price = longEntryPrice - atr_multiple * entry_atr; //多单止损价格
short_stop_price = shortEntryPrice + atr_multiple * entry_atr; //空单止损价格
If(MarketPosition <> 1 and close[1] < low_rail[1] And Open >= low_rail[1]) //开多单
{
Buy(positionlots, Open);
PlotString("跳多","跳多",Low,Red);
}
If(MarketPosition <> 1 And Low < low_rail[1] And High >= low_rail[1])
{
Buy(positionlots, low_rail[1]);
PlotString("实多","实多",Low,Red);
}
If(MarketPosition == 1 And Low <= long_stop_price And BarsSinceEntry > 0) //多单止损
{
Sell(0, Min(Open, long_stop_price));
PlotString("多损","多损",Low,Red);
}
Else If(MarketPosition == 1 And High >= mean_line[1] And BarsSinceEntry > 0) //多单止盈
{
Sell(0, Max(Open, mean_line[1]));
PlotString("多盈","多盈",Low,Red);
}
If(MarketPosition <> -1 And Close[1] > high_rail[1] And Open <= high_rail[1]) //开空单
{
SellShort(positionlots, Open);
PlotString("跳空","跳空",Low,Red);
}
If(MarketPosition <> -1 And High > high_rail[1] And Low <= high_rail[1])
{
SellShort(positionlots, high_rail[1]);
PlotString("实空","实空",Low,Red);
}
If(MarketPosition == -1 And High >= short_stop_price And BarsSinceEntry > 0) //空单止损
{
BuyToCover(0, Max(Open, short_stop_price));
PlotString("控损","控损",Low,Red);
}
Else If(MarketPosition == -1 And low <= mean_line[1] And BarsSinceEntry > 0) //空单止盈
{
BuyToCover(0, Min(Open, mean_line[1]));
PlotString("空盈","空盈",Low,Red);
}
}
