allenfrostline

How to Set Up an Algo-trading System on Aliyun

2017-01-25


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

ssh [email protected]_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

Last login: Wed Jan 25 19:56:04 2017 from 85.149.7.103

Welcome to aliyun Elastic Compute Service!

[[email protected]_hostname ~]# ...

Now, enter

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.

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

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.

cd ~
jupyter notebook --generate-config

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

jupyter notebook --ip=your_host_ip

This should open a service on https://host: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.

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

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

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

ps ax | grep python

Well, it should be :)