It's been a while since I first heard of the GitHub project easytrader, which is a well wrapped API for transporting the paper trading signals on Ricequant or Joinquant to the broker's trading softwares or Xueqiu, as I will introduce below.

Server: Aliyun ECS

Aliyun Elastic Compute Service (ECS) is by far the most stable server option in mainland China. Costs less than $7 p/m and offering free trial for months. I also considered Amazon's AWS -- more stable and famous, cheaper, longer free trial, but not as fast as Aliyun if I'm gonna run scripts crawling data from servers right in China.

System: CentOS 7

Light and again, stable, with update cycles famous to be as long as years. The inheritance of the system configuration is expected to be better than other options. At least, I can find more information about my could-happen-in-the-future problems on websites like Stackoverflow, with no confusion about the versions.

Interface: bash & Jupyter Notebook

Well although bash may be the "universal" impression of Linux systems, I choose Jupyter Notebook on Safari using my own Mac.

Mostly, of course. Frist run the following scripts in the bash terminal on your localhost

1
ssh root@your_host_ip

and enter the password for the root user. The terminal now enters through ssh onto your server, and if nothing goes wrong, it should prints

1
2
3
4
5
Last login: Wed Jan 25 19:56:04 2017 from 85.149.7.103

Welcome to aliyun Elastic Compute Service!

[root@your_hostname ~]# ...

Now, enter

1
2
3
sudo yum update -y
sudo yum install bzip2 -y
sudo shutdown -r now

Then reboot the system. Go to the official Anaconda website to check the most up-to-date version, and do the following.

1
2
3
cd ~
wget http://repo.continuum.io/archive/Anaconda3-4.1.1-Linux-x86_64.sh
sudo bash Anaconda3-4.1.1-Linux-x86_64.sh

Notice that the second & third lines should vary with the version you opt. Now, the terminal will ask a lot of questions, just press ENTER until you cannot. It will be

1
Do you approve the license terms? [yes|no]

Of course yes, and then again press ENTER till you can't. After the Anaconda is installed, type the following.

1
2
cd ~
jupyter notebook --generate-config

Let's see whether it's successfully done by entering

1
jupyter notebook --ip=your_host_ip

This should open a service on https:/yourhost:8888/, go check it out on your browser.

trade.py

New a textfile on the top right corner of Jupyter Notebook, rename it to trade.py and then paste the following.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import easytrader
import json
import logging
import os
import subprocess


logger = logging.getLogger('mylogger')
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler('trade.log')
fh.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)


try:
xq_user = easytrader.use('xq')
xq_user.prepare(user='your_xq_mail_address', account='', password='your_xq_pwd', portfolio_code='your_xq_portfolio_code')
for pos in xq_user.position:
logger.info(json.dumps(pos, indent=4, ensure_ascii=False))

jq_follower = easytrader.follower('jq')
jq_follower.login(user='your_jq_account', password='your_jq_pwd')
jq_follower.follow(xq_user, 'your_paper_trade_url')
except:
logger.error('Error receiving signals.')

git_dir = 'easytrader_git'
if not os.path.exists(git_dir):
subprocess.getoutput('git clone http://github.com/shidenggui/easytrader')
subprocess.getoutput('mv easytrader {}'.format(git_dir))
subprocess.getoutput('ln -s `pwd`/{}/easytrader easytrader'.format(git_dir))
else:
subprocess.getoutput('cd {} && git pull'.format(git_dir))
logger.info('easytrader updated.')

This is the main course of our big meal. The script should be kept running and anytime (including the first time) it find the easytrader version not up-to-date, it clones the repository from GitHub automatically.

Talking about keeping it running, we need yet another tool to make our little script a daemon service and enable it to restart anytime the process dies somehow. I tried nohup, which keeps the script running when I log off the server, but has no function on restarting dead scripts. Later I considered supervisor, screen and tmux, which are all very famous monitoring applications on Linux, but also all too redundant. Finally I found a repository on GitHub called pmonitor, which perfectly met my need, with no other functions trivial.

After installation according to the instruction on the GitHub page, enter the following

1
pmonitor python trade.py > trade.log 2>&1 </dev/null &

Now exit the server and try to check whether the process is still there:

1
ps ax | grep python

Well, it should be :)