vnpy 123–跑起来一个最简单的量化交易的程式

上周使用了掘金的平台来跑起来一个简单的无脑买nasdaq 的协议。
但是掘金本身是一个闭源的平台,在交易品种上面远远不比不上开源平台的vnpy
另外,vn的论坛是很活跃的所以在这里就想对vn的平台来进行探索。
准备实现最简单的交易策略,以及实现vn平台的搬转套利。

安装配置

这里在 vnpy-github已经有很好的介绍,基本已经做到了傻瓜式安装所以基本没有过多的坑,但是在 ubuntu 下面是有部分的坑。解决完成之后也是能使用的。

初步了解

关于入门的教程在 vnpy专栏 有了比较详尽的入门内容。

vn.py快速入门1 – 环境准备
vn.py快速入门3 – 数字货币BITMEX
vn.py快速入门6 – 开发第一个量化策略
vn.py快速入门7 – 历史数据回测优化
vn.py快速入门8 – 策略实盘自动交易

在这里主要是来实现一个数字货币使用的一个量化程序。所以就在这里选取了这么几个章节来进行操作。量化的第一部就是获取历史数据用来进行策略的验证。之后就是来实现交易程序,回测之后再进行实盘。

数据获取

这里有一点,数据源是使用的bitmex的历史数据源。但是由于其服务是在境外的。所以连接质量不好做保障。需要使用一点科学的方法。来进行数据的访问。
https://www.vnpy.com/docs/cn/cta_backtester.html#id3
vnpy 里面已经实现了 bitmex 的数据拉取的逻辑,可以直接在 CTA回测模块里面来进行策略下载

交易策略

有了回测用的历史数据之后就就可以,来编写策略了。
这里使用的策略是使用的教程中的例示配置。

from vnpy.app.cta_strategy import (
    CtaTemplate,
    StopOrder,
    TickData,
    BarData,
    TradeData,
    OrderData,
    BarGenerator,
    ArrayManager,
)

class DemoStrategy(CtaTemplate):
    """演示用的简单双均线"""
    # 策略作者
    author = "Smart Trader"
    # 定义参数
    fast_window = 13
    slow_window = 39
    volume = 1

    # 定义变量
    fast_ma0 = 0.0
    fast_ma1 = 0.0
    slow_ma0 = 0.0
    slow_ma1 = 0.0
    # 添加参数和变量名到对应的列表
    parameters = ["fast_window", "slow_window","volume"]
    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)
        # K线合成器:从Tick合成分钟K线用
        self.bg = BarGenerator(self.on_bar)
        # 时间序列容器:计算技术指标用
        self.am = ArrayManager()

    def on_init(self):
        """
        当策略被初始化时调用该函数。
        """
        # 输出个日志信息,下同
        self.write_log("策略初始化")
        # 加载10天的历史数据用于初始化回放
        self.load_bar(10)

    def on_start(self):
        """
        当策略被启动时调用该函数。
        """
        self.write_log("策略启动")
        # 通知图形界面更新(策略最新状态)
        # 不调用该函数则界面不会变化
        self.put_event()

    def on_stop(self):
        """
        当策略被停止时调用该函数。
        """
        self.write_log("策略停止")
        self.put_event()

    def on_tick(self, tick: TickData):
        """
        通过该函数收到Tick推送。
        """
        self.bg.update_tick(tick)

    def on_bar(self, bar: BarData):
        """
        通过该函数收到新的1分钟K线推送。
        """
        am = self.am
        # 更新K线到时间序列容器中
        am.update_bar(bar)
        # 若缓存的K线数量尚不够计算技术指标,则直接返回
        if not am.inited:
            return

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

        # 计算慢速均线
        slow_ma = am.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, self.volume)
            # 当前持有空头仓位,则先平空,再开多
            elif self.pos < 0:
                self.cover(price, self.volume)
                self.buy(price, self.volume)

        # 如果发生了死叉
        elif cross_below:
            price = bar.close_price - 5
            # 当前无仓位,则直接开空
            if self.pos == 0:
                self.short(price, self.volume)

            # 当前持有空头仓位,则先平多,再开空
            elif self.pos > 0:
                self.sell(price, self.volume)
                self.short(price, self.volume)
        self.put_event()

    def on_order(self, order: OrderData):
        """
        通过该函数收到委托状态更新推送。
        """
        pass

    def on_trade(self, trade: TradeData):
        """
        通过该函数收到成交推送。
        """
        # 成交后策略逻辑仓位发生变化,需要通知界面更新。
        self.put_event()

    def on_stop_order(self, stop_order: StopOrder):
        """
        通过该函数收到本地停止单推送。
        """
        pass

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注