量化交易之回测篇 - 重写vnpy自带的双均线策略

"""

双均线策略作为测试期货回测器的一个测试策略, 在测试品种ag时出现了一个问题:

回测时ag净值曲线无最大回撤值,说明ag在双均线策略上无回撤,理论上这是不可能的;
排查后发现在vnpy自带的双均线策略的更新bar上出了问题;
慢均线的指标值一直是nan, 也就是说就算回测的bar已经足够多了, 该值还是更新不成功;
所以就直接废弃了vnpy自带的更新bar操作, 重写;

"""

from tqz_strategy.template import CtaTemplate
from public_module.object import BarData

class DoubleMaStrategy(CtaTemplate):
    """
    re write.
    """
    author = "tqz"

    fast_window = 30
    slow_window = 250

    lots_size = 0
    parameters = ["fast_window", "slow_window", "lots_size"]

    fast_ma0 = 0
    fast_ma1 = 0

    slow_ma0 = 0
    slow_ma1 = 0
    variables = ["fast_ma0", "fast_ma1", "slow_ma0", "slow_ma1"]


    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)

        self.bar_close_prices = []


    def on_init(self):
        """
        Callback when strategy is inited.
        """
        self.write_log(msg=f'strategy_name: {self.strategy_name} on_init.')
        pass

    def on_start(self):
        """
        Callback when strategy is started.
        """
        self.write_log(msg=f'strategy_name: {self.strategy_name} on_start.')
        pass

    def on_stop(self):
        """
        Callback when strategy is stopped.
        """
        self.write_log(msg=f'strategy_name: {self.strategy_name} on_stop.')
        pass


    def update_bars_close_prices(self, new_bar: BarData) -> bool:
        self.bar_close_prices.append(new_bar.close_price)
        if len(self.bar_close_prices) > self.slow_window:
            # update params
            self.slow_ma0 = sum(self.bar_close_prices[-self.slow_window:]) / self.slow_window
            self.slow_ma1 = sum(self.bar_close_prices[-self.slow_window-1:-1]) / self.slow_window
            self.fast_ma0 = sum(self.bar_close_prices[-self.fast_window:]) / self.fast_window
            self.fast_ma1 = sum(self.bar_close_prices[-self.fast_window-1:-1]) / self.fast_window

            bars_is_enough = True
        else:
            bars_is_enough = False

        return bars_is_enough


    def on_bar(self, bar: BarData):
        """
        Callback of new bar data update.
        """

        # 1. update self.bars_close_prices & update params.
        if self.update_bars_close_prices(new_bar=bar) is False:
            return

        # 2. trend direction.
        cross_over = self.fast_ma0 > self.slow_ma0 and self.fast_ma1 < self.slow_ma1
        cross_below = self.fast_ma0 < self.slow_ma0 and self.fast_ma1 > self.slow_ma1

        # 3. modify postion.
        if cross_over:
            if self.pos == 0:
                self.buy(bar.close_price, self.lots_size)
            elif self.pos < 0:
                self.cover(bar.close_price, self.lots_size)
                self.buy(bar.close_price, self.lots_size)
        elif cross_below:
            if self.pos == 0:
                self.short(bar.close_price, self.lots_size)
            elif self.pos > 0:
                self.sell(bar.close_price, self.lots_size)
                self.short(bar.close_price, self.lots_size)

        print(f'DoubleMaStrategy, bar.datetime: {bar.datetime}, bar.close_price: {bar.close_price}, self.fast_ma0: {round(self.fast_ma0, 3)}, self.fast_ma1: {round(self.fast_ma1, 3)}, self.slow_ma0: {round(self.slow_ma0, 3)}, self.slow_ma1: {round(self.slow_ma1, 3)}, pos: {self.pos}')

        self.put_event()

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值