VeighNa量化社区
你的开源社区量化交易平台
ny
ny's Avatar
Member
离线
9 帖子
声望: 11

折腾了好久,终于搞定了,头秃头秃~
考完试没事情干,打算在服务器上安装最新版vnpy,看了网上很多教程资料,一直安装出错
卡在最后一步就是安装不上去,最后一步步排查把问题解决了,恰巧看到论坛有朋友提问一样
的问题就发个帖子。其中很多就是论坛的教程,感谢前人的肩膀,给我踩了下/😀😀😀

本人的环境:ubuntu18.04 腾讯云
使用工具:xshell flashfxp UltraEdit
管理员root用户

这一步是安装相关依赖,在论坛看到的
sudo vim /etc/apt/sources.list.d/pgdg.list
sudo apt-get update
deb http://apt.postgresql.org/pub/repos/apt/ bionic-pgdg main
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get install libpq-dev

安装anaconda
sudo apt-get install build-essential
bash Anaconda3-2019.07-Linux-x86_64.sh

配置anaconda为python默认解释器
vim /etc/profile
export PATH=/root/anaconda3/bin:$PATH
source /etc/profile

安装talib
tar -xvf ta-lib-0.4.0-src.tar.gz
cd ta-lib
./configure
make
make install
vim /etc/profile
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
source /etc/profile
pip install ta-lib

升级gcc编译器
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update
sudo apt install gcc-9 g++-9
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 60 --slave /usr/bin/g++ g++ /usr/bin/g++-9

现在去安装是不能成功的,会报一大堆的问题还得修改一点东西

修改相关文件配置(解决编译失败等问题)大部分都是在这个环节出的问题
问题出在安装文件中setup.py文件中,个别的api无法编译或许是库的问题c++找不到
经过排查问题在vones这个api上面,只要把vone相关的代码注释掉就可以正常安装

#    vnoes = Extension(
#        name="vnpy.api.oes.vnoes",
#        sources=gather_autocxxpy_generated_files(
#            "vnpy/api/oes/vnoes/generated_files/",
#        ),
#        include_dirs=["vnpy/api/oes/vnoes/include",
#                      "vnpy/api/oes/vnoes/include/oes"],
#        define_macros=[("BRIGAND_NO_BOOST_SUPPORT", "1")],
#        undef_macros=[],
#        library_dirs=["vnpy/api/oes/vnoes/libs"],
#        libraries=["oes_api"],
#        extra_compile_args=compiler_flags,
#        extra_link_args=extra_link_args,
#        runtime_library_dirs=runtime_library_dirs,
#        depends=[],
#        language="cpp",
#    )


        ext_modules = [
            vnctptd, vnctpmd,
            vnxtptd, vnxtpmd,
            vnsgittd, vnsgitmd,
            vnksgoldmd, vnksgoldtd]
#            vnoes   //这个地方需要注释掉
#       ]

#    ext_modules = check_extension_build_flag(
#        ext_modules, "VNPY_BUILD_OES", vnoes)
上面两行也注释掉
注意:注释掉一定不要缺少也不要多了,把vones相关的注释掉就可以其他的不影响!!!

最后安装
sudo PATH=/root/anaconda3/bin:$PATH bash install.sh

安装成功!

要是看不明白:B站传送门→→→https://www.bilibili.com/video/BV1pV411r7Kt?p=17
欢迎点赞欢迎点赞欢迎点赞欢迎点赞欢迎点赞欢迎点赞欢迎点赞欢迎点赞欢迎点赞
用到的工具;链接:https://pan.baidu.com/s/1mRI3a327OB79Iy5x0YHNgg 提取码:9z5o(anaconda talib md文档)

闲来无事,在家把之前的编写的策略如何一步一步实现的记录下来了!

在B站发了些自己做的关于量化的视频,只是简单的记录一下自己是

如何一步一步走进这个量化坑的,希望可以帮助新手少走一些坑。

这个策略,实盘肯定不行的,只是记录下编写策略的一个流程。

我在B站发的视频,欢迎大家点赞关注 /😊/😊/😊/😊/😊/😊/😊

https://www.bilibili.com/video/BV1pV411r7Kt?p=10

视频只是简单的记录自己之前做的一些思路,高手别喷(●ˇ∀ˇ●)

质量肯定没法和官方的比 最后还是希望大家多多支持官方

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


class Demo01(CtaTemplate):
    """"""

    # 参数
    fast_window = 30  # 快速均线
    slow_window = 60  # 慢速均线
    x_min = 30  # 交易周期  默认是15分钟
    lots = 1  # 开仓手数
    save = 20  # 止损参数
    startstop = 100  # 开始止盈
    stoploss = 40  # 回撤点位
    daily_window = 10  # 日线的参数
    max_lots = 3
    flag=0

    # 变量
    fast_ma = 0
    fast_ma_pre = 0
    slow_ma = 0
    slow_ma_pre = 0
    price = 0  # tick的实时价格
    bartime = ""  # 时间的显示
    avg_buy_price = 0
    avg_sell_price = 0
    highest = 0
    lowest = 0
    daily_ma = 0

    liqDays = 60
    liqpoint = 0
    holding_days = 0

    run_buy=False
    run_sell=False



    parameters = ["fast_window", "slow_window", "x_min", "lots", 'stoploss', 'startstop', 'save']

    variables = ["bartime", "price", "fast_ma", "slow_ma", 'highest', 'lowest']

    def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
        """"""
        super().__init__(cta_engine, strategy_name, vt_symbol, setting)
        self.bg_x = BarGenerator(self.on_bar, self.x_min, self.on_x_bar, Interval.MINUTE)
        self.am_x = ArrayManager()

        self.bg_daily = BarGenerator(self.on_bar, 1, self.on_daily_bar, Interval.DAILY)
        self.am_daliy = ArrayManager()

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

    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_x.update_tick(tick)
        self.price = tick.last_price


        if self.pos > 0:
            if tick.last_price < self.avg_buy_price - self.save*2:
                self.sell(tick.last_price*0.9, abs(self.pos))
                print(tick.datetime, tick.last_price, "保命出场")
                self.flag+=1

        elif self.pos < 0:
            if tick.last_price > self.avg_sell_price + self.save*2:
                self.cover(tick.last_price*1.2, abs(self.pos))
                print(tick.datetime, tick.last_price, "保命出场")
                self.flag+=1

        self.put_event()

    def on_bar(self, bar: BarData):

        self.bg_x.update_bar(bar)
        self.bg_daily.update_bar(bar)

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

        am = self.am_x

        am.update_bar(bar)

        if not am.inited:
            return
        # ma30的计算
        self.fast_ma = am.close_array[-self.fast_window:-1].mean()
        # 之前的ma30的计算
        self.fast_ma_pre = am.close_array[-self.fast_window - 1:-2].mean()
        # ma60的计算
        self.slow_ma = am.close_array[-self.slow_window:-1].mean()
        # 之前的ma60的计算
        self.slow_ma_pre = am.close_array[-self.slow_window - 1:-2].mean()

        self.run_buy=bar.close_price<=am.close_array[-2]*1.05

        self.run_sell=bar.close_price>=am.close_array[-2]*0.95





        if self.pos == 0:
            # 金叉开多
            if self.fast_ma_pre < self.slow_ma_pre and self.fast_ma > self.slow_ma:
                if bar.close_price > self.daily_ma and self.run_buy:
                    self.buy(bar.close_price,min(self.lots,self.max_lots))
                    self.highest = bar.close_price
                    self.avg_buy_price = bar.close_price
                    self.holding_days = 0
                    print(bar.datetime, bar.close_price, "开多单","开仓手数:",min(self.lots,self.max_lots))

            elif self.fast_ma_pre > self.slow_ma_pre and self.fast_ma < self.slow_ma:
                # 死叉开空
                if bar.close_price < self.daily_ma and self.run_sell:
                    self.short(bar.close_price,min(self.lots,self.max_lots))
                    self.lowest = bar.close_price
                    self.avg_sell_price = bar.close_price
                    self.holding_days = 0
                    print(bar.datetime, bar.close_price, "开空单","开仓手数:",min(self.lots,self.max_lots))

        elif self.pos > 0:
            # 持有多单的最高价记录
            self.highest = max(bar.high_price, self.highest)
            # 多单止损的逻辑
            if bar.close_price < self.avg_buy_price - self.save:
                self.sell(bar.close_price, abs(self.pos))
                print(bar.datetime, bar.close_price, "多单止损","止损手数:",abs(self.pos))
                self.flag+=1

            # 多单止盈
            elif self.highest > self.avg_buy_price + self.startstop:
                if bar.close_price < self.highest - self.stoploss:
                    self.sell(bar.close_price, abs(self.pos))
                    print(bar.datetime, bar.close_price, "多单止盈","止盈手数:",abs(self.pos))
                    self.flag=0

            elif self.holding_days > 20 and bar.close_price < self.liqpoint:
                self.sell(bar.close_price, abs(self.pos))
                print(bar.datetime, bar.close_price, "多单自适应均线出场","平仓手数:",abs(self.pos))
                # if self.avg_buy_price<bar.close_price:
                #     self.flag=0
                # else:
                #     self.flag+=1


        elif self.pos < 0:
            # 持有空单的最低价记录
            self.lowest = min(bar.low_price, self.lowest)
            # 空单止损的逻辑
            if bar.close_price > self.avg_sell_price + self.save:
                self.cover(bar.close_price, abs(self.pos))
                print(bar.datetime, bar.close_price, "空单止损","止损手数:",abs(self.pos))
                self.flag+=1

            # 空单止盈
            elif self.lowest < self.avg_sell_price - self.startstop:
                if bar.close_price > self.lowest + self.stoploss:
                    self.cover(bar.close_price, abs(self.pos))
                    print(bar.datetime, bar.close_price, "空单止盈", "止盈手数:", abs(self.pos))
                    self.flag=0


            elif self.holding_days > 20 and bar.close_price > self.liqpoint:
                self.cover(bar.close_price, abs(self.pos))
                print(bar.datetime, bar.close_price, "空单自适应均线出场","平仓手数:",abs(self.pos))
                # if self.avg_sell_price > bar.close_price:
                #     self.flag =0
                # else:
                #     self.flag += 1

        if self.pos != 0:
            self.holding_days += 1
        else:
            self.liqDays = self.slow_window

        if self.pos != 0 and self.holding_days >= 20:
            self.liqDays -= 1
            self.liqDays = max(self.liqDays, 50)

        self.liqpoint = am.close_array[-self.liqDays:].mean()

        self.lots=2 if self.flag>=2 else 1

        self.put_event()

    def on_daily_bar(self, bar: BarData):

        self.cancel_all()

        am = self.am_daliy

        am.update_bar(bar)

        if not am.inited:
            return

        self.daily_ma = am.close_array[-self.daily_window:-1].mean()

    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

https://www.vnpy.com/forum/topic/3409-wei-shi-yao-ni-de-hui-ce-ce-lue-he-bie-de-ping-tai-bu-tai-yi-yang?page=1#pid12167
这是我之前的帖子,为什么你的回测策略和别的平台“不太一样”

vnpy的商品期货30分钟周期的每天的10点到11点的数据是没有的,别的时间比如9.30-10.00都是
有数据的但是10.00到10.30是没有数据的,直接是10.00到11.00,少了这一部分的分钟的数据,
也就是说商品期货休息的这段时间没有数据但是事实是10.00-10.30之间有15min的数据所以一直是少
了这一个K线,下面就是解决办法,只是国内的商品期货,别的品种大家自行选择

在合成分钟线的代代码下面加上这三句代码,原理大家都懂不多说,之后就会合成10.00-10.15的K线了

            elif self.last_bar and str(bar.datetime)[-8:]=='10:14:00':
                finished = True
                self.interval_count = 0

description

description

因为自己写的策略会用到日K线的数据,但是我自己写的时候发现调用不了,然后进入代码去看,
发现合成K线的BarGenerator下面的方法并没有self.interval == Interval.DAILY
又是我就来社区找,发现有大佬写的代码,很强,于是小弟也来发一发自己的,
因为自己做的是cta国内期货所以时间的问题可能和大家的不一样,我的规定是每天收到14:59:00的
合成一个日K线,所以在self.interval == Interval.HOUR后面加上了四行代码,就很简单的合成了日K线
把代码粘到elif self.interval == Interval.HOUR: 下面对齐就好了,只是国内的期货啊,别的不适应!

        elif self.interval == Interval.DAILY:
            ''' 如果当天的最后一个收盘时间事14.59,进行合成,生成日线bar'''
            if self.last_bar and str(bar.datetime)[-8:]=='14:59:00':
                finished = True
                self.interval_count = 0

description

那么如何调用呢??也很简单 看图

description

description

这是合成的数据,和别的平台的对比,看图

description

description

送给量化小白的小技巧:

原理很简单,算是一个小技巧,某些时候效果很不错,送给均线派,可以适度提升模型!
传统简单均线受困于固定周期参数的限制,不论你使用什么参数的均线都会出现的问题就是反应过快或者反应过慢,最让人头疼的是进场后的均线反应过慢,往往让你损失一大笔利润。自适应均线的原理很简单就是随着持仓周期的拉长,均线的参数慢慢变小,越来越敏感,有时候往往能收到意想不到的效果,各位看官看图

description

description

description

就如图上所示,加了自适应均线的模型因为均线参数的逐渐变小而慢慢敏感,于是额外获得了一段利润
但是有利也有弊,自适应均线会导致过早出场,与后面的利润失之交臂,如何使用还请自行决断。

代码如下

    liqDays = 60
    liqpoint = 0
    holding_days = 0  #需要增加的三个变量

假如我的模型主策略在on_xmin_bar这个函数里面,在on_xmin_bar这个函数最后面加上这段代码
假如有持仓,并没有立即更新liqDays,而是判断持仓超过20个holding_days,开始启动liqDays的更新
当然了最低不能低于某一个阈值,我设置的是50,你们自行选择

        # 更新自适应均线
        if self.pos != 0:
            self.holding_days += 1

        if self.pos!=0 and self.holding_days>=20:
            self.liqDays-=1
            self.liqDays=max(self.liqDays,50)
        else:
            self.liqDays=60
        self.liqpoint=am.close_array[-self.liqDays:].mean()

下面是多单出场演示,空单同理

            elif self.holding_days>=20 and bar.close_price<=self.liqpoint:
                self.sell(bar.close_price, abs(self.pos))
                print('多单自适应均线止盈', bar.datetime, bar.close_price)

这几天接触vnpy,之前都是在别的平台做的,之前在tb上写过一个策略,忽然想了起来,然后就在vnpy
上面复刻了这个策略,回测之后发现相差很大然后调试了好久,以为是策略的问题,然后又找了一个
策略来写,策略是在30分钟周期上的双均线策略,很简单来验证问题的所在。

可就是这么简单的策略,再两个平台上的差别也很大,然后我就把vnpy的每个bar的输出都print出来,
发现一个问题就是30分钟周期的每天的10点到11点的数据是没有的,别的时间比如9.30-10.00都是
有数据的但是10.00到10.30是没有数据的,直接是10.00到11.00,少了这一部分的分钟的数据,
也就是说商品期货休息的这段时间没有数据但是事实是10.00-10.30之间有15min的数据所以一直是少
了这一个K线,也就是少了15分钟数据然后看代码,10.00-10.30只有15个bar 14+1的数量没法整除30
所以这段数据就被抛弃了把,一开始我还以为是米筐的数据问题假如你的周期是15分钟或者一下的其
实是没有影响的,或者你做的是股指期货也是没有影响的,但是你是30分钟的周期的商品期货的话影响就很大
问问版主,这个算不算一个bug,我已经修改完了,然后回测和tb的结果是一致的

description

description
这是什么原因?????????

© 2015-2022 微信 18391752892
备案服务号:沪ICP备18006526号

沪公网安备 31011502017034号

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