关于MarketPosition() 获取到的状态不对 后续DEMO提供
//------------------------------------------------------------------------ // 简称: MultiBOLLChannel_CloseEntry // 名称: 多品种BOLL通道交易系统(收盘价开仓版) // 类别: 策略应用 // 类型: 内建应用 //------------------------------------------------------------------------ Params Numeric MALength(20); // MA周期 Numeric StdDevLength(20); // 标准差周期 Numeric StdDevMultiplier(2); // 标准差倍数 Numeric MaxOpenSymbols(1); // 最大开仓品种数量 Vars Series<Numeric> MAValue; // MA值 Series<Numeric> StdDevValue; // 标准差 Series<Numeric> UpperBand; // 上轨 Series<Numeric> LowerBand; // 下轨 Natural CodeProperty codePro; // 合约属性 Global Numeric symbolCount; // 当前持有仓位的品种数量 Global Numeric w; // 用来调试 显示 OnBar中显示Range执行顺序 Global Numeric q; // 用来调试 显示 OnReady中显示Range执行顺序 Events OnReady() { w=0; q=0; symbolCount = 0; // 初始化持仓品种数 Range[0:DataSourceSize()-1] { q=q+1; Print("nReady "+ Text(q)); // 为每个图层设置回测参数 SetBackBarMaxCount(1 + Max(MALength, StdDevLength)); setPlotOption("MA", "begin-bar", MALength); setPlotOption("Upper", "begin-bar", MALength); setPlotOption("Lower", "begin-bar", MALength); // 获取合约属性 GetProperty(codePro); Print("symbol=" + codePro.symbol); } } OnBar(ArrayRef<Integer> indexs) { Numeric i; Range[i=0:DataSourceSize()-1] { GetProperty(codePro); // 当前品种属性 // 计算每个图层的指标 MAValue = AverageFC(Close, MALength); StdDevValue = StandardDev(Close, StdDevLength, 2); // 使用StandardDev函数 UpperBand = MAValue + StdDevMultiplier * StdDevValue; LowerBand = MAValue - StdDevMultiplier * StdDevValue; // 主图显示BOLL通道 PlotNumeric("MA", MAValue); PlotNumeric("Upper", UpperBand); PlotNumeric("Lower", LowerBand); // Commentary内容调整 String positionInfo = "当前持仓手数=" + Text(CurrentContracts()) + "\n当前持仓品种数=" + Text(symbolCount)+"\n方向="+Text(MarketPosition()); Commentary("当前图层索引=" + Text(i) + "\n合约=" + codePro.symbol + "\n当前持仓品种数=" + Text(symbolCount) + "\n" + positionInfo); // 交易逻辑(当前K线收盘满足条件,直接以收盘价交易) Print("开仓之前=" + Text(Date) + ",方向="+Text(MarketPosition())+", 合约=" + codePro.symbol + ", 当前持仓品种数=" + Text(symbolCount) +"最大持仓数=" + Text(MaxOpenSymbols)); Bool tradeReturn = false; // 开多条件:K线收盘上穿上轨,且未超过最大持仓品种数 If(MarketPosition() <> 1 && Close > UpperBand && symbolCount < MaxOpenSymbols) { Print("开多之前时间=" + Text(Date) + ",方向="+Text(MarketPosition())+", 合约=" + codePro.symbol + ", 当前持仓品种数=" + Text(symbolCount) +"最大持仓数=" + Text(MaxOpenSymbols)); tradeReturn=Buy(1,Close); // 固定开1手 if(tradeReturn) { if(MarketPosition() <> 0) { symbolCount = symbolCount + 1; } Print("[开多] 时间=" + Text(Date) + ",方向=" + Text(MarketPosition()) + ", 合约=" + codePro.symbol + ", 当前持仓品种数=" + Text(symbolCount) + "最大持仓数=" + Text(MaxOpenSymbols)); } Else { Print("[开多] 失败 时间=" + Text(Date) + ",方向="+Text(MarketPosition())+", 合约=" + codePro.symbol + ", 当前持仓品种数=" + Text(symbolCount) +"最大持仓数=" + Text(MaxOpenSymbols)); } } // 平多条件:K线收盘下穿MA20 If(MarketPosition() == 1 && Close < MAValue) { Print("平多之前时间=" + Text(Date) + ",方向="+Text(MarketPosition())+", 合约=" + codePro.symbol + ", 当前持仓品种数=" + Text(symbolCount) +"最大持仓数=" + Text(MaxOpenSymbols)); tradeReturn=Sell(0,Close); if(tradeReturn) { symbolCount=symbolCount-1; Print("[平多] 时间=" + Text(Date) + ",方向="+Text(MarketPosition())+", 合约=" + codePro.symbol + ", 当前持仓品种数=" + Text(symbolCount) +"最大持仓数=" + Text(MaxOpenSymbols)); } Else { Print("[平多] 失败 时间=" + Text(Date) + ",方向="+Text(MarketPosition())+", 合约=" + codePro.symbol + ", 当前持仓品种数=" + Text(symbolCount) +"最大持仓数=" + Text(MaxOpenSymbols)); } } // 开空条件:K线收盘下穿下轨,且未超过最大持仓品种数 If(MarketPosition() <> -1 && Close < LowerBand && symbolCount < MaxOpenSymbols) { Print("开空之前时间=" + Text(Date) + ",方向="+Text(MarketPosition())+", 合约=" + codePro.symbol + ", 当前持仓品种数=" + Text(symbolCount) +"最大持仓数=" + Text(MaxOpenSymbols)); tradeReturn=SellShort(1,Close); // 固定开1手 if(tradeReturn) { if(MarketPosition() <> 0) { symbolCount = symbolCount + 1; } Print("[开空] 时间=" + Text(Date) + ",方向="+Text(MarketPosition())+", 合约=" + codePro.symbol + ", 当前持仓品种数=" + Text(symbolCount) +"最大持仓数=" + Text(MaxOpenSymbols)); } Else { Print("[开空] 失败 时间=" + Text(Date) + ",方向="+Text(MarketPosition())+", 合约=" + codePro.symbol + ", 当前持仓品种数=" + Text(symbolCount) +"最大持仓数=" + Text(MaxOpenSymbols)); } } // 平空条件:K线收盘上穿MA20 If(MarketPosition() == -1 && Close > MAValue) { Print("平空之前时间=" + Text(Date) + ",方向="+Text(MarketPosition())+", 合约=" + codePro.symbol + ", 当前持仓品种数=" + Text(symbolCount) +"最大持仓数=" + Text(MaxOpenSymbols)); tradeReturn=BuyToCover(0,Close); if(tradeReturn) { symbolCount=symbolCount-1; Print("[平空] 时间=" + Text(Date) + ",方向="+Text(MarketPosition())+", 合约=" + codePro.symbol + ", 当前持仓品种数=" + Text(symbolCount) +"最大持仓数=" + Text(MaxOpenSymbols)); } Else { Print("[平空] 失败 时间=" + Text(Date) + ",方向="+Text(MarketPosition())+", 合约=" + codePro.symbol + ", 当前持仓品种数=" + Text(symbolCount) +"最大持仓数=" + Text(MaxOpenSymbols)); } } w=w+1; } } //------------------------------------------------------------------------ // 编译版本 GS2010.12.08 // 版权所有 TradeBlazer Software 2003-2025 // 更改声明 TradeBlazer Software保留对TradeBlazer平 // 台每一版本的TradeBlazer公式修改和重写的权利 //------------------------------------------------------------------------ 策略逻辑是 以BOLL通道 为基准 上穿上轨开多 下轨开空 中轨平仓。默认开仓1手设置了一个最大开仓品种的限制默认为1,以全局变量Global Numeric symbolCount; 作为判断。复现路径 先打开螺纹钢指数合约的K线,缩小到最早的时间,打开策略应用设置把所有指标勾选都去掉只显示K线, 然后添加沪铅 沪锡 沪锌 指数合约,选择切换策略,选择上面的策略 就会出现问题 100%出现6900行 两次平多