vn.py量化社区
By Traders, For Traders.
Member
avatar
加入于:
帖子: 10
声望: 0

各位前辈好,如果要实现程序在多个周期同时运行,不是老大课程上讲的先在15分钟判断方向,然后在5分钟上交易的那种,
是那种比如说在5分钟和30分钟各自独立的跑双均线策略,问题如下:
1:各个周期的订单会不会打架?我按照老大课程上的方法改了一个,但是单独跑5分钟回测和单独30分钟回测,两个分别的订单数量之和与以下程序实现的不相等
2:如果以下的程序用在实盘中,不考虑双均线是否盈利,只考虑程序照顾的全面程度还有什么需要改进和注意的地方?
以下是我修改的一个程序同时独立跑两个周期的代码,请各位指正,谢谢
from vnpy.app.cta_strategy import (
CtaTemplate,
StopOrder,
TickData,
BarData,
TradeData,
OrderData,
BarGenerator,
ArrayManager,
)
from vnpy.trader.constant import Interval

class 双周期(CtaTemplate):
""""""

# 策略作者
author = "Smart Trader"

# 定义参数
fast_window = 10
slow_window = 20

# 定义变量
fast_ma0 = 0.0
fast_ma1 = 0.0
slow_ma0 = 0.0
slow_ma1 = 0.0

# 添加参数和变量名到对应的列表
parameters = ["fast_window",  "slow_window" ]
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.bg5 = BarGenerator(
        self.on_bar,
        window=5,
        on_window_bar=self.on_5min_bar,
        interval=Interval.MINUTE
        )

    self.am5 = ArrayManager()

    self.bg30 = BarGenerator(
        self.on_bar,
        window=30,
        on_window_bar=self.on_30min_bar,
        interval=Interval.MINUTE
        )
    self.am30 = ArrayManager()

def on_init(self):
    """
    Callback when strategy is inited.
    """
    self.write_log("策略初始化")
    self.load_bar(10)

def on_start(self):
    """
    Callback when strategy is started.
    """
    self.write_log("策略启动")

def on_stop(self):
    """
    Callback when strategy is stopped.
    """
    self.write_log("策略停止")

def on_tick(self, tick: TickData):
    """
    Callback of new tick data update.
    """
    self.bg5.update_tick(tick)
    self.bg30.update_tick(tick)
def on_bar(self, bar: BarData):
    """
    Callback of new bar data update.
    """
    self.bg5.update_bar(bar)
    self.bg30.update_bar(bar)

def on_5min_bar(self,bar:BarData):
    am5 = self.am5
    # 更新K线到时间序列容器中
    am5.update_bar(bar)
    # 若缓存的K线数量尚不够计算技术指标,则直接返回
    if not am5.inited:
        return

    # 计算快速均线
    fast_ma = am5.sma(self.fast_window, array=True)
    self.fast_ma0 = fast_ma[-1]     # T时刻数值
    self.fast_ma1 = fast_ma[-2]     # T-1时刻数值

    # 计算慢速均线
    slow_ma = am5.sma(self.slow_window, array=True)
    self.slow_ma0 = slow_ma[-1]
    self.slow_ma1 = slow_ma[-2]

    # 判断是否金叉
    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)

    # 如果发生了金叉
    if cross_over:
        # 为了保证成交,在K线收盘价上加5发出限价单
        price = bar.close_price + 5

        # 当前无仓位,则直接开多
        if self.pos == 0:
            self.buy(price, 1)
        # 当前持有空头仓位,则先平空,再开多
        elif self.pos < 0:
            self.cover(price, 1)
            self.buy(price, 1)

    # 如果发生了死叉
    elif cross_below:
        price = bar.close_price - 5

        # 当前无仓位,则直接开空
        if self.pos == 0:
            self.short(price, 1)
        # 当前持有空头仓位,则先平多,再开空
        elif self.pos > 0:
            self.sell(price, 1)
            self.short(price, 1)

    self.put_event()   

def on_30min_bar(self,bar:BarData):
    am30 = self.am30

    # 更新K线到时间序列容器中
    am30.update_bar(bar)

    # 若缓存的K线数量尚不够计算技术指标,则直接返回
    if not am30.inited:
        return

    # 计算快速均线
    fast_ma = am30.sma(self.fast_window, array=True)
    self.fast_ma0 = fast_ma[-1]     # T时刻数值
    self.fast_ma1 = fast_ma[-2]     # T-1时刻数值

    # 计算慢速均线
    slow_ma = am30.sma(self.slow_window, array=True)
    self.slow_ma0 = slow_ma[-1]
    self.slow_ma1 = slow_ma[-2]

    # 判断是否金叉
    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)

    # 如果发生了金叉
    if cross_over:
        # 为了保证成交,在K线收盘价上加5发出限价单
        price = bar.close_price + 5

        # 当前无仓位,则直接开多
        if self.pos == 0:
            self.buy(price, 1)
        # 当前持有空头仓位,则先平空,再开多
        elif self.pos < 0:
            self.cover(price, 1)
            self.buy(price, 1)

    # 如果发生了死叉
    elif cross_below:
        price = bar.close_price - 5

        # 当前无仓位,则直接开空
        if self.pos == 0:
            self.short(price, 1)
        # 当前持有空头仓位,则先平多,再开空
        elif self.pos > 0:
            self.sell(price, 1)
            self.short(price, 1)

    self.put_event()        

def on_order(self, order: OrderData):
    """
    Callback of new order data update.
    """
    pass

def on_trade(self, trade: TradeData):
    """
    Callback of new trade data update.
    """
    self.put_event()

def on_stop_order(self, stop_order: StopOrder):
    """
    Callback of stop order update.
    """
    pass
Administrator
avatar
加入于:
帖子: 4220
声望: 241
  1. 多周期策略,只是为了能够调用不同周期上的数据产生交易信号,所有委托和持仓都还是在一个策略实例内,所以是会互相影响到的
  2. 一般不建议在多个周期上都有下单的操作,这种可以直接分成两个策略来跑
Member
avatar
加入于:
帖子: 10
声望: 0

感谢回复
如果在多个周期上都有下单的操作,分成两个策略来跑,
这种情况下我在一个商品上的30分钟和5分钟来跑相同的均线策略,相当于两个策略,他们分别开的单子应该不会相互干扰吧?

Administrator
avatar
加入于:
帖子: 4220
声望: 241

两个策略之间的所有数据:持仓、委托,都是独立的,不会互相影响

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