commit
ed41076a17
@ -1,5 +1,11 @@
|
||||
FROM hub.c.163.com/public/ubuntu:16.04-tools
|
||||
|
||||
# 初始化 /etc/machine-id
|
||||
RUN systemd-machine-id-setup
|
||||
|
||||
# 使用传统的 bash 作为 shell 解释器
|
||||
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
|
||||
|
||||
# 时区设置
|
||||
ENV TZ=Asia/Shanghai
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
@ -8,15 +14,15 @@ RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
RUN locale-gen zh_CN.UTF-8 \
|
||||
&& DEBIAN_FRONTEND=noninteractive dpkg-reconfigure locales \
|
||||
&& locale-gen zh_CN.UTF-8
|
||||
|
||||
ENV LANG zh_CN.UTF-8
|
||||
ENV LANGUAGE zh_CN:zh
|
||||
ENV LC_ALL zh_CN.UTF-8
|
||||
|
||||
|
||||
# 替换 apt 源为阿里云,在本地构建镜像时,取消注释,使用阿里云的 apt 源
|
||||
RUN echo "开始配置系vnpy环境" \
|
||||
&& echo "更新源列表" \
|
||||
# 在本地构建镜像时,使用阿里云或163的 apt 源
|
||||
RUN echo "开始配置 vnpy 环境" \
|
||||
|
||||
&& echo "更新 apt 源列表" \
|
||||
&& echo "" > /etc/apt/sources.list \
|
||||
&& echo "deb http://mirrors.163.com/ubuntu/ xenial main multiverse restricted universe" >> /etc/apt/sources.list \
|
||||
&& echo "deb http://mirrors.163.com/ubuntu/ xenial-backports main multiverse restricted universe" >> /etc/apt/sources.list \
|
||||
@ -30,44 +36,74 @@ RUN echo "开始配置系vnpy环境" \
|
||||
&& echo "deb-src http://mirrors.163.com/ubuntu/ xenial-updates main multiverse restricted universe" >> /etc/apt/sources.list \
|
||||
&& apt-get clean \
|
||||
&& apt-get update \
|
||||
|
||||
&& echo "从 apt 获取软件" \
|
||||
&& apt-get install -y bzip2 wget \
|
||||
&& apt-get install -y bzip2 wget libgl1-mesa-glx qt5-default ttf-wqy-microhei \
|
||||
&& echo "安装编译环境" \
|
||||
&& apt-get install -y build-essential libboost-all-dev python-dev cmake \
|
||||
&& apt-get clean \
|
||||
&& echo "安装 ta-lib 内核" \
|
||||
&& cd /opt \
|
||||
&& wget -t 0 http://kent.dl.sourceforge.net/project/ta-lib/ta-lib/0.4.0/ta-lib-0.4.0-src.tar.gz \
|
||||
&& tar -zxvf ta-lib-0.4.0-src.tar.gz \
|
||||
&& rm ta-lib-0.4.0-src.tar.gz \
|
||||
&& cd ta-lib \
|
||||
&& ./configure --prefix=/usr \
|
||||
&& make && make install \
|
||||
&& echo "安装 miniconda" \
|
||||
&& apt-get install -y build-essential libboost-all-dev python-dev cmake
|
||||
|
||||
RUN echo "安装 VNC 服务,使用固定密码 123456 登录" \
|
||||
&& apt-get install -y x11vnc xvfb \
|
||||
&& mkdir ~/.vnc \
|
||||
&& x11vnc -storepasswd 123456 ~/.vnc/passwd \
|
||||
&& apt-get clean
|
||||
|
||||
RUN echo "安装 anaconda" \
|
||||
&& mkdir /tmp/conda/ \
|
||||
&& cd /tmp/conda/ \
|
||||
# && echo "下载 Miniconda by Python2" && wget -t 0 https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda2-latest-Linux-x86_64.sh \
|
||||
&& echo "下载 Miniconda by Python3" && wget -t 0 https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh \
|
||||
# && echo "下载 Miniconda by Python3" && wget -t 0 https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh \
|
||||
&& echo "下载 Miniconda by Python2" && wget -t 0 https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda2-latest-Linux-x86_64.sh \
|
||||
&& bash Miniconda*.sh -b -p /opt/conda \
|
||||
&& rm Miniconda*.sh \
|
||||
# && echo "下载 anaconda by Python2" && wget -t 0 https://repo.continuum.io/archive/Anaconda2-4.4.0-Linux-x86_64.sh \
|
||||
# && bash Anaconda*.sh -b -p /opt/conda \
|
||||
# && rm Anaconda*.sh \
|
||||
&& echo "设置 conda 和 python 的环境路径" \
|
||||
&& ln -s /opt/conda/bin/python /usr/local/bin/python \
|
||||
&& ln -s /opt/conda/bin/conda /usr/local/bin/conda \
|
||||
&& ln -s /opt/conda/bin/pip /usr/local/bin/pip \
|
||||
&& echo "设置 conda 国内源, 从 conda 安装 python 库" \
|
||||
&& ln -s /opt/conda/bin/pip /usr/local/bin/pip
|
||||
|
||||
RUN echo "设置 conda 国内源, 从 conda 安装 python 库" \
|
||||
&& conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ \
|
||||
&& conda config --set show_channel_urls yes \
|
||||
&& conda install -y pymongo pyzmq numpy msgpack-python \
|
||||
&& echo "更改 pip 源" \
|
||||
&& conda install -y pymongo pyzmq numpy msgpack-python qtpy pyqt \
|
||||
&& conda install -c https://conda.anaconda.org/quantopian ta-lib \
|
||||
&& conda clean -ay
|
||||
|
||||
RUN echo "从 pip 安装 python 库" \
|
||||
&& mkdir ~/.pip \
|
||||
&& echo "[global]" >> ~/.pip/pip.conf \
|
||||
&& echo "index-url = https://pypi.doubanio.com/simple/" >> ~/.pip/pip.conf \
|
||||
&& echo "index-url = http://pypi.douban.com/simple" >> ~/.pip/pip.conf \
|
||||
&& echo "使用 pip 安装 python 库" \
|
||||
&& pip install TA-Lib \
|
||||
&& conda clean -ay \
|
||||
&& echo "安装结束"
|
||||
&& pip --trusted-host pypi.douban.com install ta-lib websocket-client qdarkstyle psutil quantopian-tools \
|
||||
&& pip --trusted-host pypi.douban.com install zipline
|
||||
|
||||
|
||||
RUN echo "安装 fluxbox 桌面管理器" \
|
||||
&& apt-get install -y fluxbox
|
||||
|
||||
#RUN echo "安装 mongodb 服务" \
|
||||
# && mkdir -p /data/db \
|
||||
# && apt-get install -y mongodb \
|
||||
# && systemctl enable mongodb.service \
|
||||
# && sed -i 's/bind_ip = 127.0.0.1/\#bind_ip = 127.0.0.1/g' /etc/mongodb.conf
|
||||
|
||||
# 在客户端登录时自动启动 GUI 程序 (might not be the best way to do it, but it does the trick)
|
||||
#RUN bash -c 'echo "python /srv/vnpy/examples/VnTrader/run_simple.py" >> ~/.bashrc'
|
||||
#RUN bash -c 'echo "/usr/bin/xterm" >> ~/.bashrc'
|
||||
# 设置登录时开启本地 mongodb 服务并激活图形管理界面
|
||||
#RUN bash -c 'echo "service mongodb restart" >> ~/.bashrc'
|
||||
RUN bash -c 'echo "fluxbox &" >> ~/.bashrc'
|
||||
RUN bash -c 'echo "pip install -e /srv/vnpy" >> ~/.bashrc'
|
||||
# 编译安装相关接口库
|
||||
#RUN bash -c 'echo "cd /srv/vnpy/vnpy/api/ctp && bash ./build.sh && cp -af ./build/lib/*.so . && cd /srv/vnpy" >> ~/.bashrc'
|
||||
|
||||
RUN echo "安装配置结束"
|
||||
|
||||
|
||||
WORKDIR /srv/vnpy
|
||||
|
||||
|
||||
# 暂时不设置入口点,否则不能使用 -it 交互模式
|
||||
# ENTRYPOINT python /srv/vnpy/vn.trader/vtServer.py
|
||||
|
||||
|
@ -1,56 +1,82 @@
|
||||
# VNPY 的 Docker 镜像
|
||||
|
||||
author:[@lamter](https://github.com/lamter)
|
||||
author: [@lamter](https://github.com/lamter) and [@crystalphi](https://github.com/crystalphi)
|
||||
|
||||
|
||||
> _关于Docker_
|
||||
> - _`Docker` 是基于 `Linux`的一个服务。通过模拟了整个 `Linux`的系统文件,来实现沙盒,所以`Docker`不是虚拟机,更类似于在`Linux`中模拟`Windows`的`Wine`。_
|
||||
> - _在`Linux`中,`Docker`可以直接运行在宿主中,而在`Mac`和`Windows`中,是通过`VirtualBox`等先建立一个`Linux`的虚拟机,然后再在这个虚拟机中运行`Docker`。这样的话可能会有些许差异,比如`--host`的与宿主共享网络的模式。_
|
||||
> - _在`Linux`系统下,模式下会使得`Docker`的容器与宿主共享网络端口,但是在`Mac`或者`Windows`中,该模式是容器与虚拟机中的`Linux`共享网络端口,而不是直接跟宿主`Mac`或者`Windows`共享端口。_
|
||||
> - Docker教程看[这里](https://yeasy.gitbooks.io/docker_practice/content/)。
|
||||
常用命令示例:
|
||||
```
|
||||
docker build -t friendlyname . # Create image using this directory's Dockerfile
|
||||
docker run -p 4000:80 friendlyname # Run "friendlyname" mapping port 4000 to 80
|
||||
docker run -d -p 4000:80 friendlyname # Same thing, but in detached mode
|
||||
docker ps # See a list of all running containers
|
||||
docker stop <hash> # Gracefully stop the specified container
|
||||
docker ps -a # See a list of all containers, even the ones not running
|
||||
docker kill <hash> # Force shutdown of the specified container
|
||||
docker rm <hash> # Remove the specified container from this machine
|
||||
docker rm $(docker ps -a -q) # Remove all containers from this machine
|
||||
docker images -a # Show all images on this machine
|
||||
docker rmi <imagename> # Remove the specified image from this machine
|
||||
docker rmi $(docker images -q) # Remove all images from this machine
|
||||
docker login # Log in this CLI session using your Docker credentials
|
||||
docker tag <image> username/repository:tag # Tag <image> for upload to registry
|
||||
docker push username/repository:tag # Upload tagged image to registry
|
||||
docker run username/repository:tag # Run image from a registry
|
||||
```
|
||||
> - Docker加速看[这里](https://www.daocloud.io/mirror#accelerator-doc)
|
||||
|
||||
|
||||
## 设计概述
|
||||
|
||||
1. 使用 docker 镜像来提供基于 vnpy 的交易系统开发、测试、回测、实盘环境。
|
||||
|
||||
1. 使用 docker 镜像来提供运行和编译环境。
|
||||
2. 将策略打包到 docker 镜像中以便直接在生产环境部署。
|
||||
3. Docker教程看[这里](https://yeasy.gitbooks.io/docker_practice/content/)。
|
||||
4. Docker加速看[这里](https://www.daocloud.io/mirror#accelerator-doc)
|
||||
|
||||
## 制作环境镜像
|
||||
|
||||
## 镜像制作与实例运行
|
||||
|
||||
### 制作环境镜像
|
||||
在`docker/`目录下运行:
|
||||
|
||||
```bash
|
||||
➜ user@master~/vnpy/docker: bash build_image.sh
|
||||
➜ user@master~/vnpy/docker: docker build -f Dockerfile --force-rm -t vnpy-vnc ..
|
||||
...
|
||||
Successfully built fb3ae4d5e0eb
|
||||
Successfully built 26c00f8cf521
|
||||
```
|
||||
|
||||
漫长的等待后之后,查看
|
||||
```bash
|
||||
➜ user@master~/vnpy/docker: docker images
|
||||
REPOSITORY TAG IMAGE ID CREATED SIZE
|
||||
vnpy latest fb3ae4d5e0eb 21 minutes ago 856 MB
|
||||
ubuntu 16.04 4ca3a192ff2a 4 weeks ago 128.2 MB
|
||||
vnpy latest 26c00f8cf521 Less than a second ago 3.02GB
|
||||
hub.c.163.com/public/ubuntu 16.04-tools 1196ea15dad6 5 months ago 336MB
|
||||
```
|
||||
|
||||
vnpy 的运行环境镜像 `vnpy:latest` 制作成功。
|
||||
`ubuntu` 镜像是用于构建 `vnpy` 镜像的上层镜像。之后可以使用 `vnpy` 镜像继续构建下层镜像,用于生产环境的部署。
|
||||
之后可以使用该镜像继续构建下层镜像,用于生产环境的部署。
|
||||
|
||||
### 测试运行
|
||||
|
||||
### 运行 Docker 实例
|
||||
在`docker/`目录下运行
|
||||
|
||||
```bash
|
||||
➜ user@master~/vnpy/docker: bash run_vnc.sh
|
||||
➜ 在 MacOS 的 Finder 中按 Command-k 打开对话框,输入 vnc://127.0.0.1:5900 进行 VNC 连接。
|
||||
or
|
||||
➜ user@master~/vnpy/docker: bash run_shell.sh
|
||||
➜ root@docker/: 进入镜像
|
||||
➜ root@docker /srv/vnpy: 进入镜像实例的命令行界面
|
||||
```
|
||||
|
||||
只是使用 `vnpy` 镜像启动了一个容器,并使用了`bash`来进行交互。此时环境基本上跟使用命令行登陆一台`Linux`类似。
|
||||
从脚本可知,已经将整个`vnpy`的项目路径映射到了容器内的`/srv/vnpy`路径。
|
||||
|
||||
查看`run_shell.sh`脚本可知,已经将整个`vnpy`的项目路径映射到了容器内的`/srv/vnpy`路径。
|
||||
|
||||
### 尝试编译
|
||||
### 重新编译接口库
|
||||
由于是一个新的```Linux```环境,```CTP```之类的接口需要重新编译。
|
||||
```bash
|
||||
➜ root@docker/: cd /srv/vnpy/vn.ctp
|
||||
➜ root@docker/: cd /srv/vnpy/api/ctp/
|
||||
➜ root@docker/: ./build.sh
|
||||
...
|
||||
[100%] Built target vnctpmd
|
||||
@ -61,22 +87,19 @@ vnpy 的运行环境镜像 `vnpy:latest` 制作成功。
|
||||
|
||||
**也就意味着,当前项目下的CTP接口已经被镜像中的编译包替换了。**
|
||||
|
||||
### 启动`vnpy`
|
||||
在`vn.trader/ctpGateway/CTP_connection.json`中配置CTP链接账号的服务器host。
|
||||
|
||||
### 启动基于 `vnpy` 的交易等程序
|
||||
注意:需要先在`vnpy/trader/gateway/ctpGateway/CTP_connect.json`中配置正确的CTP链接账号及服务器信息。
|
||||
|
||||
尝试启动 vnpy 实例
|
||||
```bash
|
||||
➜ root@docker /: cd /srv/vnpy/vn.trader
|
||||
➜ root@docker docker: python vtServer.py
|
||||
➜ root@docker /srv/vnpy: python ./examples/VnTrader/run_simple.py
|
||||
...
|
||||
vn.trader服务器已启动
|
||||
请输入exit来关闭服务器
|
||||
运行成功将在 VNC 界面上打开中文 GUI 程序,可正常连接 CTP 服务器及数据库。
|
||||
```
|
||||
运行成功。
|
||||
|
||||
### 直接运行项目代码
|
||||
目前由于未知的原因,直接在宿主中通过传递命令的方式(见`vn.docker/server_vnpy.sh`脚本)来直接启动服务,会使得服务阻塞。所以目前只能先通过`run_shell.sh`脚本进入容器交互中,再启动服务。
|
||||
|
||||
## Q&A
|
||||
__Q:__ MongoDB无法链接?
|
||||
__Q:__ 如何连接容器外的MongoDB?
|
||||
__A:__ 在`Linux`系统下,无需特定端口映射`-p 2014`,直接使用`--net=host`共享网络模式即可。在`Mac`或`Windows`下,需要在`VT_setting.json`中设置`mongoHost`时,指定其局域网中的`IP`,而非`localhost`。
|
||||
|
||||
|
35
docker/build_image.sh
Normal file → Executable file
35
docker/build_image.sh
Normal file → Executable file
@ -1,9 +1,32 @@
|
||||
#/bin/bash
|
||||
# 在 Mac 或者 Linux 下直接运行这个在本地构建镜像。
|
||||
#!/usr/bin/env bash
|
||||
# 在 Mac 或者 Linux 下直接运行此脚本在本地构建镜像。
|
||||
|
||||
# 删除旧镜像
|
||||
# docker rmi vnpy:latest
|
||||
read -p "需要删除现有镜像吗? [N|y]:" input
|
||||
case "$input" in
|
||||
[Yy])
|
||||
docker rmi vnpy:latest
|
||||
echo -n "删除完毕。"
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
# 在本地构建镜像时,在 Dockerfile 取消注释,使用阿里云的 apt 源
|
||||
# 制作镜像, 如有问题, 添加 --no-cache 参数以不使用缓存
|
||||
docker build --force-rm -t vnpy .
|
||||
echo ""
|
||||
|
||||
# 构建新镜像
|
||||
read -p "确定开始构建镜像? [N|y]:" input
|
||||
case "$input" in
|
||||
[Yy])
|
||||
# 构建镜像时,如有问题可以添加 --no-cache 参数以不使用缓存
|
||||
docker build -f Dockerfile --force-rm -t vnpy ..
|
||||
echo -n "构建完毕。"
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
echo ""
|
||||
echo "当前镜像列表:"
|
||||
docker images
|
||||
|
0
docker/dockerTrader/tmp/server.sh
Normal file → Executable file
0
docker/dockerTrader/tmp/server.sh
Normal file → Executable file
10
docker/run_shell.sh
Normal file → Executable file
10
docker/run_shell.sh
Normal file → Executable file
@ -1,10 +1,12 @@
|
||||
#/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
# 以 shell 方式启动容器,环境如同 Linux 命令行
|
||||
|
||||
cd ..
|
||||
# 将 vnpy 指定到
|
||||
|
||||
## Run docker container, mapping the ssh and vnc ports, then run bash terminal:
|
||||
docker run --name vnpy_bash --rm \
|
||||
-v `pwd`:/srv/vnpy \
|
||||
-p 2014:2014 -p 602:602 \
|
||||
-it vnpy:latest /bin/bash
|
||||
-p 2222:22 \
|
||||
-it vnpy:latest \
|
||||
/bin/bash
|
||||
|
||||
|
18
docker/run_vnc.sh
Executable file
18
docker/run_vnc.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
# 以 vnc 服务方式启动容器,环境如同 Linux 命令行
|
||||
|
||||
|
||||
#You can use vnc to connect to docker:
|
||||
echo 'please press Command-k on Finder and connect to: vnc://127.0.0.1:5900'
|
||||
|
||||
DIR=$(cd `dirname $0`; pwd)
|
||||
#mkdir -p ${DIR}/../docker/mongodb-data
|
||||
#-v ${DIR}/../docker/mongodb-data:/var/lib/mongodb \
|
||||
|
||||
# Run docker container, mapping the ssh and vnc ports:
|
||||
docker run --name vnpy_vnc --rm \
|
||||
-v ${DIR}/..:/srv/vnpy \
|
||||
-p 5900:5900 -p 27018:27017 \
|
||||
vnpy:latest \
|
||||
/usr/bin/x11vnc -forever -usepw -create
|
||||
|
0
docker/server_vnpy.sh
Normal file → Executable file
0
docker/server_vnpy.sh
Normal file → Executable file
56
examples/VnTrader/run_simple.py
Normal file
56
examples/VnTrader/run_simple.py
Normal file
@ -0,0 +1,56 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
# 重载sys模块,设置默认字符串编码方式为utf8
|
||||
import sys
|
||||
|
||||
reload(sys)
|
||||
sys.setdefaultencoding('utf8')
|
||||
|
||||
# 判断操作系统
|
||||
import platform
|
||||
|
||||
system = platform.system()
|
||||
|
||||
# vn.trader模块
|
||||
from vnpy.event import EventEngine
|
||||
from vnpy.trader.vtEngine import MainEngine
|
||||
from vnpy.trader.uiQt import createQApp
|
||||
from vnpy.trader.uiMainWindow import MainWindow
|
||||
|
||||
# 加载底层接口
|
||||
from vnpy.trader.gateway import ctpGateway
|
||||
|
||||
# 加载上层应用
|
||||
from vnpy.trader.app import (riskManager, ctaStrategy, spreadTrading)
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def main():
|
||||
"""主程序入口"""
|
||||
# 创建Qt应用对象
|
||||
qApp = createQApp()
|
||||
|
||||
# 创建事件引擎
|
||||
ee = EventEngine()
|
||||
|
||||
# 创建主引擎
|
||||
me = MainEngine(ee)
|
||||
|
||||
# 添加交易接口
|
||||
me.addGateway(ctpGateway)
|
||||
|
||||
# 添加上层应用
|
||||
me.addApp(riskManager)
|
||||
me.addApp(ctaStrategy)
|
||||
me.addApp(spreadTrading)
|
||||
|
||||
# 创建主窗口
|
||||
mw = MainWindow(me, ee)
|
||||
mw.showMaximized()
|
||||
|
||||
# 在主线程中启动Qt事件循环
|
||||
sys.exit(qApp.exec_())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
0
install.sh
Normal file → Executable file
0
install.sh
Normal file → Executable file
0
vnpy/api/ctp/build.sh
Normal file → Executable file
0
vnpy/api/ctp/build.sh
Normal file → Executable file
0
vnpy/api/ib/build.sh
Normal file → Executable file
0
vnpy/api/ib/build.sh
Normal file → Executable file
0
vnpy/api/ib/ibapi/linux/build.sh
Normal file → Executable file
0
vnpy/api/ib/ibapi/linux/build.sh
Normal file → Executable file
0
vnpy/api/lts/build.sh
Normal file → Executable file
0
vnpy/api/lts/build.sh
Normal file → Executable file
Loading…
Reference in New Issue
Block a user