VeighNa量化社区
你的开源社区量化交易平台
Member
avatar
加入于:
帖子: 6
声望: 2

说明

  • vnpy官方目前仍是python2的版本,群主有提到将在2.0版本升级python3。大佳老师在vnpy的基础上自己fork了一个python3版本。还有不少其他用户也自行魔改python3版本。
  • vnpy集成了众多交易接口,包括期货、IB等。本文仅针对期货CTP接口在ubuntu、python3环境下的编译安装。
  • ubuntu16自带python2.7和python3.5,如果不介意,可以直接用系统的python3.5来编译和运行。如果服务器还有其他任务,可能用到不同的环境,或者希望使用其他版本的python,常用的一种解决方案是安装最新的anaconda3,然后用其创建独立的python虚拟环境,例如python3.6的环境。
  • sudo apt-get install libboost-all-dev这个方式安装的boost库是python2版本的,安装python3版本应下载boost源代码在编译时指定python3.
  • 本文参考大佳老师github的安装流程以及各种搜索结果。
  • 本文也发在我的博客我的博客

以下是直接使用ubuntu16系统python3.5来编译安装的流程

下载python3版本的ctpapi代码

建议使用git,直接克隆整个仓库下来,然后将其中的vnpy/api/ctp/文件夹复制到用户目录下。
git clone https://github.com/msincenselee/vnpy.git

安装编译工具

更新apt-get的软件列表
sudo apt-get update

安装编译相关软件
sudo apt-get install gcc build-essential cmake

安装python相关软件
sudo apt-get install python-dev python-pip python3 python3-dev python3-pip

安装boost依赖的软件
sudo apt-get install mpi-default-dev libicu-dev libbz2-dev

安装boost

下载boost安装包
wget http://sourceforge.net/projects/boost/files/boost/1.66.0/boost_1_66_0.tar.gz/download

重命名
mv download boost_1_66_0.tar.gz

解压缩
tar -xvzf boost_1_66_0.tar.gz

修改 boost_1_66_0/tools/build/example/user-config.jam,指定使用python3.5。然后把user-config.jam复制到用户目录,例如/home/ubuntu/
using python : 3.5 : /usr/bin/python3 : /usr/include/python3.5m : /urs/lib/x86_64-linux-gnu ;

回到 boost_1_66_0/,运行bootstrap.sh,指定使用pyhton3.5。此处只编译ctpapi需要的库,如过希望编译所有的库则修改参数为--with-libraries=all
./bootstrap.sh --with-python=/usr/bin/python3 --with-python-version=3.5 --with-libraries=python,locale,thread,date_time,system,chrono

编译,安装
sudo ./b2 install

安装完成检查 /usr/local下, include/boost, lib/libboos_python3.so等是否存在

配置CMakeLists.txt

主要是修改一些路径在具体服务器上的实际位置,并去掉了windows的部分

cmake_minimum_required(VERSION 2.8) # 版本要求
project(vn_ctp_api)     # 项目名称

# 设置使用的编译器
set(CMAKE_BUILD_TYPE "Release") # 编译类型为release,即发布
if (CMAKE_COMPILER_IS_GNUCXX)   # 原为if (CMAKE_COMPILER_IS_GNUC OR CMAKE_COMPILER_IS_GNUCXX),其中的CMAKE_COMPILER_IS_GNUC疑为CMAKE_COMPILER_IS_GNUCC,少了个C
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -std=c++11") # C++编译器加上c++11支持选项
  # -fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),
  # 则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意
  # 位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
endif ()

# 设置输出目录
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)  # CMAKE_BINARY_DIR 如果是 in source 编译,指得就是工程顶层目录,如果是 out-of-source 编译,指的是工程编译发生的目录
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/lib)

# 使用64位编译
option(USE_64BITS "comiple 64bits" ON)  # option命令为用户提供了一个在ON和OFF中做出选择的选项。如果没有指定初始值,将会使用OFF作为初值。
if (USE_64BITS)
  add_definitions(-DUSE_64BITS)       # 为源文件的编译添加由-D引入的define flag
endif()

# 设置C++ API源文件的所在目录
message("Under unix: " ${CMAKE_SIZEOF_VOID_P})
if (CMAKE_SIZEOF_VOID_P MATCHES "8")  # 检查当前电脑是否是64位的
    set(CTPAPI_PATH ctpapi/x64_linux) # 设置ctpapi的搜索路径
endif()
include_directories(${CTPAPI_PATH}) # 添加到include文件的搜索路径
set(CTPAPI_LIBRARY )
find_library(CTPAPI_MD_LIBRARY  # 在CTPAPI_PATH目录查找库文件thostmduserapi,保存在名为CTPAPI_MD_LIBRARY的变量中
  NAMES thostmduserapi
  PATHS ${CTPAPI_PATH}) 
find_library(CTPAPI_TD_LIBRARY  # 在CTPAPI_PATH目录查找库文件thosttraderapi,保存在名为CTPAPI_TD_LIBRARY的变量中
  NAMES thosttraderapi
  PATHS ${CTPAPI_PATH})

  # 设置编译源文件
set (vnctpmd )
set (vnctptd )
option(BUILD_CTP_MD "build ctp md" ON)  # 增加选项BUILD_CTP_MD,初始值为ON。
if (BUILD_CTP_MD)
  add_definitions(-DBUILD_CTP_MD)
  set(CTP_MD_PATH vnctpmd/vnctpmd)  # 设置CTP_MD_PATH变量,即CTP_MD头文件的路径
  include_directories(CTP_MD_PATH)
  set(VN_CTP_MD_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/vnctpmd/vnctpmd/vnctpmd.cpp)     # 设置VN_CTP_MD_SOURCE变量,即其cpp源代码的位置
  add_library(vnctpmd SHARED ${VN_CTP_MD_SOURCE}) # 使用指定的源文件向工程中添加一个库。vnctpmd是名称。SHARED库会被动态链接,在运行时被加载。
endif()
option(BUILD_CTP_TD "build ctp td" ON)  # 选项BUILD_CTP_TD 同上
if (BUILD_CTP_TD)
  add_definitions(-DBUILD_CTP_TD)
  set(CTP_TD_PATH vnctptd/vnctptd)
  include_directories(CTP_TD_PATH)
  set(VN_CTP_TD_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/vnctptd/vnctptd/vnctptd.cpp)
  add_library(vnctptd SHARED ${VN_CTP_TD_SOURCE})  
endif()

# 设置Python所在的目录,这里使用系统的python3.5
# 如果使用anaconda虚拟环境,lib和include的目录相应修改
set(PYTHON_LIBRARY )
set(PYTHON_INCLUDE_PATH /usr/include/python3.5m)
find_library(PYTHON_LIBRARY
  NAMES python3.5m
  PATHS /urs/lib/x86_64-linux-gnu)
include_directories(${PYTHON_INCLUDE_PATH})

# 链接boost库
set(Boost_USE_MULTITHREADED      ON)    # Boost多线程
find_package(Boost 1.66.0 COMPONENTS python thread date_time system chrono REQUIRED) # 如果boost库没有完全编译,需要将编译的库明确地指出,否者message(${Boost_LIBRARIES})会出错.这里指出了依赖的boost组件
if(Boost_FOUND)
  include_directories(${Boost_INCLUDE_DIRS})
endif()

# 去掉生成的so文件名中前缀的lib
set_target_properties(vnctpmd PROPERTIES PREFIX "")
set_target_properties(vnctptd PROPERTIES PREFIX "")
# 链接生成.so文件
target_link_libraries(vnctpmd  ${Boost_LIBRARIES} ${PYTHON_LIBRARY} ${CTPAPI_MD_LIBRARY})
target_link_libraries(vnctptd  ${Boost_LIBRARIES} ${PYTHON_LIBRARY} ${CTPAPI_TD_LIBRARY})

配置build.sh

如果目录结构没有变化,build.sh可以完全照搬,不需要修改。

#!/bin/bash
# Written by Suzhengchun on 20160213

set -e
BUILDDIR=build
rm -rf $BUILDDIR
if [ ! -f $BUILDDIR ]; then
    mkdir -p $BUILDDIR
fi
pushd $BUILDDIR
cmake ..
make VERBOSE=1 -j 1
ln -fs `pwd`/lib/vnctpmd.so ../vnctpmd/test/vnctpmd.so
ln -fs `pwd`/lib/vnctptd.so ../vnctptd/test/vnctptd.so
cp ../vnctpmd/test/vnctpmd.* ../
cp ../vnctptd/test/vnctptd.* ../
popd

开始编译

./build.sh
编译完成可以在CMakeLists.txt的同一目录以及build/lib/目录下看到vnctpmd.so和vnctptd.so。使用test下的mdTest.py和tdTest.py可以进行测试。

以下是直接使用python3.6虚拟环境来编译安装的流程(仅列出不同的部分)

安装anaconda

下载anaconda安装包
wget -c https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.3.0-Linux-x86_64.sh

使安装包可执行
chmod a+x Anaconda3-5.3.0-Linux-x86_64.sh

开始安装anaconda
./Anaconda3-5.3.0-Linux-x86_64.sh

如果希望之后在命令行直接输入conda就能运行而不需要加具体路径,在安装过程提示Do you wish the installer to initialize Anaconda3 in your /home/ubuntu/.bashrc [yes|no]时选择yes,然后运行source .bashrc使配置生效。

配置为国内的镜像

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --set show_channel_urls yes

创建虚拟python3.6环境
conda create --name py36 python=3.6

激活虚拟python3.6环境
source activate py36

安装boost

修改 boost_1_66_0/tools/build/example/user-config.jam,指定使用虚拟环境的python3.6
using python : 3.6 : /home/ubuntu/anaconda3/envs/py36/bin/python3 : /home/ubuntu/anaconda3/envs/py36/include/python3.6m : /home/ubuntu/anaconda3/envs/py36/lib ;

回到 boost_1_66_0/,运行bootstrap.sh,指定使用虚拟环境的pyhton3.6。此处只选择需要的库,如过希望编译所有的库则改为--with-libraries=all
./bootstrap.sh --with-python=/home/ubuntu/anaconda3/envs/py36/bin/python3 --with-python-version=3.6 --with-python-root=/home/ubuntu/anaconda3/envs/py35 --with-libraries=python,locale,thread,date_time,system,chrono

配置CMakeLists.txt

# 设置Python所在的目录,此处使用的是anaconda创建的python3.6虚拟环境
set(PYTHON_LIBRARY )
set(PYTHON_INCLUDE_PATH /home/ubuntu/anaconda3/envs/py36/include/python3.6m)
find_library(PYTHON_LIBRARY
NAMES python3.6m
PATHS /home/ubuntu/anaconda3/envs/py36/lib/)
include_directories(${PYTHON_INCLUDE_PATH})

以下是编译过程碰到的一些问题的解决方案,供参考

内存不足问题

如果配置太低内存不足,编译会出现Memory exhausted错误,需设置swap文件,相当于虚拟内存。

创建swap挂载点
mkdir /opt/images/
rm -rf /opt/images/swap
设置挂载swap的大小,64M*32=2GB
dd if=/dev/zero of=/opt/images/swap bs=64M count=32
mkswap /opt/images/swap
开启swap
swapon /opt/images/swap
这个时候,可以执行之前内存不足时的命令了,正常情况下,执行时间会比较长,但是能过去

使用完毕后可以考虑关闭swap并删除挂载文件
swapoff swap
rm -f /opt/images/swap

Member
avatar
加入于:
帖子: 6
声望: 2

找了半天总算找到编辑按钮了。管理员大佬赶紧改一下前端代码吧,在chrome浏览器下看着很不正常。

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

多谢大佬奉献。

Administrator
avatar
加入于:
帖子: 4500
声望: 320

板蓝根 wrote:

找了半天总算找到编辑按钮了。管理员大佬赶紧改一下前端代码吧,在chrome浏览器下看着很不正常。

能描述下具体不正常的情况嘛?我们看了下没定位到异常

Member
avatar
加入于:
帖子: 6
声望: 2

我CTRL+F5刷新网页之后没问题了,之前可能缓存了最早的版本

用Python的交易员 wrote:

板蓝根 wrote:

找了半天总算找到编辑按钮了。管理员大佬赶紧改一下前端代码吧,在chrome浏览器下看着很不正常。

能描述下具体不正常的情况嘛?我们看了下没定位到异常

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

18年的帖子,现在还管用么?感觉断档的厉害,有高人指点一下么?

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

沪公网安备 31011502017034号

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