VeighNa量化社区
你的开源社区量化交易平台 | vn.py | vnpy
Member
avatar
加入于:
帖子: 1
声望: 0

用了几种方法都不行
self.sell(tick.last_price, abs(self.pos))
self.sell(tick.last_price, abs(self.pos), stop=True)
self.sell(0, abs(self.pos))
self.sell(tick.last_price-4, abs(self.pos))

日志:
2026-06-13 20:05:18.116 策略初始化(最终修复版)
2026-06-13 20:05:18.117 策略启动
2023-08-01 09:29:00.000 进入新交易日: 2023-08-01
2023-08-01 09:56:02.000 开多仓 1 手 @ 6519.80 (触发价 6519.60)
2023-08-01 14:55:00.000 强制平多仓 @ 6510.40
2023-08-01 14:55:01.000 强制平多仓 @ 6510.20
2023-08-01 14:55:02.000 强制平多仓 @ 6510.20
2023-08-01 14:55:03.000 强制平多仓 @ 6510.80
2023-08-01 14:55:04.000 强制平多仓 @ 6510.40
2023-08-01 14:55:05.000 强制平多仓 @ 6510.60
2023-08-01 14:55:06.000 强制平多仓 @ 6510.20
2023-08-01 14:55:07.000 强制平多仓 @ 6510.60

Super Moderator
avatar
加入于:
帖子: 128
声望: 15

我来帮你分析这个问题。从日志看,策略多次发送平仓指令但都没有成交,这通常与tick级回测的成交机制有关。让我先查询相关文档和源码。

让我进一步查询CTA回测引擎的成交逻辑源码:

现在我找到问题了!让我查看策略模板中sell方法的实现来确认:

找到问题了!这是tick级回测成交机制导致的。让我详细解释:

问题原因

在VeighNa的tick级回测中,限价单的成交判断逻辑与K线回测不同(见 backtesting.pycross_limit_order 方法):

# TICK模式下:
long_cross_price = self.tick.ask_price_1   # 买入用卖一价判断
short_cross_price = self.tick.bid_price_1  # 卖出用买一价判断

# 卖出成交条件:委托价格 <= 买一价
short_cross: bool = (
    order.direction == Direction.SHORT
    and order.price <= short_cross_price
)

关键问题:你使用 tick.last_price 作为委托价,但tick级回测中卖出委托必须与买一价(bid_price_1)比较,而不是最新价。

通常情况下盘口关系是:

bid_price_1 <= last_price <= ask_price_1

所以你以 last_price 委托卖出,价格往往高于买一价,无法满足 委托价 <= 买一价 的成交条件。

解决方案

在tick级回测中,平仓应该使用买一价(bid_price_1)

# 平多仓 - 使用买一价
self.sell(tick.bid_price_1, abs(self.pos))

# 或者为了保险,用更低的价格确保成交
self.sell(tick.bid_price_1 - self.pricetick, abs(self.pos))

同理,开仓买入应该用卖一价(ask_price_1)

# 开多仓 - 使用卖一价
self.buy(tick.ask_price_1, volume)

# 或者为了保险,用更高的价格确保成交
self.buy(tick.ask_price_1 + self.pricetick, volume)

参考代码

template.pyTargetPosTemplate 类中,官方示例也是这么写的:

if pos_change > 0:
    long_price = self.last_tick.ask_price_1 + self.tick_add
else:
    short_price = self.last_tick.bid_price_1 - self.tick_add

总结

操作 K线回测 Tick级回测
买入 bar.close_price tick.ask_price_1
卖出 bar.close_price tick.bid_price_1

修改你的平仓代码为:

self.sell(tick.bid_price_1, abs(self.pos))

这样应该就能正常成交了。

© 2015-2022 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

【用户协议】
【隐私政策】
【免责条款】