vn.py官网
开源量化社区
Member
avatar
加入于:
帖子: 11
声望: 0

一个用portfolio_strategy模块,写的 多标的 双均线策略,有2个标的,策略的数据源是 mongodb,不同的标的使用,不同的表
(1)请大家看看,有什么地方可以修改,优化,简洁一些 ?
我指的优化,不是指策略本身,意思指,在使用 portfolio_strategy模块方面,有什么改善的地方?
(2)如果建立股票池,股票池的 标的和数量 ,过一段时间就会改变,使用portfolio_strategy模块,策略怎么样写?
谢谢大家

from vnpy.app.cta_strategy.backtesting import BacktestingEngine

from datetime import datetime
from importlib import reload

import vnpy.app.portfolio_strategy
reload(vnpy.app.portfolio_strategy)

from vnpy.app.portfolio_strategy import BacktestingEngine

import vnpy.app.portfolio_strategy.strategies.pair_trading_strategy as stg
reload(stg)

from vnpy.trader.constant import Interval, Direction, Offset

from typing import List, Dict
from vnpy.trader.object import BarData, TickData, OrderData, TradeData

from vnpy.app.portfolio_strategy import StrategyTemplate, StrategyEngine
from vnpy.trader.utility import BarGenerator, ArrayManager
from vnpy.trader.object import TickData, BarData

engine = BacktestingEngine()

engine.set_parameters(
vt_symbols=["000001.SZSE","601518.SSE"],
interval=Interval.MINUTE,
start=datetime(2017, 7, 1),
end=datetime(2020, 9, 21),
rates={"000001.SZSE": 0/10000,"601518.SSE": 0/10000},
slippages={"000001.SZSE": 00,"601518.SSE": 0},
sizes={"000001.SZSE": 10,"601518.SSE": 10},
priceticks={"000001.SZSE": 1,"601518.SSE": 1},
capital=1_000_000,
collection_names={"000001.SZSE":'000001_bar',"601518.SSE":'601518_bar'}
)

class DemoStrategy2(StrategyTemplate):
""""""

author = "zhp168"

fast_window_1 = 10
slow_window_1 = 20
fast_ma0_1 = 0.0
fast_ma1_1 = 0.0
slow_ma0_1 = 0.0
slow_ma1_1 = 0.0

fast_window_2 = 10
slow_window_2 = 20
fast_ma0_2 = 0.0
fast_ma1_2 = 0.0
slow_ma0_2 = 0.0
slow_ma1_2 = 0.0



parameters = ["fast_window","slow_window"]
variables = ["fast_ma0","fast_ma1","slow_ma0","slow_ma1"]

def __init__(
    self,
    strategy_engine: StrategyEngine,
    strategy_name: str,
    vt_symbols: List[str],
    setting: dict
):
    """"""
    super().__init__(strategy_engine, strategy_name, vt_symbols, setting)
    self.bg = BarGenerator(self.on_bar)

    self.am_1 = ArrayManager()
    self.am_2 = ArrayManager()

    self.vt_symbol_1 = vt_symbols[0]
    self.vt_symbol_2 = vt_symbols[1]


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

    self.load_bars(20)

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.bg.update_tick(tick)

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

    bars = {bar.vt_symbol: bar}
    self.on_bars(bars)

def on_bars(self, bars: Dict[str, BarData]):
    """"""
    self.cancel_all()

    bar_1 = bars[self.vt_symbol_1]
    am_1 = self.am_1
    am_1.update_bar(bar_1)
    if not am_1.inited:
        return

    bar_2 = bars[self.vt_symbol_2]
    am_2 = self.am_2
    am_2.update_bar(bar_2)
    if not am_2.inited:
        return


    # 第一个标的,计算快速均线
    fast_ma_1 = am_1.sma(self.fast_window_1, array=True)

    self.fast_ma0_1 = fast_ma_1[-1]  # T时刻数值
    self.fast_ma1_1 = fast_ma_1[-2]  # T-1时刻数值

    # 第二个标的,计算快速均线
    fast_ma_2 = am_2.sma(self.fast_window_2, array=True)
    self.fast_ma0_2 = fast_ma_2[-1]  # T时刻数值
    self.fast_ma1_2 = fast_ma_2[-2]  # T-1时刻数值



    # 第一个标的,计算慢速均线
    slow_ma_1 = am_1.sma(self.slow_window_1, array=True)
    self.slow_ma0_1 = slow_ma_1[-1]
    self.slow_ma1_1 = slow_ma_1[-2]

    # 第二个标的,计算慢速均线
    slow_ma_2 = am_2.sma(self.slow_window_2, array=True)
    self.slow_ma0_2 = slow_ma_2[-1]
    self.slow_ma1_2 = slow_ma_2[-2]



    # 获取仓位
    pos_1 = self.get_pos(self.vt_symbol_1)
    pos_2 = self.get_pos(self.vt_symbol_2)


    # 判断是否金叉
    cross_over_1 = (self.fast_ma0_1 > self.slow_ma0_1 and
                  self.fast_ma1_1 < self.slow_ma1_1)

    cross_over_2 = (self.fast_ma0_2 > self.slow_ma0_2 and
                    self.fast_ma1_2 < self.slow_ma1_2)

    # 判断是否死叉
    cross_below_1 = (self.fast_ma0_1 < self.slow_ma0_1 and
                   self.fast_ma1_1 > self.slow_ma1_1)

    cross_below_2 = (self.fast_ma0_2 < self.slow_ma0_2 and
                     self.fast_ma1_2 > self.slow_ma1_2)

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

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

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

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

---------------------------------------------------------------------------------------------

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

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

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

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

    self.put_event()

def update_trade(self, trade: TradeData):
    print("股票编号:", trade.symbol, "成交时间:", trade.datetime, "成交价格:", trade.price)
    print("方向:", trade.direction, trade.direction.value, "offset:", trade.offset, "成交量:", trade.volume)


engine.add_strategy(DemoStrategy2,{})

engine.load_data()
engine.run_backtesting()
df = engine.calculate_result()
engine.calculate_statistics()
engine.show_chart()

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

strong text

Member
avatar
加入于:
帖子: 2357
声望: 148

可参考https://www.vnpy.com/forum/topic/3180-ru-he-yong-portfolio-strategyshi-xian-shi-zhi-zui-xiao-de-10zhi-gu-piao-yu-qi-huo-dui-chong

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

谢谢

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

mark

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

沪公网安备 31011502017034号