VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 42
声望: 4

最近在模拟盘测试海龟策略,对vnpy2.1.6版自带海龟策略的以下代码有所疑问:

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        if trade.direction == Direction.LONG:
            self.long_entry = trade.price
            self.long_stop = self.long_entry - 2 * self.atr_value
        else:
            self.short_entry = trade.price
            self.short_stop = self.short_entry + 2 * self.atr_value

上面代码定义了收到成交回报时所做的处理,即有新的成交时,立即设置对应的止损价。
从逻辑上看,有两点存疑:
1.上述处理没有区分成交是开仓还是平仓。如果是开仓,则没有问题。但如果是平仓,实际上是不应该这这里设置止损价的。比方原有一个在5000价位开的多单,止损价原来设置的为4950。当价格跌到4950时,通过一个空单平仓了所开的多单。根据以上代码逻辑,这个时候会设置一个对应空单(就是在4950成交的平多单)的止损价。假设是50点的止损,那么这个止损单会设置在5000。那么当价格涨到5000时,会自动开一个买单(根据on_bar逻辑,假设pos不空时,会在on_bar里产生这个买单)。但实际上这个买单是不应该开的。
2.如果成交的是开仓,上述代码只是设置了止损价,并没有立刻生成对应的停损单,而是要等到下一根K线产生时,才会在on_bar里生成对应的停损单。假设策略的周期是日线,当天开了仓,则需要等到第二天才能生成停损单。如果当天发生了黑天鹅事件,那么损失会很可怕。所以在开仓完后,不光要生成止损价,而且需要立刻设置对应的停损单。
以上是在阅读代码以及测试策略所发现的两个问题,我对on_trade做了个修改:

    def on_trade(self, trade: TradeData):
        """
        Callback of new trade data update.
        """
        # 只在开仓时设置止损价格
        if not (trade.offset == Offset.OPEN):
            return

        # 如果有开仓,则立刻设置对应的止损单
        if trade.direction == Direction.LONG:
            self.long_entry = trade.price
            self.long_stop = self.long_entry - 2 * self.atr_value
            print("%s: 多单成交价格:long_entry = %.1f" % (self.vt_symbol, self.long_entry))
            print("%s: 设置多单的止损价格:long_stop = %.1f" % (self.vt_symbol, self.long_stop))
            # 计算多单的止损价
            sell_price = max(self.long_stop, self.exit_down)
            # 如果有多头仓位,则设置多单的止损单
            print("long_stop = %d, self.exit_down = %d" % (self.long_stop, self.exit_down))
            print("%s: in on_trade(), 设置多头止损单,sell_price:%.1f, vol:%d" % (
                self.vt_symbol, sell_price, abs(trade.volume)))
            self.sell(sell_price, abs(trade.volume), True)
        elif trade.direction == Direction.SHORT:
            self.short_entry = trade.price
            self.short_stop = self.short_entry + 2 * self.atr_value
            print("%s: 空单成交价格:short_entry = %.1f" % (self.vt_symbol, self.short_entry))
            print("%s: 设置空单的止损价格:short_stop = %.1f" % (self.vt_symbol, self.short_stop))
            # 计算空单的止损价
            cover_price = min(self.short_stop, self.exit_up)
            # 如果有空头仓位,则设置空单的止损单
            print("short_stop = %d, self.exit_up = %d" % (self.short_stop, self.exit_up))
            print("%s: in on_trade(), 设置空头止损单,cover_price:%.1f, vol:%d" % (
                self.vt_symbol, cover_price, abs(trade.volume)))
            self.cover(cover_price, abs(trade.volume), True)

上述代码大家也可以一起来做个检查,看看是否有不妥之处。

Member
avatar
加入于:
帖子: 33
声望: 0

赞一个!正在为止损单太晚头疼,非常好的解决方案!

Member
avatar
加入于:
帖子: 8
声望: 0

海龟的逻辑是:平仓的时候,所有仓位全平,此时self.pos ==0,下一根bar传入的时候,on_bar会自动设置self.long_stop=0,self.short_stop=0。应该是不影响计算结果的

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

沪公网安备 31011502017034号

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