├── .gitignore ├── README.md ├── bins └── save_data.py ├── docs ├── API │ ├── CTP Client Development Guidance-20141107.pdf │ ├── CTP_API_Manual.pdf │ ├── CTP客户端开发指南-20141107.pdf │ ├── UDP-API使用方法.pdf │ ├── 客户端认证-20110418.pdf │ ├── 组合合约持仓计算规则.pdf │ ├── 综合交易平台API开发FAQ.pdf │ ├── 综合交易平台API技术开发指南.pdf │ ├── 综合交易平台TraderAPI接口说明.pdf │ ├── 综合交易平台交易API特别说明.pdf │ └── 综合交易平台简介.pdf ├── help │ └── 如何安装TAlib.md └── research │ ├── .ipynb_checkpoints │ └── 因子研究文档-checkpoint.ipynb │ └── 因子研究文档.ipynb ├── etc ├── config-default.json └── requirements.txt ├── setup.py ├── tests ├── data │ └── hs300.csv ├── output │ ├── cumulative_return.png │ └── equity.csv ├── test_factor.py ├── test_interface.py ├── test_ml.py └── test_strategy.py └── wolfquant ├── __init__.py ├── api.py ├── backtest.py ├── data.py ├── event.py ├── execution.py ├── factors ├── __init__.py └── trade_factors.py ├── interface ├── __init__.py └── future │ ├── ApiStruct.py │ ├── _MdApi.cpython-36m-x86_64-linux-gnu.so │ ├── _TraderApi.cpython-36m-x86_64-linux-gnu.so │ ├── __init__.py │ ├── libthostmduserapi.so │ └── libthosttraderapi.so ├── portfolio.py ├── strategy.py └── utils ├── __init__.py ├── api_utils.py ├── backtest_utils.py ├── data_utils.py ├── db_utils.py └── factor_utils.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | tmp/ 7 | # Distribution / packaging 8 | .Python 9 | env/ 10 | develop-eggs/ 11 | dist/ 12 | downloads/ 13 | eggs/ 14 | .eggs/ 15 | lib64/ 16 | parts/ 17 | sdist/ 18 | var/ 19 | *.egg-info/ 20 | .installed.cfg 21 | *.egg 22 | 23 | # PyInstaller 24 | # Usually these files are written by a python script from a template 25 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 26 | *.manifest 27 | *.spec 28 | 29 | # Installer logs 30 | pip-log.txt 31 | pip-delete-this-directory.txt 32 | 33 | # Unit test / coverage reports 34 | htmlcov/ 35 | .tox/ 36 | .coverage 37 | .coverage.* 38 | .cache 39 | nosetests.xml 40 | coverage.xml 41 | *,cover 42 | 43 | # Translations 44 | *.mo 45 | *.pot 46 | 47 | # Django stuff: 48 | *.log 49 | 50 | # Sphinx documentation 51 | docs/_build/ 52 | 53 | # PyBuilder 54 | target/ 55 | **/*.DS_Store 56 | .DS_Store 57 | .vscode 58 | build/ 59 | dist/ 60 | *.egg-info 61 | config.json 62 | */**/__pycache__ 63 | */**/*.con -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wolfquant 2 | 重新构建集成交易、回测、建模的AI投资框架。 3 | 期货接口基于pyctp,使用语言python3.6,环境linux64/ubuntu 4 | 5 | # 使用 6 | ## 交易接口调用 7 | 1.安装包 8 | ```shell 9 | $ python setup.py 10 | ``` 11 | 2.复制配置文件,更新配置信息 12 | ```shell 13 | $ cp etc/config-default.json config.json 14 | ``` 15 | 3.使用案例 16 | ```python 17 | # 通过以下方式使用期货版API 18 | >>>from wolfquant.api.future import ApiStruct, MdApi, TraderApi 19 | ``` 20 | 4.运行测试案例 21 | ```shell 22 | $ cd tests 23 | $ python test_api.py 24 | ``` 25 | ## 因子构建并采用机器学习模型训练 26 | ```python 27 | import pandas as pd 28 | import numpy as np 29 | import tushare as ts 30 | from sklearn.linear_model import LogisticRegression 31 | from sklearn.ensemble import RandomForestClassifier 32 | from sklearn.discriminant_analysis import LinearDiscriminantAnalysis, QuadraticDiscriminantAnalysis 33 | from sklearn.svm import LinearSVC, SVC 34 | from sklearn.metrics import confusion_matrix 35 | from wolfquant.utils.factor_utils import Factor_pipeline 36 | from wolfquant.factors import trade_factors as tf 37 | 38 | # 获取数据 39 | datasets = ts.get_k_data('000300', start='2005-01-01', index=True).set_index('date') 40 | datasets.index = pd.to_datetime(datasets.index, format='%Y-%m-%d') 41 | 42 | # 构建特征 43 | datasets = Factor_pipeline(datasets).add(tf.SMA, 50)\ 44 | .add(tf.EWMA, 200)\ 45 | .add(tf.BBANDS, 50)\ 46 | .add(tf.CCI, 20)\ 47 | .add(tf.ForceIndex, 1)\ 48 | .add(tf.EVM, 14)\ 49 | .add(tf.ROC, 5)\ 50 | .add(tf.LAGRETURN, 0)\ 51 | .data.dropna() 52 | 53 | # 构建标签 54 | datasets['direction'] = np.sign(datasets['LAGRETURN_0']).shift(-1) 55 | datasets = datasets.dropna() 56 | 57 | # 构建训练集和测试集 58 | X = datasets[datasets.columns[6:-2]] 59 | y = datasets['direction'] 60 | start_test = '2012-01-01' 61 | X_train = X.loc[:start_test] 62 | X_test = X.loc[start_test:] 63 | y_train = y.loc[:start_test] 64 | y_test = y.loc[start_test:] 65 | 66 | # 构建模型 67 | print('Hit rates/Confusion Matrices:\n') 68 | models = [('LR', LogisticRegression()), 69 | ('LDA', LinearDiscriminantAnalysis()), 70 | ('QDA', QuadraticDiscriminantAnalysis()), 71 | ('LSVC', LinearSVC()), 72 | ('RSVM', SVC()), 73 | ('RF', RandomForestClassifier(n_estimators=1000))] 74 | 75 | # 遍历模型 76 | for m in models: 77 | # 训练模型 78 | m[1].fit(X_train, y_train) 79 | # 预测模型 80 | pred = m[1].predict(X_test) 81 | # 输出hit-rate和交叉验证结果 82 | print("%s:\n%0.3f" % (m[0], m[1].score(X_test, y_test))) 83 | print("%s\n" % confusion_matrix(pred, y_test)) 84 | ``` 85 | 86 | ## 运行策略回测 87 | ```python 88 | import datetime 89 | import numpy as np 90 | 91 | from wolfquant.backtest import Backtest 92 | from wolfquant.data import HistoricCSVDataHandler 93 | from wolfquant.event import SignalEvent, OrderEvent 94 | from wolfquant.execution import SimulatedExecutionHandler 95 | from wolfquant.portfolio import NaivePortfolio 96 | from wolfquant.strategy import Strategy 97 | 98 | # 创建策略 99 | class BuyAndHoldStrategy(Strategy): 100 | """一直持有策略 101 | results: 102 | Total Return: -2.74% 103 | Sharpe Ratio: -0.05 104 | Max Drawdown: 25.00% 105 | Drawdown Duration: 584 106 | 交易信号数: 1 107 | 下单数: 1 108 | 成交数: 1 109 | """ 110 | def init(self): 111 | self.bought = dict([(symbol, False) for symbol in self.symbol_list]) 112 | 113 | def handle_bar(self, bar_dict): 114 | for s in self.symbol_list: 115 | if self.bought[s] is False: 116 | self.order_shares(s, 10) 117 | self.bought[s] = True 118 | 119 | # 运行策略 120 | csv_dir = 'data/' 121 | symbol_list = ['hs300'] 122 | initial_capital = 100000.0 123 | start_date = datetime.datetime(2015, 4, 8, 0, 0, 0) 124 | end_date = datetime.datetime(2017, 10, 27, 0, 0, 0) 125 | heartbeat = 0.0 126 | backtest = Backtest(csv_dir, 127 | symbol_list, 128 | initial_capital, 129 | heartbeat, 130 | start_date, 131 | end_date, 132 | HistoricCSVDataHandler, 133 | SimulatedExecutionHandler, 134 | NaivePortfolio, 135 | MovingAverageCrossStrategy) 136 | backtest.simulate_trading() 137 | ``` 138 | 139 | 140 | # 路线图 141 | ### 0.0.0 142 | * 实现了期货python版的交易接接口 143 | * 整理交易接口的使用文档 144 | ### 0.0.1 145 | * 添加交易接口的测试案例 146 | ### 0.0.2 147 | * 期货交易接口二次开发。 148 | * 添加feature处理模块。 149 | ### 0.0.3 150 | * 添加回测模块。 151 | * 更新策略测试案例。 152 | ### 0.0.4 153 | * 调整回测功能函数,添加交易接口。 154 | * order_shares: 按照数据来买 155 | * order_value: 按照市值来买 156 | * order_percent: 按照仓位百分比来买 157 | * order_target_percent: 买到目标仓位 158 | * 接受并保存期货高频行情数据。 159 | 160 | ### 0.0.5 161 | * 添加tushare数据接口 162 | * 重新定义回测API 163 | 164 | # 附言 165 | 该项目会长期做,有志同道合的小伙伴,欢迎一起入坑,我的微信号wolfquant。 166 | -------------------------------------------------------------------------------- /bins/save_data.py: -------------------------------------------------------------------------------- 1 | """定时保存高频数据 2 | """ 3 | import time 4 | import json 5 | from wolfquant import config 6 | from wolfquant.interface import MdGateway 7 | user_info = config('../config.json')['user_info'] 8 | 9 | 10 | def save_future(symbol_list, data_path): 11 | """保存期货数据 12 | """ 13 | new_getway = MdGateway() 14 | new_getway.connect(user_info['brokerID'], 15 | user_info['userID'], 16 | user_info['password'], 17 | user_info['register_front'], 18 | symbol_list) 19 | try: 20 | while 1: 21 | time.sleep(1) 22 | with open(data_path, 'a') as f: 23 | json.dumps(new_getway._snapshot_cache, f) 24 | except KeyboardInterrupt: 25 | pass 26 | 27 | 28 | def main(): 29 | save_future(['rb1801', 'i1801'], 'data.json') 30 | 31 | 32 | if __name__ == '__main__': 33 | main() -------------------------------------------------------------------------------- /docs/API/CTP Client Development Guidance-20141107.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/docs/API/CTP Client Development Guidance-20141107.pdf -------------------------------------------------------------------------------- /docs/API/CTP_API_Manual.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/docs/API/CTP_API_Manual.pdf -------------------------------------------------------------------------------- /docs/API/CTP客户端开发指南-20141107.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/docs/API/CTP客户端开发指南-20141107.pdf -------------------------------------------------------------------------------- /docs/API/UDP-API使用方法.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/docs/API/UDP-API使用方法.pdf -------------------------------------------------------------------------------- /docs/API/客户端认证-20110418.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/docs/API/客户端认证-20110418.pdf -------------------------------------------------------------------------------- /docs/API/组合合约持仓计算规则.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/docs/API/组合合约持仓计算规则.pdf -------------------------------------------------------------------------------- /docs/API/综合交易平台API开发FAQ.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/docs/API/综合交易平台API开发FAQ.pdf -------------------------------------------------------------------------------- /docs/API/综合交易平台API技术开发指南.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/docs/API/综合交易平台API技术开发指南.pdf -------------------------------------------------------------------------------- /docs/API/综合交易平台TraderAPI接口说明.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/docs/API/综合交易平台TraderAPI接口说明.pdf -------------------------------------------------------------------------------- /docs/API/综合交易平台交易API特别说明.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/docs/API/综合交易平台交易API特别说明.pdf -------------------------------------------------------------------------------- /docs/API/综合交易平台简介.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/docs/API/综合交易平台简介.pdf -------------------------------------------------------------------------------- /docs/help/如何安装TAlib.md: -------------------------------------------------------------------------------- 1 | # windows 2 | 以win7为标准: 3 | 下载[ta-lib-0.4.0-msvc.zip](http://prdownloads.sourceforge.net/ta-lib/ta-lib-0.4.0-msvc.zip) 并解压到 C:\ta-lib 4 | 这个是32位版本的,如果想使用64位版本的,需要重新进行编译。 5 | - 下载并解压**ta-lib-0.4.0-msvc.zip** 6 | - 将解压后的文件移动到C:\ta-lib 7 | - 下载VS2017,免费版的即可,记得选择VS C++ 特性 8 | - 编译ta-lib 9 | - 从开始菜单中进行[VS2015 x64 Native Tools Command Prompt] 10 | - 切换到C:\ta-lib\c\make\cdr\win32\msvc 11 | - 运行nmake 12 | - 安装ta-lib python包 13 | ```sh 14 | $ git clone https://github.com/mrjbq7/ta-lib 15 | $ cd ta-lib 16 | $ python setup.py install 17 | ``` -------------------------------------------------------------------------------- /docs/research/.ipynb_checkpoints/因子研究文档-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 参数设置\n", 8 | "在对因子进行分析前,可以设置股票池,起止日期,调仓周期,因子方向,分组,数据预处理以及IC计算方法等参数。" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": null, 14 | "metadata": { 15 | "collapsed": true 16 | }, 17 | "outputs": [], 18 | "source": [] 19 | } 20 | ], 21 | "metadata": { 22 | "kernelspec": { 23 | "display_name": "Python 3", 24 | "language": "python", 25 | "name": "python3" 26 | }, 27 | "language_info": { 28 | "codemirror_mode": { 29 | "name": "ipython", 30 | "version": 3 31 | }, 32 | "file_extension": ".py", 33 | "mimetype": "text/x-python", 34 | "name": "python", 35 | "nbconvert_exporter": "python", 36 | "pygments_lexer": "ipython3", 37 | "version": "3.6.2" 38 | } 39 | }, 40 | "nbformat": 4, 41 | "nbformat_minor": 2 42 | } 43 | -------------------------------------------------------------------------------- /docs/research/因子研究文档.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 参数设置\n", 8 | "在对因子进行分析前,可以设置股票池,起止日期,调仓周期,因子方向,分组,数据预处理以及IC计算方法等参数。" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": null, 14 | "metadata": { 15 | "collapsed": true 16 | }, 17 | "outputs": [], 18 | "source": [] 19 | } 20 | ], 21 | "metadata": { 22 | "kernelspec": { 23 | "display_name": "Python 3", 24 | "language": "python", 25 | "name": "python3" 26 | }, 27 | "language_info": { 28 | "codemirror_mode": { 29 | "name": "ipython", 30 | "version": 3 31 | }, 32 | "file_extension": ".py", 33 | "mimetype": "text/x-python", 34 | "name": "python", 35 | "nbconvert_exporter": "python", 36 | "pygments_lexer": "ipython3", 37 | "version": "3.6.2" 38 | } 39 | }, 40 | "nbformat": 4, 41 | "nbformat_minor": 2 42 | } 43 | -------------------------------------------------------------------------------- /etc/config-default.json: -------------------------------------------------------------------------------- 1 | { 2 | "user_info":{ 3 | "brokerID": "0000", 4 | "userID": "0000", 5 | "password": "0000", 6 | "register_front":"tcp://180.168.146.187:10010" 7 | } 8 | } -------------------------------------------------------------------------------- /etc/requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | pandas 3 | pymysql 4 | ta-lib -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | """ 2 | name: 'wolfquant' 3 | version: '0.0.2' 4 | description: '构建期货交易的框架' 5 | author: 'rickyall' 6 | author_email: 'rickyallqi@gmail.com' 7 | url: 'https://github.com/rickyall/wolfquant.git' 8 | """ 9 | import os 10 | 11 | # 将包安装到anaconda中 12 | package_path = '{}/site-packages/wolfquant'.format(os.__file__[:-6]) 13 | os.system('rm -rf {}'.format(package_path)) 14 | os.system('cp -rf wolfquant {}'.format(package_path)) 15 | print('安装完成!') 16 | -------------------------------------------------------------------------------- /tests/output/cumulative_return.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/tests/output/cumulative_return.png -------------------------------------------------------------------------------- /tests/output/equity.csv: -------------------------------------------------------------------------------- 1 | datetime,cash,commission,hs300,sh000001,total,returns,equity_curve 2 | 2015-04-08,100000000.0,0.0,0.0,0.0,100000000.0,, 3 | 2015-04-08,100000000.0,0.0,0.0,0.0,100000000.0,0.0,1.0 4 | 2015-04-09,100000000.0,0.0,0.0,0.0,100000000.0,0.0,1.0 5 | 2015-04-10,100000000.0,0.0,0.0,0.0,100000000.0,0.0,1.0 6 | 2015-04-13,100000000.0,0.0,0.0,0.0,100000000.0,0.0,1.0 7 | 2015-04-14,100000000.0,0.0,0.0,0.0,100000000.0,0.0,1.0 8 | 2015-04-15,100000000.0,0.0,0.0,0.0,100000000.0,0.0,1.0 9 | 2015-04-16,100000000.0,0.0,0.0,0.0,100000000.0,0.0,1.0 10 | 2015-04-17,100000000.0,0.0,0.0,0.0,100000000.0,0.0,1.0 11 | 2015-04-20,100000000.0,0.0,0.0,0.0,100000000.0,0.0,1.0 12 | 2015-04-21,100000000.0,0.0,0.0,0.0,100000000.0,0.0,1.0 13 | 2015-04-22,100000000.0,0.0,0.0,0.0,100000000.0,0.0,1.0 14 | 2015-04-23,6672.969999998808,175.32,50006907.720000006,50179735.17,100193315.86000001,0.0019331586000002066,1.0019331586000002 15 | 2015-04-24,6672.969999998808,175.32,49603446.720000006,49943074.23,99553193.92,-0.006388868703521622,0.9955319392 16 | 2015-04-27,6672.969999998808,175.32,50710459.32,51462955.8,102180088.09,0.026386839704117815,1.0218008809 17 | 2015-04-28,6672.969999998808,175.32,50017139.279999994,50881079.07,100904891.32,-0.012479894995557461,1.0090489132 18 | 2015-04-29,6672.969999998808,175.32,50359632.839999996,50885739.54,101252045.35,0.0034404083435268795,1.0125204535 19 | 2015-04-30,6672.969999998808,175.32,50101839.720000006,50488235.55,100596748.24000001,-0.006471939482652456,1.0059674824000002 20 | 2015-05-04,6672.969999998808,175.32,50501081.519999996,50929388.82,101437143.31,0.008354097768597857,1.0143714331 21 | 2015-05-05,6672.969999998808,175.32,48487468.32,48863436.57,97357577.86,-0.040217668961087805,0.9735757786 22 | 2015-05-06,6672.969999998808,175.32,48028524.839999996,48074112.09,96109309.9,-0.012821477150910643,0.9610930990000001 23 | 2015-05-07,6672.969999998808,175.32,47150509.32,46743491.07,93900673.36,-0.022980464039311643,0.9390067336 24 | 2015-05-08,6672.969999998808,175.32,48082003.199999996,47808692.64,95897368.81,0.021263909816120252,0.9589736881 25 | 2015-05-11,6672.969999998808,175.32,49475710.44,49259803.86,98742187.27,0.029665239988350356,0.9874218727 26 | 2015-05-12,6672.969999998808,175.32,50075786.160000004,50028667.74,100111126.87,0.013863776343709944,1.0011112687000001 27 | 2015-05-13,6672.969999998808,175.32,49770105.12,49739263.92,99516042.00999999,-0.005944242948865863,0.9951604200999999 28 | 2015-05-14,6672.969999998808,175.32,49583827.44,49768249.77,99358750.18,-0.001580567583105652,0.9935875018000001 29 | 2015-05-15,6672.969999998808,175.32,48705073.56,48976879.23,97688625.75999999,-0.016809032088008213,0.9768862576 30 | 2015-05-18,6672.969999998808,175.32,48258576.720000006,48690430.83,96955680.52000001,-0.007502871847134718,0.9695568052000002 31 | 2015-05-19,6672.969999998808,175.32,49904908.56,50214290.85,100125872.38,0.03269732977993001,1.0012587238 32 | 2015-05-20,6672.969999998808,175.32,50154896.160000004,50540978.43,100702547.56,0.00575950217753296,1.0070254755999999 33 | 2015-05-21,6672.969999998808,175.32,51062657.04,51485917.14,102555247.15,0.018397743005420297,1.0255524714999997 34 | 2015-05-22,6672.969999998808,175.32,52226628.839999996,52942939.2,105176241.00999999,0.025556896724810763,1.0517624100999996 35 | 2015-05-25,6672.969999998808,175.32,53789526.0,54718464.6,108514663.57,0.0317412233784109,1.0851466356999995 36 | 2015-05-26,6672.969999998808,175.32,54838208.160000004,55822200.3,110667081.43,0.019835271927204134,1.1066708142999997 37 | 2015-05-27,6672.969999998808,175.32,54653723.64,56172417.57,110832814.18,0.0014975794776410645,1.1083281417999997 38 | 2015-05-28,6672.969999998808,175.32,50989137.480000004,52518609.09,103514419.54,-0.06603093762569656,1.0351441953999998 39 | 2015-05-29,6672.969999998808,175.32,51061074.839999996,52421648.58,103489396.38999999,-0.00024173588676068558,1.0348939638999997 40 | 2015-06-01,6672.969999998808,175.32,53543546.64,54888287.58,108438507.19,0.04782239507272101,1.0843850718999997 41 | 2015-06-02,6672.969999998808,175.32,54447404.76,55817994.51,110272072.24,0.01690880018098473,1.1027207223999995 42 | 2015-06-03,6672.969999998808,175.32,54254587.32,55811742.66,110073002.94999999,-0.0018052557275494152,1.1007300294999995 43 | 2015-06-04,6672.969999998808,175.32,54653618.160000004,56233685.7,110893976.83000001,0.007458449011088941,1.1089397682999997 44 | 2015-06-05,6672.969999998808,175.32,55171841.4,57097577.7,112276092.07,0.012463393229361408,1.1227609206999996 45 | 2015-06-08,6672.969999998808,175.32,56471355.0,58334079.96,114812107.93,0.02258731857552454,1.1481210792999996 46 | 2015-06-09,6672.969999998808,175.32,56088568.08,58125495.51,114220736.56,-0.005150775302902311,1.1422073655999996 47 | 2015-06-10,6672.969999998808,175.32,56000492.279999994,58040356.68,114047521.92999999,-0.0015164902207491782,1.1404752192999994 48 | 2015-06-11,6672.969999998808,175.32,55973911.32,58217113.53,114197697.82,0.0013167834553404756,1.1419769781999995 49 | 2015-06-12,6672.969999998808,175.32,56274845.76,58725900.45,115007419.18,0.007090522623987683,1.1500741917999997 50 | 2015-06-15,6672.969999998808,175.32,55072901.160000004,57551007.33,112630581.46000001,-0.02066682077510118,1.1263058145999998 51 | 2015-06-16,6672.969999998808,175.32,53423721.36,55555416.81,108985811.14,-0.03236039690778325,1.0898581113999997 52 | 2015-06-17,6672.969999998808,175.32,54204378.839999996,56470119.3,110681171.10999998,0.015555786136437266,1.1068117110999995 53 | 2015-06-18,6672.969999998808,175.32,52007441.4,54395187.12,106409301.49,-0.03859617292768258,1.0640930148999996 54 | 2015-06-19,6672.969999998808,175.32,48911603.4,50905518.12,99823794.49,-0.061888452492274704,0.9982379448999996 55 | 2015-06-23,6672.969999998808,175.32,50483677.32,52020961.83,102511312.12,0.026922615431827168,1.0251131211999998 56 | 2015-06-24,6672.969999998808,175.32,51475611.24,53312935.05,104795219.25999999,0.022279562057760494,1.0479521925999997 57 | 2015-06-25,6672.969999998808,175.32,49644372.96,51467275.26,101118321.19,-0.03508650581547523,1.0111832118999997 58 | 2015-06-26,6672.969999998808,175.32,45738132.12,47660353.29,93405158.38,-0.07627858848157765,0.9340515837999998 59 | 2015-06-29,6672.969999998808,175.32,44212469.4,46070792.010000005,90289934.38,-0.03335173403728242,0.9028993437999997 60 | 2015-06-30,-35243.830000001195,176.62,47225934.0,48619159.74,95809849.91,0.061135447355278094,0.9580984990999997 61 | 2015-07-01,-35243.830000001195,176.62,44903385.160000004,46078407.9,90946549.23,-0.05075992379247418,0.9094654922999998 62 | 2015-07-02,-75782.1300000012,177.92000000000002,43372264.0,44515584.29,87812066.16,-0.03446511271222652,0.8781206615999998 63 | 2015-07-03,-75782.1300000012,177.92000000000002,41027543.36,41946088.84,82897850.07,-0.05596287964624291,0.8289785006999998 64 | 2015-07-06,-75782.1300000012,177.92000000000002,42216585.32,42958528.07,85099331.25999999,0.026556553494946344,0.8509933125999998 65 | 2015-07-07,-75782.1300000012,177.92000000000002,41471824.0,42403444.24,83799486.11,-0.015274446117897633,0.8379948610999999 66 | 2015-07-08,-75782.1300000012,177.92000000000002,38674376.32,39901300.63,78499894.82,-0.06324133399867704,0.7849989481999998 67 | 2015-07-09,-75782.1300000012,177.92000000000002,41151177.54,42201047.41,83276442.82,0.06084782675126643,0.8327644281999997 68 | 2015-07-10,-75782.1300000012,177.92000000000002,43357060.480000004,44117730.6,87399008.95,0.04950458965821625,0.8739900894999998 69 | 2015-07-13,-75782.1300000012,177.92000000000002,44468289.980000004,45171127.03,89563634.88,0.02476716791191924,0.8956363487999996 70 | 2015-07-14,-75782.1300000012,177.92000000000002,43416079.699999996,44648922.73,87989220.29999998,-0.017578725808856,0.8798922029999996 71 | 2015-07-15,-75782.1300000012,177.92000000000002,41881052.080000006,43297448.9,85102718.85,-0.03280517136256511,0.8510271884999997 72 | 2015-07-16,-75782.1300000012,177.92000000000002,42204126.88,43496318.86,85624663.61,0.00613311498214264,0.8562466360999997 73 | 2015-07-17,-75782.1300000012,177.92000000000002,43831537.0,45022770.949999996,88778525.82,0.03683357197600312,0.8877852581999996 74 | 2015-07-20,-75782.1300000012,177.92000000000002,43927720.379999995,45418235.47,89270173.72,0.0055379146641478805,0.8927017371999998 75 | 2015-07-21,-75782.1300000012,177.92000000000002,43984733.580000006,45709145.36,89618096.81,0.0038974169703229755,0.8961809680999999 76 | 2015-07-22,-75782.1300000012,177.92000000000002,43891295.28,45804257.08,89619770.22999999,1.8672791094243024e-05,0.8961977022999998 77 | 2015-07-23,-75782.1300000012,177.92000000000002,44880051.980000004,46917837.84,91722107.69,0.023458411627306885,0.9172210768999999 78 | 2015-07-24,-75782.1300000012,177.92000000000002,44093164.239999995,46314743.07,90332125.17999999,-0.015154280085863614,0.9033212517999998 79 | 2015-07-27,-75782.1300000012,177.92000000000002,40318151.34,42385696.12,82628065.33,-0.0852859360349214,0.8262806532999999 80 | 2015-07-28,-75782.1300000012,177.92000000000002,40237488.22,41673951.0,81835657.09,-0.009590061643526049,0.8183565708999999 81 | 2015-07-29,-75782.1300000012,177.92000000000002,41496952.04,43109387.09,84530557.0,0.03293063202310753,0.84530557 82 | 2015-07-30,-75782.1300000012,177.92000000000002,40283098.78,42160545.29,82367861.94,-0.02558477238000456,0.8236786194 83 | 2015-07-31,-75782.1300000012,177.92000000000002,40296718.6,41682256.21,81903192.68,-0.005641390331807772,0.8190319268 84 | 2015-08-03,-75782.1300000012,177.92000000000002,40429115.919999994,41217847.07,81571180.85999998,-0.004053710351649031,0.8157118085999998 85 | 2015-08-04,-75782.1300000012,177.92000000000002,41684673.28,42738155.58,84347046.72999999,0.0340299826572843,0.8434704672999999 86 | 2015-08-05,-75782.1300000012,177.92000000000002,40826730.2,42033122.89,82784070.96000001,-0.018530296324460127,0.8278407096 87 | 2015-08-06,-75782.1300000012,177.92000000000002,40456672.3,41657340.58,82038230.75,-0.009009465243143056,0.8203823075 88 | 2015-08-07,-75782.1300000012,177.92000000000002,41249578.1,42597877.17,83771673.14,0.021129690074404683,0.8377167313999999 89 | 2015-08-10,-75782.1300000012,177.92000000000002,43122672.88,44693634.34,87740525.09,0.04737701661237237,0.8774052509 90 | 2015-08-11,-75782.1300000012,177.92000000000002,42935901.86,44687832.07,87547951.8,-0.0021948043940068773,0.875479518 91 | 2015-08-12,-75782.1300000012,177.92000000000002,42402300.54,44214662.64,86541181.05,-0.011499649384144717,0.8654118105 92 | 2015-08-13,-75782.1300000012,177.92000000000002,43028706.68,44991029.12,87943953.66999999,0.016209307557167874,0.8794395367000001 93 | 2015-08-14,-75782.1300000012,177.92000000000002,43008435.32,45113559.41,88046212.6,0.0011627738546269306,0.8804621260000001 94 | 2015-08-17,-75782.1300000012,177.92000000000002,43054151.46,45435983.59,88414352.92,0.004181216989678882,0.8841435292000001 95 | 2015-08-18,-75782.1300000012,177.92000000000002,40388678.78,42642816.32,82955712.97,-0.06173929650244847,0.8295571297000001 96 | 2015-08-19,-75782.1300000012,177.92000000000002,41029866.12,43165589.47,84119673.46,0.014031107060955783,0.8411967346 97 | 2015-08-20,-75782.1300000012,177.92000000000002,39713389.1,41688627.33,81326234.3,-0.033207917305198675,0.813262343 98 | 2015-08-21,-75782.1300000012,177.92000000000002,37898363.32,39907557.98,77730139.16999999,-0.04421814388619749,0.7773013916999999 99 | 2015-08-24,-75782.1300000012,177.92000000000002,34583045.74,36519146.07,71026409.68,-0.08624363164124227,0.7102640968000001 100 | 2015-08-25,-75782.1300000012,177.92000000000002,32127254.939999998,33732463.69,65783936.49999999,-0.07381019544165723,0.657839365 101 | 2015-08-26,-75782.1300000012,177.92000000000002,31945235.02,33303778.33,65173231.22,-0.009283501603769118,0.6517323121999999 102 | 2015-08-27,-75782.1300000012,177.92000000000002,33845147.12,35082003.43,68851368.41999999,0.05643631796594528,0.6885136841999998 103 | 2015-08-28,-75782.1300000012,177.92000000000002,35287897.82,36774445.949999996,71986561.63999999,0.04553567041507467,0.7198656163999998 104 | 2015-08-31,-75782.1300000012,177.92000000000002,35543929.32,36474548.23,71942695.41999999,-0.0006093667901430067,0.7194269541999998 105 | 2015-09-01,-75782.1300000012,177.92000000000002,35496840.64,36026635.74,71447694.25,-0.006880492412887462,0.7144769424999999 106 | 2015-09-02,-75782.1300000012,177.92000000000002,35536433.14,35953254.09,71413905.1,-0.00047292148969535486,0.7141390509999999 107 | 2015-09-07,-75782.1300000012,177.92000000000002,34318673.419999994,35045938.34,69288829.63,-0.029757166577353278,0.6928882962999999 108 | 2015-09-08,-75782.1300000012,177.92000000000002,35200583.16,36070209.65,71195010.67999999,0.02751065446160572,0.7119501067999999 109 | 2015-09-09,-75782.1300000012,177.92000000000002,35889809.4,36896634.93,72710662.19999999,0.021288732251370623,0.7271066219999999 110 | 2015-09-10,-75782.1300000012,177.92000000000002,35449118.48,36382394.53,71755730.88,-0.013133305227964076,0.7175573088 111 | 2015-09-11,-75782.1300000012,177.92000000000002,35339632.02,36409016.71,71672866.6,-0.001154810619079072,0.716728666 112 | 2015-09-14,-75782.1300000012,177.92000000000002,34642170.54,35437079.6,70003468.00999999,-0.023291918813806767,0.7000346800999999 113 | 2015-09-15,-75782.1300000012,177.92000000000002,33281244.34,34189819.09,67395281.3,-0.03725796427153316,0.673952813 114 | 2015-09-16,-75782.1300000012,177.92000000000002,34939061.5,35863262.02,70726541.39,0.04942868440850323,0.7072654139 115 | 2015-09-17,-75782.1300000012,177.92000000000002,34176246.0,35110104.62,69210568.49,-0.021434285774567075,0.6921056848999999 116 | 2015-09-18,-75782.1300000012,177.92000000000002,34326908.66,35245035.84,69496162.37,0.004126448983601039,0.6949616237 117 | 2015-09-21,-75782.1300000012,177.92000000000002,34928503.5,35911955.58,70764676.94999999,0.018253016234858643,0.7076467694999998 118 | 2015-09-22,-75782.1300000012,177.92000000000002,35253478.74,36242798.74,71420495.35,0.00926759547653111,0.7142049534999999 119 | 2015-09-23,-75782.1300000012,177.92000000000002,34451070.74,35449480.53,69824769.14,-0.022342693118831636,0.6982476914 120 | 2015-09-24,-75782.1300000012,177.92000000000002,34683030.0,35754384.13,70361632.0,0.0076887165774022215,0.70361632 121 | 2015-09-25,-75782.1300000012,177.92000000000002,34122928.1,35181665.949999996,69228811.91999999,-0.0160999688011787,0.6922881191999998 122 | 2015-09-28,-75782.1300000012,177.92000000000002,34236954.5,35277346.52,69438518.89,0.0030291863197413615,0.6943851888999999 123 | 2015-09-29,-75782.1300000012,177.92000000000002,33562298.3,34564918.78,68051434.94999999,-0.019975713223338465,0.6805143494999998 124 | 2015-09-30,-75782.1300000012,177.92000000000002,33816746.1,34731478.06,68472442.03,0.006186601065934161,0.6847244203 125 | 2015-10-08,-75782.1300000012,177.92000000000002,34804235.84,35762006.72,70490460.43,0.029471979385748304,0.7049046043000001 126 | 2015-10-09,-75782.1300000012,177.92000000000002,35264986.96,36214697.550000004,71403902.38,0.012958376841744057,0.7140390238000001 127 | 2015-10-12,-75782.1300000012,177.92000000000002,36400711.02,37403707.82,73728636.71000001,0.03255752490428532,0.7372863671000002 128 | 2015-10-13,-75782.1300000012,177.92000000000002,36372732.32,37467077.71,73764027.9,0.0004800195904774984,0.7376402790000002 129 | 2015-10-14,-75782.1300000012,177.92000000000002,35961709.38,37116779.88,73002707.13,-0.010321030340589732,0.7300270713000001 130 | 2015-10-15,-75782.1300000012,177.92000000000002,36813739.98,37977222.39,74715180.24,0.023457665849986986,0.7471518024000001 131 | 2015-10-16,-75782.1300000012,177.92000000000002,37312605.48,38583388.949999996,75820212.29999998,0.014789926979368984,0.758202123 132 | 2015-10-19,-75782.1300000012,177.92000000000002,37313872.44,38530485.9,75768576.21,-0.0006810333080534692,0.7576857621000002 133 | 2015-10-20,-75782.1300000012,177.92000000000002,37773356.6,38969979.41,76667553.88,0.011864782406738161,0.7666755388000003 134 | 2015-10-21,-75782.1300000012,177.92000000000002,36670573.5,37779376.36,74374167.72999999,-0.029913386223194394,0.7437416773000002 135 | 2015-10-22,-75782.1300000012,177.92000000000002,37211987.74,38326154.98,75462360.59,0.014631328231469842,0.7546236059000004 136 | 2015-10-23,-75782.1300000012,177.92000000000002,37705151.919999994,38823216.11,76452585.89999999,0.013122108853446113,0.7645258590000003 137 | 2015-10-26,-75782.1300000012,177.92000000000002,37895407.080000006,39018331.66,76837956.61,0.005040649776111961,0.7683795661000004 138 | 2015-10-27,-75782.1300000012,177.92000000000002,37933627.04,39072486.18,76930331.09,0.001202198549720146,0.7693033109000004 139 | 2015-10-28,-75782.1300000012,177.92000000000002,37216105.36,38399650.4,75539973.63,-0.018072942626146338,0.7553997363000002 140 | 2015-10-29,-75782.1300000012,177.92000000000002,37304686.98,38537425.87,75766330.72,0.0029965206383142373,0.7576633072000003 141 | 2015-10-30,-75782.1300000012,177.92000000000002,37312816.64,38483385.12,75720419.63,-0.0006059563603478813,0.7572041963000002 142 | 2015-11-02,-75782.1300000012,177.92000000000002,36699185.68,37829435.16,74452838.71,-0.016740278595838598,0.7445283871000001 143 | 2015-11-03,-75782.1300000012,177.92000000000002,36588643.419999994,37734095.9,74246957.19,-0.0027652608492461095,0.7424695719000002 144 | 2015-11-04,-75782.1300000012,177.92000000000002,38310125.32,39360324.28,77594667.47,0.04508885490664771,0.7759466747000001 145 | 2015-11-05,-75782.1300000012,177.92000000000002,39127631.26,40079123.14,79130972.27,0.019799102826157045,0.7913097227 146 | 2015-11-06,-75782.1300000012,177.92000000000002,40050400.46,40843771.31,80818389.64,0.021324360381197227,0.8081838964 147 | 2015-11-09,-75782.1300000012,177.92000000000002,40546415.3,41490553.76,81961186.92999999,0.014140312558694967,0.8196118693 148 | 2015-11-10,-75782.1300000012,177.92000000000002,40471347.919999994,41417854.73,81813420.51999998,-0.0018028827489554589,0.8181342051999999 149 | 2015-11-11,-75782.1300000012,177.92000000000002,40475676.7,41528894.25,81928788.82,0.0014101390611311881,0.8192878882 150 | 2015-11-12,-75782.1300000012,177.92000000000002,40070988.56,41331503.300000004,81326709.73,-0.007348809846594584,0.8132670973000001 151 | 2015-11-13,-75782.1300000012,177.92000000000002,39552801.919999994,40739216.68,80216236.47,-0.013654471743498653,0.8021623647000001 152 | 2015-11-16,-75782.1300000012,177.92000000000002,39741684.54,41036383.92,80702286.33,0.006059245377109779,0.8070228633000001 153 | 2015-11-17,-75782.1300000012,177.92000000000002,39681081.62,41011695.83,80616995.32,-0.0010568598967721776,0.8061699532000001 154 | 2015-11-18,-75782.1300000012,177.92000000000002,39229093.64,40598483.19,79751794.69999999,-0.010732236007627072,0.797517947 155 | 2015-11-19,-75782.1300000012,177.92000000000002,39856133.26,41151291.62,80931642.75,0.014793999990071915,0.8093164275000002 156 | 2015-11-20,-75782.1300000012,177.92000000000002,39849904.04,41304198.5,81078320.41,0.0018123647934973341,0.8107832041000003 157 | 2015-11-23,-75782.1300000012,177.92000000000002,39627658.14,41074496.87,80626372.88,-0.00557420932888808,0.8062637288000003 158 | 2015-11-24,-75782.1300000012,177.92000000000002,39633570.62,41140483.47,80698271.96,0.0008917563500843162,0.8069827196000003 159 | 2015-11-25,-75782.1300000012,177.92000000000002,39926238.38,41502499.61,81352955.86,0.008112737535749481,0.8135295586000004 160 | 2015-11-26,-75782.1300000012,177.92000000000002,39692061.94,41361652.35,80977932.16,-0.004609834959720227,0.8097793216000003 161 | 2015-11-27,-75782.1300000012,177.92000000000002,37554700.419999994,39094785.1,76573703.38999999,-0.054388012295719435,0.7657370339000001 162 | 2015-11-30,-75782.1300000012,177.92000000000002,37654156.78,39198429.57,76776804.22,0.0026523574152550466,0.7677680422000002 163 | 2015-12-01,-75782.1300000012,177.92000000000002,37921168.6,39322438.87,77167825.34,0.0050929590515327305,0.7716782534000002 164 | 2015-12-02,-75782.1300000012,177.92000000000002,39296453.68,40239425.07,79460096.62,0.029705013325181717,0.7946009662000001 165 | 2015-12-03,-75782.1300000012,177.92000000000002,39585109.4,40784497.14,80293824.41,0.01049240845989785,0.8029382441 166 | 2015-12-04,-75782.1300000012,177.92000000000002,38827995.22,40103811.23,78856024.32,-0.017906733183591372,0.7885602432 167 | 2015-12-07,-75782.1300000012,177.92000000000002,38933786.38,40239652.61,79097656.86,0.0030642242248919427,0.7909765686000001 168 | 2015-12-08,-75782.1300000012,177.92000000000002,38251845.16,39478986.39,77655049.41999999,-0.018238308153089466,0.7765504942 169 | 2015-12-09,-75782.1300000012,177.92000000000002,38388254.52,39505949.88,77818422.27000001,0.0021038277770761837,0.7781842227000002 170 | 2015-12-10,-75782.1300000012,177.92000000000002,38252478.64,39313223.5,77489920.00999999,-0.0042213945029654365,0.7748992001 171 | 2015-12-11,-75782.1300000012,177.92000000000002,38093897.48,39075216.66,77093332.00999999,-0.005117930176580687,0.7709333201 172 | 2015-12-14,-75782.1300000012,177.92000000000002,39184116.56,40054662.59,79162997.02000001,0.026846225945086344,0.7916299702000003 173 | 2015-12-15,-75782.1300000012,177.92000000000002,39005369.62,39937251.949999996,78866839.44,-0.003741111265976871,0.7886683944000001 174 | 2015-12-16,-75782.1300000012,177.92000000000002,38910875.52,40003693.63,78838787.02000001,-0.0003556934726834937,0.7883878702000003 175 | 2015-12-17,-75782.1300000012,177.92000000000002,39654686.62,40729660.0,80308564.49,0.018642821960555223,0.8030856449000002 176 | 2015-12-18,-75782.1300000012,177.92000000000002,39781593.78,40717827.92,80423639.57,0.001432911679231097,0.8042363957000003 177 | 2015-12-21,-75782.1300000012,177.92000000000002,40816911.26,41440381.19,82181510.32,0.021857637373772,0.8218151032000003 178 | 2015-12-22,-75782.1300000012,177.92000000000002,40930515.34,41546187.29,82400920.5,0.0026698241386129418,0.8240092050000003 179 | 2015-12-23,-75782.1300000012,177.92000000000002,40821240.04,41367795.93,82113253.84,-0.0034910612436664934,0.8211325384000003 180 | 2015-12-24,-75782.1300000012,177.92000000000002,40430805.2,41099298.73,81454321.8,-0.00802467335278123,0.8145432180000003 181 | 2015-12-25,-75782.1300000012,177.92000000000002,40523715.6,41274732.07,81722665.53999999,0.003294407639399033,0.8172266554000002 182 | 2015-12-28,-75782.1300000012,177.92000000000002,39356317.54,40203815.06,79484350.47,-0.027389158872998642,0.7948435047000002 183 | 2015-12-29,-75782.1300000012,177.92000000000002,39717823.46,40544669.98,80186711.31,0.008836467000697068,0.8018671131000001 184 | 2015-12-30,-75782.1300000012,177.92000000000002,39752770.44,40648655.76,80325644.07,0.0017326157630144223,0.8032564407 185 | 2015-12-31,-75782.1300000012,177.92000000000002,39391898.0,40265250.86,79581366.72999999,-0.009265750043054743,0.7958136673 186 | 2016-01-04,-75782.1300000012,177.92000000000002,36640588.78,37506100.82,74070907.47,-0.06924308398341061,0.7407090747000001 187 | 2016-01-05,-75782.1300000012,177.92000000000002,36728959.24,37404276.67,74057453.78,-0.00018163257963921264,0.7405745378000002 188 | 2016-01-06,-75782.1300000012,177.92000000000002,37373313.98,38247653.68,75545185.53,0.02008888604811543,0.7554518553000001 189 | 2016-01-07,-75782.1300000012,177.92000000000002,34782064.04,35553125.0,70259406.91,-0.06996843786823381,0.7025940691000001 190 | 2016-01-08,-75782.1300000012,177.92000000000002,35491350.48,36251786.57,71667354.91999999,0.020039281171324586,0.7166735492 191 | 2016-01-11,-75782.1300000012,177.92000000000002,33705887.1,34320995.9,67951100.87,-0.051854209690706754,0.6795110087000001 192 | 2016-01-12,-75782.1300000012,177.92000000000002,33951466.18,34391078.22,68266762.27,0.004645419955798813,0.6826676227000001 193 | 2016-01-13,-75782.1300000012,177.92000000000002,33319781.040000003,33557599.199999996,66801598.11,-0.021462335568298463,0.6680159811000002 194 | 2016-01-14,-75782.1300000012,177.92000000000002,34013336.06,34218034.050000004,68155587.98,0.0202688245237852,0.6815558798000003 195 | 2016-01-15,-75782.1300000012,177.92000000000002,32927551.34,33004335.689999998,65856104.89999999,-0.033738731454782345,0.6585610490000002 196 | 2016-01-18,-75782.1300000012,177.92000000000002,33054247.34,33150757.680000003,66129222.89,0.004147193193626109,0.6612922289000003 197 | 2016-01-19,-75782.1300000012,177.92000000000002,34029700.96,34219057.98,68172976.81,0.030905457990934027,0.6817297681000004 198 | 2016-01-20,-75782.1300000012,177.92000000000002,33515104.040000003,33865802.13,67305124.04,-0.01273015805689004,0.6730512404000004 199 | 2016-01-21,-75782.1300000012,177.92000000000002,32532893.3,32771220.96,65228332.129999995,-0.030856371481698175,0.6522833213000002 200 | 2016-01-22,-75782.1300000012,177.92000000000002,32871910.68,33181703.12,65977831.67,0.011490398658458023,0.6597783167000003 201 | 2016-01-25,-75782.1300000012,177.92000000000002,33034820.619999997,33431428.270000003,66390466.76,0.006254147484928918,0.6639046676000002 202 | 2016-01-26,-75782.1300000012,177.92000000000002,31045904.580000002,31284360.83,62254483.28,-0.06229785211409167,0.6225448328000002 203 | 2016-01-27,-75782.1300000012,177.92000000000002,30938635.3,31122466.12,61985319.29,-0.004323608129383927,0.6198531929000002 204 | 2016-01-28,-75782.1300000012,177.92000000000002,30129998.080000002,30213443.819999997,60267659.769999996,-0.02771074731363221,0.6026765977000001 205 | 2016-01-29,-75782.1300000012,177.92000000000002,31104818.220000003,31145675.2,62174711.29,0.03164303255307899,0.6217471129000002 206 | 2016-02-01,-75782.1300000012,177.92000000000002,30629285.900000002,30591046.45,61144550.22,-0.0165688114769853,0.6114455022000002 207 | 2016-02-02,-75782.1300000012,177.92000000000002,31265722.14,31281857.89,62471797.9,0.021706720798902346,0.6247179790000001 208 | 2016-02-03,-75782.1300000012,177.92000000000002,31131741.119999997,31164447.25,62220406.239999995,-0.004024082361170578,0.6222040624000001 209 | 2016-02-04,-75782.1300000012,177.92000000000002,31513096.080000002,31639664.54,63076978.489999995,0.013766741520394143,0.6307697849000001 210 | 2016-02-05,-75782.1300000012,177.92000000000002,31291694.82,31440225.729999997,62656138.419999994,-0.006671848907073397,0.6265613842000002 211 | 2016-02-15,-75782.1300000012,177.92000000000002,31111364.18,31243517.4,62279099.449999996,-0.006017590287365149,0.6227909945000002 212 | 2016-02-16,-75782.1300000012,177.92000000000002,32065068.32,32271656.89,64260943.08,0.03182196993055597,0.6426094308000002 213 | 2016-02-17,-75782.1300000012,177.92000000000002,32342532.560000002,32621727.180000003,64888477.61,0.009765411149020409,0.6488847761000002 214 | 2016-02-18,-75782.1300000012,177.92000000000002,32240964.599999998,32571099.529999997,64736281.99999999,-0.0023454951573181892,0.6473628200000001 215 | 2016-02-19,-75782.1300000012,177.92000000000002,32218581.64,32538447.54,64681247.05,-0.0008501407294289054,0.6468124705000001 216 | 2016-02-22,-75782.1300000012,177.92000000000002,32929029.459999997,33302526.86,66155774.19,0.022796826085621946,0.6615577419 217 | 2016-02-23,-75782.1300000012,177.92000000000002,32617462.880000003,33031185.41,65572866.16,-0.00881114365506308,0.6557286616 218 | 2016-02-24,-75782.1300000012,177.92000000000002,32830628.900000002,33322095.3,66076942.07,0.007687263643014086,0.6607694207 219 | 2016-02-25,-75782.1300000012,177.92000000000002,30816162.5,31187201.25,61927581.62,-0.06279589097213811,0.6192758161999999 220 | 2016-02-26,-75782.1300000012,177.92000000000002,31125300.740000002,31482548.17,62532066.78,0.009761162057146722,0.6253206678 221 | 2016-02-29,-75782.1300000012,177.92000000000002,30380328.259999998,30581148.46,60885694.589999996,-0.026328446743848488,0.6088569458999998 222 | 2016-03-01,-75782.1300000012,177.92000000000002,30942225.02,31095275.09,61961717.98,0.01767284412612624,0.6196171797999999 223 | 2016-03-02,-75782.1300000012,177.92000000000002,32215942.14,32420809.36,64560969.37,0.0419493111995215,0.6456096936999999 224 | 2016-03-03,-75782.1300000012,177.92000000000002,32290798.36,32535489.520000003,64750505.75,0.0029357734533657087,0.6475050574999999 225 | 2016-03-04,-75782.1300000012,177.92000000000002,32665290.619999997,32699204.55,65288713.03999999,0.008312016775251063,0.6528871303999998 226 | 2016-03-07,-75782.1300000012,177.92000000000002,32780900.720000003,32963037.180000003,65668155.77,0.0058117661128891385,0.6566815576999999 227 | 2016-03-08,-75782.1300000012,177.92000000000002,32810779.86,33009114.029999997,65744111.75999999,0.0011566639737230489,0.6574411175999998 228 | 2016-03-09,-75782.1300000012,177.92000000000002,32433225.779999997,32567345.12,64924788.769999996,-0.012462302220934252,0.6492478876999999 229 | 2016-03-10,-75782.1300000012,177.92000000000002,31812837.7,31909413.21,63646468.78,-0.01968924372674541,0.6364646878 230 | 2016-03-11,-75782.1300000012,177.92000000000002,31867000.240000002,31972896.87,63764114.980000004,0.001848432477953521,0.6376411498000001 231 | 2016-03-14,-75782.1300000012,177.92000000000002,32367555.02,32532531.5,64824304.39,0.01662674076684878,0.6482430439000001 232 | 2016-03-15,-75782.1300000012,177.92000000000002,32463527.240000002,32587937.49,64975682.599999994,0.002335207626591229,0.6497568260000001 233 | 2016-03-16,-75782.1300000012,177.92000000000002,32624536.740000002,32656882.11,65205636.72,0.0035390797110304018,0.6520563672000002 234 | 2016-03-17,-75782.1300000012,177.92000000000002,32985303.599999998,33048250.91,65957772.379999995,0.011534825788600989,0.6595777238000002 235 | 2016-03-18,-75782.1300000012,177.92000000000002,33489553.68,33620741.550000004,67034513.1,0.016324698077985644,0.6703451310000003 236 | 2016-03-21,-75782.1300000012,177.92000000000002,34307587.52,34344887.6,68576692.99000001,0.023005759551045557,0.6857669299000004 237 | 2016-03-22,-75782.1300000012,177.92000000000002,34057890.82,34123718.72,68105827.41,-0.0068662625663310495,0.6810582741000003 238 | 2016-03-23,-75782.1300000012,177.92000000000002,34166638.22,34244314.92,68335171.00999999,0.0033674592721608665,0.6833517101000002 239 | 2016-03-24,-75782.1300000012,177.92000000000002,33593972.3,33686955.69,67205145.85999998,-0.016536508701128994,0.6720514586000002 240 | 2016-03-25,-75782.1300000012,177.92000000000002,33762583.56,33896975.11,67583776.53999999,0.005633953697366634,0.6758377654000003 241 | 2016-03-28,-75782.1300000012,177.92000000000002,33466009.34,33651118.14,67041345.349999994,-0.008026056218964794,0.6704134535000004 242 | 2016-03-29,-75782.1300000012,177.92000000000002,33103658.779999997,33218905.91,66246782.559999995,-0.011851832415531893,0.6624678256000004 243 | 2016-03-30,-75782.1300000012,177.92000000000002,33957484.24,34138395.050000004,68020097.16,0.026768312836837005,0.6802009716000004 244 | 2016-03-31,-75782.1300000012,177.92000000000002,33976594.22,34175597.84,68076409.93,0.0008278842923077345,0.6807640993000005 245 | 2016-04-01,-75782.1300000012,177.92000000000002,34016714.62,34239422.81,68180355.3,0.0015268926505800362,0.6818035530000004 246 | 2016-04-05,-75782.1300000012,177.92000000000002,34466485.419999994,34734777.39,69125480.67999999,0.013862136327118746,0.6912548068000003 247 | 2016-04-06,-75782.1300000012,177.92000000000002,34393001.74,34706562.43,69023782.03999999,-0.001471217834575267,0.6902378204000003 248 | 2016-04-07,-75782.1300000012,177.92000000000002,33883683.82,34226794.34,68034696.03,-0.014329640897202678,0.6803469603000004 249 | 2016-04-08,-75782.1300000012,177.92000000000002,33634937.34,33959889.92,67519045.13,-0.007579234274415314,0.6751904513000003 250 | 2016-04-11,-75782.1300000012,177.92000000000002,34103395.8,34517362.92,68544976.59,0.015194697407593605,0.6854497659000004 251 | 2016-04-12,-75782.1300000012,177.92000000000002,33980395.1,34400066.050000004,68304679.02000001,-0.003505691911419362,0.6830467902000005 252 | 2016-04-13,-75782.1300000012,177.92000000000002,34433650.04,34889163.28,69247031.19,0.01379630478497762,0.6924703119000003 253 | 2016-04-14,-75782.1300000012,177.92000000000002,34586213.14,35068009.72,69578440.72999999,0.004785902504479411,0.6957844073000001 254 | 2016-04-15,-75782.1300000012,177.92000000000002,34547993.18,35019771.24,69491982.28999999,-0.0012426038740290801,0.6949198229000001 255 | 2016-04-18,-75782.1300000012,177.92000000000002,34085975.1,34513949.82,68524142.78999999,-0.013927354899174849,0.6852414279000001 256 | 2016-04-19,-75782.1300000012,177.92000000000002,34189971.4,34618163.14,68732352.41,0.003038485583658934,0.6873235241000001 257 | 2016-04-20,-75782.1300000012,177.92000000000002,33585314.74,33819042.66,67328575.27,-0.020423819217276873,0.6732857527 258 | 2016-04-21,-75782.1300000012,177.92000000000002,33369614.8,33595029.53,66888862.2,-0.006530853626957933,0.6688886220000001 259 | 2016-04-22,-75782.1300000012,177.92000000000002,33520594.2,33667273.48,67112085.55,0.003337227494355499,0.6711208555000001 260 | 2016-04-25,-75782.1300000012,177.92000000000002,33384712.740000002,33524264.59,66833195.2,-0.004155590572315293,0.6683319520000002 261 | 2016-04-26,-75782.1300000012,177.92000000000002,33565571.28,33729391.9,67219181.05,0.0057753613132653925,0.6721918105000001 262 | 2016-04-27,-75782.1300000012,177.92000000000002,33425783.36,33603903.59,66953904.82,-0.003946436506012674,0.6695390482000001 263 | 2016-04-28,-75782.1300000012,177.92000000000002,33369403.64,33511977.430000003,66805598.94,-0.0022150445205355584,0.6680559894000001 264 | 2016-04-29,-75782.1300000012,177.92000000000002,33328966.5,33429266.64,66682451.01,-0.0018433773808480547,0.6668245101000001 265 | 2016-05-03,-75782.1300000012,177.92000000000002,33928555.32,34047265.28,67900038.47,0.01825948868942162,0.6790003847000001 266 | 2016-05-04,-75782.1300000012,177.92000000000002,33885478.68,34031678.79,67841375.34,-0.0008639631334805831,0.6784137534000002 267 | 2016-05-05,-75782.1300000012,177.92000000000002,33932567.36,34106425.68,67963210.91,0.001795888856754413,0.6796321091000002 268 | 2016-05-06,-75782.1300000012,177.92000000000002,33050235.3,33144045.25,66118498.42,-0.027142809547989866,0.6611849842000002 269 | 2016-05-09,-75782.1300000012,177.92000000000002,32366815.959999997,32220915.470000003,64511949.3,-0.02429802791035629,0.645119493 270 | 2016-05-10,-75782.1300000012,177.92000000000002,32403663.380000003,32226376.430000003,64554257.68000001,0.0006558223780104289,0.6455425768000002 271 | 2016-05-11,-75782.1300000012,177.92000000000002,32548307.98,32277004.08,64749529.92999999,0.0030249321581228283,0.6474952992999999 272 | 2016-05-12,-75782.1300000012,177.92000000000002,32625698.119999997,32263579.220000003,64813495.20999999,0.000987887944038368,0.6481349520999999 273 | 2016-05-13,-75782.1300000012,177.92000000000002,32465216.52,32164030.470000003,64553464.86,-0.004011978510917835,0.6455346486 274 | 2016-05-16,-75782.1300000012,177.92000000000002,32680282.98,32434234.220000003,65038735.07,0.00751733793147169,0.6503873507 275 | 2016-05-17,-75782.1300000012,177.92000000000002,32582199.16,32352547.36,64858964.39,-0.0027640556017350937,0.6485896439 276 | 2016-05-18,-75782.1300000012,177.92000000000002,32392366.32,31941041.270000003,64257625.46,-0.0092714852242185,0.6425762546 277 | 2016-05-19,-75782.1300000012,177.92000000000002,32333875.0,31934215.069999997,64192307.94,-0.001016494455442718,0.6419230793999999 278 | 2016-05-20,-75782.1300000012,177.92000000000002,32499846.759999998,32145485.96,64569550.589999996,0.005876757856293269,0.6456955058999998 279 | 2016-05-23,-75782.1300000012,177.92000000000002,32594868.759999998,32352206.05,64871292.67999999,0.004673132881410025,0.6487129267999998 280 | 2016-05-24,-75782.1300000012,177.92000000000002,32345066.48,32102139.59,64371423.94,-0.007705546156845822,0.6437142393999998 281 | 2016-05-25,-75782.1300000012,177.92000000000002,32299350.34,32027278.930000003,64250847.14,-0.001873141723762184,0.6425084713999999 282 | 2016-05-26,-75782.1300000012,177.92000000000002,32351929.18,32110899.88,64387046.92999999,0.0021198131396340525,0.6438704692999998 283 | 2016-05-27,-75782.1300000012,177.92000000000002,32333875.0,32095085.85,64353178.72,-0.0005260096807485626,0.6435317871999999 284 | 2016-05-30,-75782.1300000012,177.92000000000002,32378324.18,32111013.65,64413555.699999996,0.0009382128622223984,0.6441355569999999 285 | 2016-05-31,-75782.1300000012,177.92000000000002,33464214.48,33182385.74,66570818.089999996,0.03349081364250783,0.6657081809 286 | 2016-06-01,-75782.1300000012,177.92000000000002,33369086.900000002,33147003.270000003,66440308.04000001,-0.0019604693729848854,0.6644030804000001 287 | 2016-06-02,-75782.1300000012,177.92000000000002,33438241.8,33280341.71,66642801.379999995,0.0030477483620046097,0.6664280137999999 288 | 2016-06-03,-75782.1300000012,177.92000000000002,33672946.14,33433362.36,67030526.37,0.0058179575583741094,0.6703052636999999 289 | 2016-06-06,-75782.1300000012,177.92000000000002,33561664.82,33381255.7,66867138.39,-0.0024375159923124556,0.6686713838999999 290 | 2016-06-07,-75782.1300000012,177.92000000000002,33543293.900000002,33403327.08,66870838.849999994,5.534048695809979e-05,0.6687083884999999 291 | 2016-06-08,-75782.1300000012,177.92000000000002,33405406.419999998,33302299.319999997,66631923.60999999,-0.003572786645250847,0.6663192360999999 292 | 2016-06-13,-75782.1300000012,177.92000000000002,32374417.720000003,32231837.39,64530472.980000004,-0.031538195449674955,0.6453047298 293 | 2016-06-14,-75782.1300000012,177.92000000000002,32476196.84,32335595.63,64736010.339999996,0.0031851209282736104,0.6473601033999999 294 | 2016-06-15,-75782.1300000012,177.92000000000002,32902634.459999997,32847788.17,65674640.5,0.014499351366731306,0.656746405 295 | 2016-06-16,-75782.1300000012,177.92000000000002,32673525.86,32684073.14,65281816.87,-0.005981359425941579,0.6528181687000001 296 | 2016-06-17,-75782.1300000012,177.92000000000002,32839180.880000003,32823782.7,65587181.45,0.004677636049990719,0.6558718145000001 297 | 2016-06-20,-75782.1300000012,177.92000000000002,32863569.86,32865991.37,65653779.099999994,0.0010154064944956076,0.656537791 298 | 2016-06-21,-75782.1300000012,177.92000000000002,32796526.560000002,32749377.12,65470121.55,-0.0027973644856035262,0.6547012155 299 | 2016-06-22,-75782.1300000012,177.92000000000002,33088349.68,33056442.35,66069009.9,0.009147506310074993,0.6606900990000001 300 | 2016-06-23,-75782.1300000012,177.92000000000002,32912664.560000002,32901828.92,65738711.35,-0.004999296198019754,0.6573871135000001 301 | 2016-06-24,-75782.1300000012,177.92000000000002,32488655.279999997,32473257.33,64886130.47999999,-0.012969236124218742,0.6488613048 302 | 2016-06-27,-75782.1300000012,177.92000000000002,32946661.32,32944378.9,65815258.089999996,0.01431935612628954,0.6581525809000002 303 | 2016-06-28,-75782.1300000012,177.92000000000002,33114111.2,33136195.12,66174524.19,0.005458705328006408,0.6617452419000002 304 | 2016-06-29,-75782.1300000012,177.92000000000002,33272375.619999997,33352699.430000003,66549292.92,0.005663338491471048,0.6654929292000002 305 | 2016-06-30,-75782.1300000012,177.92000000000002,33299087.36,33330172.970000003,66553478.2,6.288992439085206e-05,0.6655347820000003 306 | 2016-07-01,-75782.1300000012,177.92000000000002,33302043.599999998,33362824.96,66589086.42999999,0.0005350318415062727,0.6658908643000002 307 | 2016-07-04,-75782.1300000012,177.92000000000002,33835222.6,34001302.199999996,67760742.66999999,0.01759531933557401,0.6776074267000001 308 | 2016-07-05,-75782.1300000012,177.92000000000002,33863518.04,34203699.03,67991434.94,0.003404512124719483,0.6799143494000002 309 | 2016-07-06,-75782.1300000012,177.92000000000002,33962974.4,34327708.33,68214900.6,0.003286673684666175,0.6821490060000001 310 | 2016-07-07,-75782.1300000012,177.92000000000002,33890652.1,34322702.449999996,68137572.41999999,-0.0011335966089497385,0.6813757242 311 | 2016-07-08,-75782.1300000012,177.92000000000002,33704092.24,33995499.93,67623810.03999999,-0.007540074613066161,0.6762381004000001 312 | 2016-07-11,-75782.1300000012,177.92000000000002,33820758.14,34073204.84,67818180.85,0.0028742954572513746,0.6781818085000001 313 | 2016-07-12,-75782.1300000012,177.92000000000002,34558234.44,34692796.26,69175248.57,0.02001038221596585,0.6917524857 314 | 2016-07-13,-75782.1300000012,177.92000000000002,34660541.46,34821470.13,69406229.46000001,0.0033390684496967804,0.6940622946000002 315 | 2016-07-14,-75782.1300000012,177.92000000000002,34596032.080000006,34745585.54,69265835.49000001,-0.002022786298755963,0.6926583549000003 316 | 2016-07-15,-75782.1300000012,177.92000000000002,34590964.24,34748771.1,69263953.21000001,-2.7174724547607276e-05,0.6926395321000003 317 | 2016-07-18,-75782.1300000012,177.92000000000002,34440407.16,34626582.12,68991207.14999999,-0.00393777783911764,0.6899120715000001 318 | 2016-07-19,-75782.1300000012,177.92000000000002,34294812.34,34547398.199999996,68766428.41,-0.0032580780839401857,0.6876642841000001 319 | 2016-07-20,-75782.1300000012,177.92000000000002,34182580.8,34448418.300000004,68555216.97,-0.003071432454521461,0.6855521697000001 320 | 2016-07-21,-75782.1300000012,177.92000000000002,34340106.16,34574816.77,68839140.8,0.00414153499250447,0.688391408 321 | 2016-07-22,-75782.1300000012,177.92000000000002,34051239.28,34276853.14,68252310.28999999,-0.008524663486212614,0.6825231028999998 322 | 2016-07-25,-75782.1300000012,177.92000000000002,34111736.62,34311097.91,68347052.39999999,0.0013881157956037171,0.6834705239999997 323 | 2016-07-26,-75782.1300000012,177.92000000000002,34520331.22,34701784.09,69146333.18,0.011694444045988073,0.6914633317999999 324 | 2016-07-27,-75782.1300000012,177.92000000000002,33978177.919999994,34039984.0,67942379.78999999,-0.01741167368724983,0.6794237978999997 325 | 2016-07-28,-75782.1300000012,177.92000000000002,34008796.12,34066378.64,67999392.63,0.0008391351638876721,0.6799939262999998 326 | 2016-07-29,-75782.1300000012,177.92000000000002,33827092.94,33895951.18,67647261.99,-0.005178438018057396,0.6764726198999997 327 | 2016-08-01,-75782.1300000012,177.92000000000002,33540759.98,33600718.03,67065695.879999995,-0.008597038415035452,0.6706569587999998 328 | 2016-08-02,-75782.1300000012,177.92000000000002,33669989.9,33804252.56,67398460.33,0.0049617683919274125,0.6739846032999998 329 | 2016-08-03,-75782.1300000012,177.92000000000002,33717078.580000006,33885939.42,67527235.87,0.0019106599671490088,0.6752723586999999 330 | 2016-08-04,-75782.1300000012,177.92000000000002,33799219.82,33931106.11,67654543.8,0.00188528270644861,0.6765454379999998 331 | 2016-08-05,-75782.1300000012,177.92000000000002,33839551.38,33865915.9,67629685.15,-0.00036743503989145054,0.6762968514999999 332 | 2016-08-08,-75782.1300000012,177.92000000000002,34146472.44,34179693.56,68250383.87,0.009177903440232171,0.6825038386999999 333 | 2016-08-09,-75782.1300000012,177.92000000000002,34387194.84,34423161.36,68734574.07,0.007094322002968445,0.6873457406999997 334 | 2016-08-10,-75782.1300000012,177.92000000000002,34243183.72,34344318.75,68511720.34,-0.0032422362837810637,0.6851172033999997 335 | 2016-08-11,-75782.1300000012,177.92000000000002,34137814.88,34161035.28,68223068.03,-0.004213181461033555,0.6822306802999997 336 | 2016-08-12,-75782.1300000012,177.92000000000002,34780480.34,34707472.59,69412170.80000001,0.017429629073220765,0.6941217079999997 337 | 2016-08-15,-75782.1300000012,177.92000000000002,35827728.36,35555400.4,71307346.63,0.027303220863969635,0.7130734662999996 338 | 2016-08-16,-75782.1300000012,177.92000000000002,35667563.5,35382925.08,70974706.44999999,-0.004664879507100594,0.7097470644999995 339 | 2016-08-17,-75782.1300000012,177.92000000000002,35612661.9,35377350.35,70914230.12,-0.0008520828478887355,0.7091423011999997 340 | 2016-08-18,-75782.1300000012,177.92000000000002,35522285.419999994,35315459.47,70761962.75999999,-0.002147204584218798,0.7076196275999995 341 | 2016-08-19,-75782.1300000012,177.92000000000002,35527881.16,35360853.699999996,70812952.72999999,0.0007205844497690794,0.7081295272999995 342 | 2016-08-22,-75782.1300000012,177.92000000000002,35229828.82,35095883.37,70249930.06,-0.00795084300674076,0.7024993005999997 343 | 2016-08-23,-75782.1300000012,177.92000000000002,35283041.14,35151630.67,70358889.68,0.0015510281634010248,0.7035888967999998 344 | 2016-08-24,-75782.1300000012,177.92000000000002,35156661.88,35108056.76,70188936.50999999,-0.0024155180784259933,0.7018893650999997 345 | 2016-08-25,-75782.1300000012,177.92000000000002,34936105.26,34908390.41,69768713.53999999,-0.005987025746431285,0.6976871353999996 346 | 2016-08-26,-75782.1300000012,177.92000000000002,34916256.22,34930916.87,69771390.96,3.837565384468e-05,0.6977139095999996 347 | 2016-08-29,-75782.1300000012,177.92000000000002,34923541.24,34927731.31,69775490.42,5.875560087886811e-05,0.6977549041999996 348 | 2016-08-30,-75782.1300000012,177.92000000000002,34967990.419999994,34980634.36,69872842.64999999,0.001395221006889269,0.6987284264999994 349 | 2016-08-31,-75782.1300000012,177.92000000000002,35134806.82,35103619.73,70162644.41999999,0.00414755946672507,0.7016264441999994 350 | 2016-09-01,-75782.1300000012,177.92000000000002,34858081.64,34851277.87,69633577.38,-0.007540580096054406,0.6963357737999994 351 | 2016-09-02,-75782.1300000012,177.92000000000002,34990373.38,34897240.949999996,69811832.19999999,0.002559897490649332,0.6981183219999995 352 | 2016-09-05,-75782.1300000012,177.92000000000002,35049181.44,34951281.699999996,69924681.00999999,0.0016164711116120056,0.6992468100999996 353 | 2016-09-06,-75782.1300000012,177.92000000000002,35291487.54,35163007.67,70378713.08,0.006493158973940538,0.7037871307999997 354 | 2016-09-07,-75782.1300000012,177.92000000000002,35272377.56,35176887.61,70373483.03999999,-7.431281094982811e-05,0.7037348303999996 355 | 2016-09-08,-75782.1300000012,177.92000000000002,35259074.48,35222623.15,70405915.5,0.0004608619411601289,0.7040591549999997 356 | 2016-09-09,-75782.1300000012,177.92000000000002,35031866.32,35028076.449999996,69984160.63999999,-0.0059903327299254405,0.6998416063999996 357 | 2016-09-12,-75782.1300000012,177.92000000000002,34446530.8,34381066.46,68751815.13,-0.017608920343264556,0.6875181512999997 358 | 2016-09-13,-75782.1300000012,177.92000000000002,34422564.14,34398473.27,68745255.28,-9.541348090358337e-05,0.6874525527999998 359 | 2016-09-14,-75782.1300000012,177.92000000000002,34194511.34,34163424.449999996,68282153.66,-0.006736488476387081,0.6828215365999998 360 | 2016-09-19,-75782.1300000012,177.92000000000002,34452020.96,34427370.85,68803609.68,0.007636783435339689,0.6880360967999999 361 | 2016-09-20,-75782.1300000012,177.92000000000002,34391629.2,34392671.0,68708518.07,-0.0013820729819594701,0.6870851806999998 362 | 2016-09-21,-75782.1300000012,177.92000000000002,34489185.12,34425322.99,68838725.97999999,0.0018950766754617376,0.6883872597999998 363 | 2016-09-22,-75782.1300000012,177.92000000000002,34747644.96,34612360.87,69284223.69999999,0.0064716148310099975,0.6928422369999998 364 | 2016-09-23,-75782.1300000012,177.92000000000002,34584523.86,34516680.300000004,69025422.03,-0.003735362196170322,0.6902542202999999 365 | 2016-09-26,-75782.1300000012,177.92000000000002,33999716.24,33908352.11,67832286.22,-0.01728545476304999,0.6783228621999999 366 | 2016-09-27,-75782.1300000012,177.92000000000002,34215838.5,34110180.09,68250236.46000001,0.006161523712240324,0.6825023645999999 367 | 2016-09-28,-75782.1300000012,177.92000000000002,34111736.62,33992883.22,68028837.71,-0.0032439264899802867,0.6802883770999998 368 | 2016-09-29,-75782.1300000012,177.92000000000002,34254269.62,34113706.96,68292194.44999999,0.003871251499586892,0.6829219444999997 369 | 2016-09-30,-75782.1300000012,177.92000000000002,34348130.24,34184471.9,68456820.00999999,0.0024106057994743857,0.6845682000999996 370 | 2016-10-10,-75782.1300000012,177.92000000000002,34776679.46,34678688.78,69379586.11,0.013479534980813002,0.6937958610999998 371 | 2016-10-11,-75782.1300000012,177.92000000000002,34910660.48,34873349.25,69708227.6,0.004736861495237887,0.6970822759999998 372 | 2016-10-12,-75782.1300000012,177.92000000000002,34841505.580000006,34796554.5,69562277.95,-0.002093722004201326,0.6956227794999998 373 | 2016-10-13,-75782.1300000012,177.92000000000002,34869378.7,34828978.949999996,69622575.52,0.0008668141955232578,0.6962257551999997 374 | 2016-10-14,-75782.1300000012,177.92000000000002,34903164.3,34856966.37,69684348.53999999,0.0008872555997623266,0.6968434853999997 375 | 2016-10-17,-75782.1300000012,177.92000000000002,34607857.04,34599391.09,69131466.0,-0.007934099286048824,0.6913146599999999 376 | 2016-10-18,-75782.1300000012,177.92000000000002,35066602.14,35085302.76,70076122.77,0.013664642523275816,0.7007612276999998 377 | 2016-10-19,-75782.1300000012,177.92000000000002,35012861.919999994,35094859.44,70031939.22999999,-0.0006305077714562346,0.7003193922999997 378 | 2016-10-20,-75782.1300000012,177.92000000000002,35037778.8,35091901.42,70053898.09,0.00031355493281282065,0.7005389808999999 379 | 2016-10-21,-75782.1300000012,177.92000000000002,35134278.919999994,35165624.38,70224121.16999999,0.0024298873387644804,0.7022412116999998 380 | 2016-10-24,-75782.1300000012,177.92000000000002,35554909.64,35590100.25,71069227.75999999,0.01203442030914359,0.7106922775999999 381 | 2016-10-25,-75782.1300000012,177.92000000000002,35553537.1,35632081.38,71109836.35,0.0005713948396504076,0.7110983634999999 382 | 2016-10-26,-75782.1300000012,177.92000000000002,35419978.4,35454258.87,70798455.13999999,-0.004378876762806794,0.7079845513999998 383 | 2016-10-27,-75782.1300000012,177.92000000000002,35323900.6,35409205.949999996,70657324.41999999,-0.001993415247845798,0.7065732441999998 384 | 2016-10-28,-75782.1300000012,177.92000000000002,35265092.54,35317279.79,70506590.19999999,-0.0021333134425527422,0.7050659019999999 385 | 2016-10-31,-75782.1300000012,177.92000000000002,35224444.24,35274274.73,70422936.84,-0.0011864615741974394,0.7042293683999999 386 | 2016-11-01,-75782.1300000012,177.92000000000002,35464849.9,35523999.88,70913067.65,0.006959817809268243,0.7091306765 387 | 2016-11-02,-75782.1300000012,177.92000000000002,35193509.3,35299759.21,70417486.38,-0.006988574693256977,0.7041748637999998 388 | 2016-11-03,-75782.1300000012,177.92000000000002,35528514.64,35597950.38,71050682.89,0.008992035111606178,0.7105068288999999 389 | 2016-11-04,-75782.1300000012,177.92000000000002,35413326.86,35556765.64,70894310.37,-0.0022008587903664667,0.7089431037 390 | 2016-11-07,-75782.1300000012,177.92000000000002,35438877.22,35647895.41,71010990.5,0.0016458320758188094,0.710109905 391 | 2016-11-08,-75782.1300000012,177.92000000000002,35592284.96,35813544.53,71330047.36,0.004493063084368698,0.7133004736000002 392 | 2016-11-09,-75782.1300000012,177.92000000000002,35401501.9,35591465.49,70917185.25999999,-0.00578805307553365,0.7091718526 393 | 2016-11-10,-75782.1300000012,177.92000000000002,35798060.38,36079652.56,71801930.81,0.01247575671194956,0.7180193081000001 394 | 2016-11-11,-75782.1300000012,177.92000000000002,36079008.76,36361347.08,72364573.71,0.00783604136619731,0.7236457371000001 395 | 2016-11-14,-75782.1300000012,177.92000000000002,36216579.5,36524379.49,72665176.86,0.004154009822605609,0.7266517686000002 396 | 2016-11-15,-75782.1300000012,177.92000000000002,36212567.46,36485925.23,72622710.56,-0.0005844106053964904,0.7262271056000003 397 | 2016-11-16,-75782.1300000012,177.92000000000002,36209611.22,36463967.62,72597796.71,-0.00034305866316330924,0.7259779671000002 398 | 2016-11-17,-75782.1300000012,177.92000000000002,36282883.74,36502535.65,72709637.25999999,0.0015405501966783142,0.7270963726000002 399 | 2016-11-18,-75782.1300000012,177.92000000000002,36081542.68,36325168.22,72330928.77,-0.005208504735703556,0.7233092877000001 400 | 2016-11-21,-75782.1300000012,177.92000000000002,36331239.38,36612892.550000004,72868349.80000001,0.007430030819995714,0.7286834980000003 401 | 2016-11-22,-75782.1300000012,177.92000000000002,36618944.88,36956477.949999996,73499640.69999999,0.00866344444100453,0.7349964070000001 402 | 2016-11-23,-75782.1300000012,177.92000000000002,36686199.34,36874449.78,73484866.99000001,-0.00020100383973686853,0.7348486699000003 403 | 2016-11-24,-75782.1300000012,177.92000000000002,36834116.919999994,36881275.98,73639610.76999998,0.0021057911150743625,0.7363961077 404 | 2016-11-25,-75782.1300000012,177.92000000000002,37177885.4,37111091.38,74213194.65,0.007789067242513159,0.7421319465000003 405 | 2016-11-28,-75782.1300000012,177.92000000000002,37323374.64,37282429.0,74530021.50999999,0.00426914461093042,0.7453002151 406 | 2016-11-29,-75782.1300000012,177.92000000000002,37629134.32,37349780.84,74903133.03,0.005006190960912926,0.7490313303000001 407 | 2016-11-30,-75782.1300000012,177.92000000000002,37354204.0,36975591.31,74254013.18,-0.008666124149172894,0.7425401318000002 408 | 2016-12-01,-75782.1300000012,177.92000000000002,37639692.32,37240447.87,74804358.06,0.0074116516593640824,0.7480435806000001 409 | 2016-12-02,-75782.1300000012,177.92000000000002,37258654.1,36905167.68,74088039.65,-0.009575891412976767,0.7408803965000001 410 | 2016-12-05,-75782.1300000012,177.92000000000002,36630030.78,36459985.67,73014234.32,-0.014493639392711533,0.7301423432 411 | 2016-12-06,-75782.1300000012,177.92000000000002,36521705.7,36402418.050000004,72848341.62,-0.002272059709246932,0.7284834162000002 412 | 2016-12-07,-75782.1300000012,177.92000000000002,36696968.5,36659424.48,73280610.85,0.005933823892036338,0.7328061085 413 | 2016-12-08,-75782.1300000012,177.92000000000002,36637738.12,36581264.49,73143220.47999999,-0.0018748529577794493,0.7314322047999999 414 | 2016-12-09,-75782.1300000012,177.92000000000002,36886484.6,36780475.76,73591178.22999999,0.006124391940364182,0.7359117822999999 415 | 2016-12-12,-75782.1300000012,177.92000000000002,35994122.44,35871339.69,71789680.0,-0.024479812299915027,0.7178968 416 | 2016-12-13,-75782.1300000012,177.92000000000002,35950412.32,35894890.08,71769520.27,-0.00028081654633371755,0.7176952027 417 | 2016-12-14,-75782.1300000012,177.92000000000002,35674954.1,35729809.81,71328981.78,-0.006138239301902382,0.7132898178 418 | 2016-12-15,-75782.1300000012,177.92000000000002,35268259.94,35469845.36,70662323.16999999,-0.009346251598770783,0.7066232316999999 419 | 2016-12-16,-75782.1300000012,177.92000000000002,35327384.74,35530143.46,70781746.07,0.0016900505763544071,0.7078174606999998 420 | 2016-12-19,-75782.1300000012,177.92000000000002,35147370.84,35474396.16,70545984.87,-0.0033308192166781048,0.7054598487 421 | 2016-12-20,-75782.1300000012,177.92000000000002,34937055.48,35301465.76,70162739.10999998,-0.005432566583431386,0.7016273910999998 422 | 2016-12-21,-75782.1300000012,177.92000000000002,35248305.32,35694541.11,70867064.3,0.010038450592639858,0.7086706429999999 423 | 2016-12-22,-75782.1300000012,177.92000000000002,35218003.86,35718774.12,70860995.85,-8.56314574328998e-05,0.7086099585 424 | 2016-12-23,-75782.1300000012,177.92000000000002,34921640.8,35384176.550000004,70230035.22,-0.008904202127438698,0.7023003522 425 | 2016-12-26,-75782.1300000012,177.92000000000002,35077899.2,35525478.89,70527595.96000001,0.0042369441944303254,0.7052759596000001 426 | 2016-12-27,-75782.1300000012,177.92000000000002,35014445.62,35435486.82,70374150.31,-0.0021756824107124206,0.7037415031 427 | 2016-12-28,-75782.1300000012,177.92000000000002,34861354.62,35294184.48,70079756.97,-0.004183259601759914,0.7007975697000001 428 | 2016-12-29,-75782.1300000012,177.92000000000002,34817750.080000006,35224329.699999996,69966297.65,-0.0016190027606483026,0.6996629765000002 429 | 2016-12-30,-75782.1300000012,177.92000000000002,34947824.64,35310112.28,70182154.78999999,0.00308515881574567,0.7018215479000001 430 | 2017-01-03,-75782.1300000012,177.92000000000002,35287264.34,35677361.84,70888844.05000001,0.010069358259440442,0.7088884405000002 431 | 2017-01-04,-75782.1300000012,177.92000000000002,35562616.98,35937553.83,71424388.67999999,0.007554709590443354,0.7142438868 432 | 2017-01-05,-75782.1300000012,177.92000000000002,35557126.82,36012869.57,71494214.25999999,0.0009776153676699373,0.7149421425999999 433 | 2017-01-06,-75782.1300000012,177.92000000000002,35344699.86,35886698.64,71155616.37,-0.004736018061106573,0.7115561637000001 434 | 2017-01-09,-75782.1300000012,177.92000000000002,35516056.2,36079197.48,71519471.55,0.0051135131499386866,0.7151947154999999 435 | 2017-01-10,-75782.1300000012,177.92000000000002,35456614.66,35970319.59,71351152.12,-0.0023534769811927037,0.7135115211999999 436 | 2017-01-11,-75782.1300000012,177.92000000000002,35205651.0,35686804.75,70816673.62,-0.007490818075384431,0.7081667361999999 437 | 2017-01-12,-75782.1300000012,177.92000000000002,35027431.96,35488162.33,70439812.16,-0.005321648712593219,0.7043981215999998 438 | 2017-01-13,-75782.1300000012,177.92000000000002,35051609.78,35413870.52,70389698.17,-0.00071144411751356,0.7038969816999999 439 | 2017-01-16,-75782.1300000012,177.92000000000002,35046753.1,35307723.11,70278694.08,-0.0015769934079261638,0.7027869407999999 440 | 2017-01-17,-75782.1300000012,177.92000000000002,35119708.88,35368476.29,70412403.03999999,0.0019025532809102685,0.7041240303999998 441 | 2017-01-18,-75782.1300000012,177.92000000000002,35257068.46,35416714.77,70598001.1,0.0026358716928687187,0.7059800109999999 442 | 2017-01-19,-75782.1300000012,177.92000000000002,35150643.82,35283490.1,70358351.78999999,-0.0033945622576557755,0.7035835178999998 443 | 2017-01-20,-75782.1300000012,177.92000000000002,35420928.62,35531963.78,70877110.27,0.00737309028426858,0.7087711026999999 444 | 2017-01-23,-75782.1300000012,177.92000000000002,35517956.64,35687032.29,71129206.8,0.0035568116284603324,0.7112920679999999 445 | 2017-01-24,-75782.1300000012,177.92000000000002,35521863.1,35752791.35,71198872.32,0.000979422140835684,0.7119887231999998 446 | 2017-01-25,-75782.1300000012,177.92000000000002,35642752.2,35832430.35,71399400.42,0.0028164505063892342,0.7139940041999999 447 | 2017-01-26,-75782.1300000012,177.92000000000002,35770081.68,35941877.09,71636176.64,0.003316221405322617,0.7163617663999999 448 | 2017-02-03,-75782.1300000012,177.92000000000002,35522285.419999994,35725714.09,71172217.38,-0.006476605561064219,0.7117221737999999 449 | 2017-02-06,-75782.1300000012,177.92000000000002,35614351.18,35916961.46,71455530.50999999,0.00398067027316773,0.7145553050999999 450 | 2017-02-07,-75782.1300000012,177.92000000000002,35534849.44,35872704.93,71331772.24,-0.0017319620905015265,0.7133177223999999 451 | 2017-02-08,-75782.1300000012,177.92000000000002,35720775.82,36030731.46,71675725.15,0.0048218752906175055,0.7167572515 452 | 2017-02-09,-75782.1300000012,177.92000000000002,35858029.82,36215038.86,71997286.55,0.004486336194395424,0.7199728654999998 453 | 2017-02-10,-75782.1300000012,177.92000000000002,36039627.419999994,36368855.9,72332701.19,0.004658712238648999,0.7233270118999999 454 | 2017-02-13,-75782.1300000012,177.92000000000002,36280138.66,36597988.68,72802345.21,0.006492831212902672,0.7280234520999999 455 | 2017-02-14,-75782.1300000012,177.92000000000002,36275176.4,36610389.61,72809783.88,0.00010217624141839465,0.7280978387999999 456 | 2017-02-15,-75782.1300000012,177.92000000000002,36126414.18,36554187.23,72604819.28,-0.002815069473874554,0.7260481928 457 | 2017-02-16,-75782.1300000012,177.92000000000002,36329338.94,36743386.74,72996943.55,0.0054008022317053594,0.7299694354999999 458 | 2017-02-17,-75782.1300000012,177.92000000000002,36123563.52,36430064.16,72477845.55,-0.00711122924817309,0.7247784555 459 | 2017-02-20,-75782.1300000012,177.92000000000002,36650935.62,36861024.92,73436178.41,0.013222424766184293,0.7343617841 460 | 2017-02-21,-75782.1300000012,177.92000000000002,36771613.56,37013135.41,73708966.84,0.0037146327042920646,0.7370896684000001 461 | 2017-02-22,-75782.1300000012,177.92000000000002,36844886.080000006,37102899.94,73872003.89,0.0022119025267834935,0.7387200389 462 | 2017-02-23,-75782.1300000012,177.92000000000002,36671312.56,36990950.26,73586480.69,-0.0038651070089443795,0.7358648069 463 | 2017-02-24,-75782.1300000012,177.92000000000002,36676908.3,37014273.11,73615399.28,0.0003929878114681262,0.7361539928 464 | 2017-02-27,-75782.1300000012,177.92000000000002,36385190.76,36732464.82,73041873.44999999,-0.007790840443839486,0.7304187344999998 465 | 2017-02-28,-75782.1300000012,177.92000000000002,36454767.98,36881162.21,73260148.06,0.0029883490070861107,0.7326014806 466 | 2017-03-01,-75782.1300000012,177.92000000000002,36514209.52,36940322.61,73378750.0,0.0016189148280572052,0.7337874999999999 467 | 2017-03-02,-75782.1300000012,177.92000000000002,36267785.8,36748051.31,72940054.97999999,-0.005978502223055182,0.7294005497999998 468 | 2017-03-03,-75782.1300000012,177.92000000000002,36191345.88,36614712.87,72730276.62,-0.0028760378650318774,0.7273027661999999 469 | 2017-03-06,-75782.1300000012,177.92000000000002,36387935.84,36791738.99,73103892.7,0.005137008923423503,0.7310389269999998 470 | 2017-03-07,-75782.1300000012,177.92000000000002,36466909.68,36888898.57,73280026.12,0.0024093576073001,0.7328002611999997 471 | 2017-03-08,-75782.1300000012,177.92000000000002,36411691.34,36868988.82,73204898.03,-0.001025219203347083,0.7320489802999998 472 | 2017-03-09,-75782.1300000012,177.92000000000002,36181632.52,36596964.75,72702815.14,-0.006858596945169437,0.7270281513999998 473 | 2017-03-10,-75782.1300000012,177.92000000000002,36191662.62,36551570.52,72667451.00999999,-0.0004864203666929967,0.7266745100999996 474 | 2017-03-13,-75782.1300000012,177.92000000000002,36510619.8,36827576.54,73262414.21,0.00818747859916158,0.7326241420999996 475 | 2017-03-14,-75782.1300000012,177.92000000000002,36495733.02,36853857.41,73273808.3,0.00015552435887999927,0.7327380829999998 476 | 2017-03-15,-75782.1300000012,177.92000000000002,36569111.12,36881503.52,73374832.50999999,0.0013787219791603356,0.7337483250999997 477 | 2017-03-16,-75782.1300000012,177.92000000000002,36757782.580000006,37190730.38,73872730.83000001,0.006785682542200799,0.7387273082999998 478 | 2017-03-17,-75782.1300000012,177.92000000000002,36380861.98,36832468.65,73137548.5,-0.009952012356113538,0.7313754849999997 479 | 2017-03-20,-75782.1300000012,177.92000000000002,36420982.38,36984465.37,73329665.62,0.0026267919001961015,0.7332966561999997 480 | 2017-03-21,-75782.1300000012,177.92000000000002,36597723.3,37107336.97,73629278.13999999,0.004085829622524129,0.7362927813999995 481 | 2017-03-22,-75782.1300000012,177.92000000000002,36425627.9,36920867.94,73270713.71,-0.0048698620855444075,0.7327071370999997 482 | 2017-03-23,-75782.1300000012,177.92000000000002,36551584.84,36958753.35,73434556.06,0.0022361232981635837,0.7343455605999998 483 | 2017-03-24,-75782.1300000012,177.92000000000002,36843196.8,37196532.65,73963947.32,0.007209021044090491,0.7396394731999996 484 | 2017-03-27,-75782.1300000012,177.92000000000002,36721146.32,37168203.92,73813568.11,-0.00203314202998639,0.7381356810999996 485 | 2017-03-28,-75782.1300000012,177.92000000000002,36634253.98,37008812.15,73567284.0,-0.0033365696349074714,0.7356728399999996 486 | 2017-03-29,-75782.1300000012,177.92000000000002,36585476.02,36876383.87,73386077.75999999,-0.0024631361951599207,0.7338607775999995 487 | 2017-03-30,-75782.1300000012,177.92000000000002,36285312.080000006,36522900.48,72732430.43,-0.00890696641585964,0.7273243042999996 488 | 2017-03-31,-75782.1300000012,177.92000000000002,36488975.9,36662496.27,73075690.03999999,0.004719484939120111,0.7307569003999995 489 | 2017-04-05,-75782.1300000012,177.92000000000002,36994070.62,37206316.87,74124605.35999998,0.014353820257131167,0.7412460535999994 490 | 2017-04-06,-75782.1300000012,177.92000000000002,37101339.9,37327937.0,74353494.77,0.003087900554591405,0.7435349476999995 491 | 2017-04-07,-75782.1300000012,177.92000000000002,37137342.68,37391875.74,74453436.28999999,0.0013441401821010501,0.7445343628999995 492 | 2017-04-10,-75782.1300000012,177.92000000000002,37007268.12,37195850.03,74127336.02,-0.004379922354823429,0.7412733601999996 493 | 2017-04-11,-75782.1300000012,177.92000000000002,37135970.14,37418611.69,74478799.69999999,0.004741350477038164,0.7447879969999995 494 | 2017-04-12,-75782.1300000012,177.92000000000002,37052667.52,37246363.91,74223249.3,-0.003431183115589209,0.7422324929999996 495 | 2017-04-13,-75782.1300000012,177.92000000000002,37106830.06,37270596.92,74301644.85,0.0010562128543192273,0.7430164484999996 496 | 2017-04-14,-75782.1300000012,177.92000000000002,36810467.0,36930538.39,73665223.25999999,-0.008565376867292862,0.7366522325999996 497 | 2017-04-17,-75782.1300000012,177.92000000000002,36741206.52,36658628.09,73324052.48,-0.004631368302459804,0.7332405247999997 498 | 2017-04-18,-75782.1300000012,177.92000000000002,36559608.919999994,36368969.67,72852796.46,-0.006427031840998576,0.7285279645999996 499 | 2017-04-19,-75782.1300000012,177.92000000000002,36381601.04,36072940.13,72378759.03999999,-0.006506784132305432,0.7237875903999995 500 | 2017-04-20,-75782.1300000012,177.92000000000002,36547044.9,36088981.699999996,72560244.47,0.0025074404757299273,0.7256024446999995 501 | 2017-04-21,-75782.1300000012,177.92000000000002,36602368.82,36100927.550000004,72627514.24000001,0.0009270885247336658,0.7262751423999996 502 | 2017-04-24,-75782.1300000012,177.92000000000002,36227243.080000006,35604662.81,71756123.76,-0.011998076612128927,0.7175612375999996 503 | 2017-04-25,-75782.1300000012,177.92000000000002,36329761.26,35662002.89,71915982.02,0.0022277995469022205,0.7191598201999995 504 | 2017-04-26,-75782.1300000012,177.92000000000002,36374210.44,35733450.449999996,72031878.75999999,0.0016115574972996871,0.7203187875999995 505 | 2017-04-27,-75782.1300000012,177.92000000000002,36390469.76,35862465.63,72177153.25999999,0.0020168084256699803,0.7217715325999995 506 | 2017-04-28,-75782.1300000012,177.92000000000002,36316880.5,35890566.82,72131665.19,-0.0006302280977490415,0.7213166518999996 507 | 2017-05-02,-75782.1300000012,177.92000000000002,36177831.64,35765988.67,71868038.18,-0.003654802773588761,0.7186803817999997 508 | 2017-05-03,-75782.1300000012,177.92000000000002,36035826.54,35670876.949999996,71630921.35999998,-0.003299336200135894,0.7163092135999994 509 | 2017-05-04,-75782.1300000012,177.92000000000002,35943549.62,35580088.49,71447855.97999999,-0.0025556753497550933,0.7144785597999994 510 | 2017-05-05,-75782.1300000012,177.92000000000002,35712962.9,35303286.08,70940466.85,-0.007101530522371835,0.7094046684999995 511 | 2017-05-08,-75782.1300000012,177.92000000000002,35462315.98,35025345.97,70411879.82,-0.007451135486853722,0.7041187981999995 512 | 2017-05-09,-75782.1300000012,177.92000000000002,35396011.74,35047189.81,70367419.42,-0.0006314332199857109,0.7036741941999995 513 | 2017-05-10,-75782.1300000012,177.92000000000002,35239436.6,34731478.06,69895132.53,-0.00671172673224063,0.6989513252999995 514 | 2017-05-11,-75782.1300000012,177.92000000000002,35439510.7,34830685.5,70194414.07,0.004281865262527829,0.7019441406999993 515 | 2017-05-12,-75782.1300000012,177.92000000000002,35742842.04,35081093.27,70748153.18,0.007888649222825839,0.7074815317999995 516 | 2017-05-15,-75782.1300000012,177.92000000000002,35888648.02,35157546.71,70970412.6,0.00314155790660009,0.7097041259999993 517 | 2017-05-16,-75782.1300000012,177.92000000000002,36199686.7,35416145.92,71540050.49000001,0.008026413671998522,0.7154005048999995 518 | 2017-05-17,-75782.1300000012,177.92000000000002,36002463.26,35319213.88,71245895.00999999,-0.00411175946879061,0.7124589500999994 519 | 2017-05-18,-75782.1300000012,177.92000000000002,35877245.38,35156522.78,70957986.03,-0.004041060610714187,0.7095798602999995 520 | 2017-05-19,-75782.1300000012,177.92000000000002,35937848.3,35162097.51,71024163.67999999,0.0009326314584521267,0.7102416367999994 521 | 2017-05-22,-75782.1300000012,177.92000000000002,36015871.919999994,34992011.36,70932101.14999999,-0.001296214206967461,0.7093210114999994 522 | 2017-05-23,-75782.1300000012,177.92000000000002,36152598.02,34835805.15,70912621.03999999,-0.0002746303815081008,0.7091262103999995 523 | 2017-05-24,-75782.1300000012,177.92000000000002,36152386.86,34860038.16,70936642.88999999,0.00033875281505180155,0.7093664288999995 524 | 2017-05-25,-75782.1300000012,177.92000000000002,36801598.28,35357781.91,72083598.06,0.016168726391218913,0.7208359805999995 525 | 2017-05-26,-75782.1300000012,177.92000000000002,36746379.94,35383152.62,72053750.42999999,-0.00041406964695578363,0.7205375042999995 526 | 2017-05-31,-75782.1300000012,177.92000000000002,36877827.04,35464156.86,72266201.77,0.002948511891915917,0.7226620176999995 527 | 2017-06-01,-75782.1300000012,177.92000000000002,36929138.919999994,35298507.74,72151864.53,-0.0015821675582714523,0.7215186452999995 528 | 2017-06-02,-75782.1300000012,177.92000000000002,36810572.580000006,35331728.58,72066519.03,-0.0011828592449543152,0.7206651902999995 529 | 2017-06-05,-75782.1300000012,177.92000000000002,36623062.5,35173815.82,71721096.19,-0.004793111206831124,0.7172109618999996 530 | 2017-06-06,-75782.1300000012,177.92000000000002,36877827.04,35292933.01,72094977.91999999,0.005212995197529047,0.7209497791999995 531 | 2017-06-07,-75782.1300000012,177.92000000000002,37310599.46,35727420.64,72962237.97,0.012029410023016718,0.7296223796999997 532 | 2017-06-08,-75782.1300000012,177.92000000000002,37596826.84,35841304.41,73362349.12,0.005483811367799962,0.7336234911999998 533 | 2017-06-09,-75782.1300000012,177.92000000000002,37757202.86,35933116.800000004,73614537.53,0.0034375727198632244,0.7361453752999998 534 | 2017-06-12,-75782.1300000012,177.92000000000002,37738409.62,35722414.76,73385042.25,-0.003117526614990651,0.7338504224999998 535 | 2017-06-13,-75782.1300000012,177.92000000000002,37821606.66,35880099.98,73625924.50999999,0.0032824435690774756,0.7362592450999996 536 | 2017-06-14,-75782.1300000012,177.92000000000002,37325697.4,35617632.59,72867547.86,-0.010300402406451137,0.7286754785999997 537 | 2017-06-15,-75782.1300000012,177.92000000000002,37256964.82,35638338.73,72819521.41999999,-0.0006590923039194729,0.7281952141999996 538 | 2017-06-16,-75782.1300000012,177.92000000000002,37151068.080000006,35532305.09,72607591.04,-0.002910351178740056,0.7260759103999997 539 | 2017-06-19,-75782.1300000012,177.92000000000002,37519647.86,35773497.49,73217363.22,0.00839818772756229,0.7321736321999996 540 | 2017-06-20,-75782.1300000012,177.92000000000002,37443841.419999994,35723893.77,73091953.06,-0.0017128472603304967,0.7309195305999997 541 | 2017-06-21,-75782.1300000012,177.92000000000002,37881681.68,35908201.17,73714100.72,0.008511848896543883,0.7371410071999996 542 | 2017-06-22,-75782.1300000012,177.92000000000002,37906809.72,35808538.65,73639566.24,-0.0010111292042090936,0.7363956623999997 543 | 2017-06-23,-75782.1300000012,177.92000000000002,38250367.04,35927086.99,74101671.9,0.006275236039467558,0.7410167189999998 544 | 2017-06-26,-75782.1300000012,177.92000000000002,38727694.22,36240750.88,74892662.97,0.0106744024759311,0.7489266296999997 545 | 2017-06-27,-75782.1300000012,177.92000000000002,38797693.76,36306282.4,75028194.03,0.001809670729084445,0.7502819402999996 546 | 2017-06-28,-75782.1300000012,177.92000000000002,38496262.86,36101496.4,74521977.13,-0.006747022323336127,0.7452197712999996 547 | 2017-06-29,-75782.1300000012,177.92000000000002,38735507.14,36270558.62,74930283.63,0.005479007880960118,0.7493028362999996 548 | 2017-06-30,-75782.1300000012,177.92000000000002,38714074.4,36320276.11,74958568.38,0.0003774808879632996,0.7495856837999996 549 | 2017-07-03,-75782.1300000012,177.92000000000002,38545674.3,36359868.07,74829760.24,-0.0017183911430513898,0.7482976023999995 550 | 2017-07-04,-75782.1300000012,177.92000000000002,38219748.84,36210715.6,74354682.31,-0.006348783271205027,0.7435468230999996 551 | 2017-07-05,-75782.1300000012,177.92000000000002,38638901.44,36487518.01,75050637.32,0.009359935223694604,0.7505063731999996 552 | 2017-07-06,-75782.1300000012,177.92000000000002,38643335.8,36547929.88,75115483.55,0.0008640330357689852,0.7511548354999995 553 | 2017-07-07,-75782.1300000012,177.92000000000002,38599308.94,36610730.92,75134257.72999999,0.00024993755099100845,0.7513425772999994 554 | 2017-07-10,-75782.1300000012,177.92000000000002,38575659.02,36550091.51,75049968.4,-0.0011218495070901557,0.7504996839999996 555 | 2017-07-11,-75782.1300000012,177.92000000000002,38756411.98,36440986.08,75121615.92999999,0.0009546643593254522,0.7512161592999994 556 | 2017-07-12,-75782.1300000012,177.92000000000002,38629821.56,36378412.58,74932452.00999999,-0.0025181023818267034,0.7493245200999994 557 | 2017-07-13,-75782.1300000012,177.92000000000002,38926501.36,36613006.32,75463725.55,0.007090032766165377,0.7546372554999995 558 | 2017-07-14,-75782.1300000012,177.92000000000002,39097224.22,36661472.34,75682914.43,0.0029045594873895464,0.7568291442999996 559 | 2017-07-17,-75782.1300000012,177.92000000000002,38679866.48,36138585.42,74742669.77,-0.012423473211640834,0.7474266976999995 560 | 2017-07-18,-75782.1300000012,177.92000000000002,38718086.44,36264983.89,74907288.19999999,0.0022024692254980494,0.7490728819999993 561 | 2017-07-19,-75782.1300000012,177.92000000000002,39378700.5,36758859.46,76061777.83,0.015412247028854686,0.7606177782999994 562 | 2017-07-20,-75782.1300000012,177.92000000000002,39570117.04,36916772.22,76411107.13,0.004592704903384703,0.7641110712999994 563 | 2017-07-21,-75782.1300000012,177.92000000000002,39366558.8,36838498.46,76129275.13,-0.003688364304426539,0.7612927512999994 564 | 2017-07-24,-75782.1300000012,177.92000000000002,39523556.26,36982076.199999996,76429850.32999998,0.003948220963442939,0.7642985032999993 565 | 2017-07-25,-75782.1300000012,177.92000000000002,39271114.48,36903461.13,76098793.47999999,-0.004331512472817822,0.7609879347999994 566 | 2017-07-26,-75782.1300000012,177.92000000000002,39121507.62,36948741.59,75994467.08,-0.0013709336932840044,0.7599446707999995 567 | 2017-07-27,-75782.1300000012,177.92000000000002,39193302.02,36972747.06,76090266.95,0.0012606163801260895,0.7609026694999995 568 | 2017-07-28,-75782.1300000012,177.92000000000002,39295714.62,37012111.48,76232043.97,0.0018632740517674495,0.7623204396999994 569 | 2017-07-31,-75782.1300000012,177.92000000000002,39464431.46,37237262.31,76625911.64,0.00516669433860395,0.7662591163999994 570 | 2017-08-01,-75782.1300000012,177.92000000000002,39807672.04,37460365.28,77192255.19,0.007391018754344669,0.7719225518999994 571 | 2017-08-02,-75782.1300000012,177.92000000000002,39707054.3,37374127.62,77005399.78999999,-0.0024206495786407434,0.7700539978999994 572 | 2017-08-03,-75782.1300000012,177.92000000000002,39358429.14,37236124.61,76518771.62,-0.0063194032019451285,0.7651877161999995 573 | 2017-08-04,-75782.1300000012,177.92000000000002,39144629.64,37112684.16,76181531.66999999,-0.0044072838972740724,0.7618153166999992 574 | 2017-08-07,-75782.1300000012,177.92000000000002,39347448.82,37310416.42,76582083.11,0.005257854905505344,0.7658208310999994 575 | 2017-08-08,-75782.1300000012,177.92000000000002,39404673.18,37337834.99,76666726.03999999,0.0011052576080805565,0.7666672603999993 576 | 2017-08-09,-75782.1300000012,177.92000000000002,39392320.32,37266159.89,76582698.08,-0.0010960160207722502,0.7658269807999993 577 | 2017-08-10,-75782.1300000012,177.92000000000002,39232683.36,37108929.75,76265830.97999999,-0.004137580784487449,0.7626583097999993 578 | 2017-08-11,-75782.1300000012,177.92000000000002,38508721.3,36503559.58,74936498.75,-0.01743024645399316,0.7493649874999995 579 | 2017-08-14,-75782.1300000012,177.92000000000002,39008431.44,36831444.72,75764094.03,0.011043954465513428,0.7576409402999995 580 | 2017-08-15,-75782.1300000012,177.92000000000002,39128581.48,36989585.02,76042384.37,0.003673116448667857,0.7604238436999996 581 | 2017-08-16,-75782.1300000012,177.92000000000002,39079592.36,36934861.65,75938671.88,-0.0013638774067811221,0.7593867187999995 582 | 2017-08-17,-75782.1300000012,177.92000000000002,39289274.24,37184928.11,76398420.22,0.006054205698073245,0.7639842021999996 583 | 2017-08-18,-75782.1300000012,177.92000000000002,39325065.86,37188227.44,76437511.16999999,0.0005116722294442599,0.7643751116999995 584 | 2017-08-21,-75782.1300000012,177.92000000000002,39497372.419999994,37395175.07,76816765.35999998,0.0049616240010290635,0.7681676535999995 585 | 2017-08-22,-75782.1300000012,177.92000000000002,39616783.4,37432946.71,76973947.97999999,0.0020462020141485127,0.7697394797999996 586 | 2017-08-23,-75782.1300000012,177.92000000000002,39656798.22,37404162.9,76985178.99,0.00014590663847613428,0.7698517898999996 587 | 2017-08-24,-75782.1300000012,177.92000000000002,39430434.7,37219969.27,76574621.84,-0.005332937526238868,0.7657462183999997 588 | 2017-08-25,-75782.1300000012,177.92000000000002,40075528.5,37902703.04,77902449.41,0.017340308552544315,0.7790244940999996 589 | 2017-08-28,-75782.1300000012,177.92000000000002,40571332.18,38256869.050000004,78752419.1,0.010910692750193407,0.7875241909999996 590 | 2017-08-29,-75782.1300000012,177.92000000000002,40485073.32,38286221.71,78695512.9,-0.000722596215460114,0.7869551289999998 591 | 2017-08-30,-75782.1300000012,177.92000000000002,40482539.4,38268018.51,78674775.78,-0.00026351083099684924,0.7867477577999997 592 | 2017-08-31,-75782.1300000012,177.92000000000002,40353626.22,38235935.37,78513779.46,-0.0020463524478315787,0.7851377945999997 593 | 2017-09-01,-75782.1300000012,177.92000000000002,40442841.32,38307724.24,78674783.43,0.0020506460280904637,0.7867478342999998 594 | 2017-09-04,-75782.1300000012,177.92000000000002,40602055.96,38449481.66,78975755.49,0.003825521302740942,0.7897575548999998 595 | 2017-09-05,-75782.1300000012,177.92000000000002,40722733.9,38503408.64,79150360.41,0.002210867359440538,0.7915036040999998 596 | 2017-09-06,-75782.1300000012,177.92000000000002,40642493.1,38515582.03,79082293.0,-0.0008599759956544606,0.7908229299999998 597 | 2017-09-07,-75782.1300000012,177.92000000000002,40435767.46,38289293.5,78649278.83,-0.005475488299258147,0.7864927882999998 598 | 2017-09-08,-75782.1300000012,177.92000000000002,40394802.419999994,38286335.48,78605355.76999998,-0.0005584674221229546,0.7860535576999996 599 | 2017-09-11,-75782.1300000012,177.92000000000002,40391212.7,38413530.34,78728960.91,0.001572477330446631,0.7872896090999998 600 | 2017-09-12,-75782.1300000012,177.92000000000002,40520864.94,38448457.73,78893540.53999999,0.0020904585567709244,0.7889354053999997 601 | 2017-09-13,-75782.1300000012,177.92000000000002,40570276.38,38501474.550000004,78995968.80000001,0.001298309840056966,0.7899596879999999 602 | 2017-09-14,-75782.1300000012,177.92000000000002,40436717.68,38356759.11,78717694.66,-0.0035226372209516965,0.7871769465999997 603 | 2017-09-15,-75782.1300000012,177.92000000000002,40450865.4,38154134.74,78529218.00999999,-0.002394336506094108,0.7852921800999997 604 | 2017-09-18,-75782.1300000012,177.92000000000002,40575872.12,38259258.22,78759348.21,0.00293050415923779,0.7875934820999997 605 | 2017-09-19,-75782.1300000012,177.92000000000002,40459522.96,38190768.68,78574509.50999999,-0.002346879503207111,0.7857450950999997 606 | 2017-09-20,-75782.1300000012,177.92000000000002,40568481.52,38294982.0,78787681.39,0.002712990272919047,0.7878768138999999 607 | 2017-09-21,-75782.1300000012,177.92000000000002,40519703.56,38201804.37,78645725.8,-0.0018017485410862788,0.7864572579999999 608 | 2017-09-22,-75782.1300000012,177.92000000000002,40518753.34,38141733.81,78584705.02000001,-0.0007758944224783848,0.7858470502 609 | 2017-09-25,-75782.1300000012,177.92000000000002,40308226.82,38016814.35,78249259.03999999,-0.004268591196144977,0.7824925903999997 610 | 2017-09-26,-75782.1300000012,177.92000000000002,40339795.24,38039909.66,78303922.77,0.0006985846341631685,0.7830392276999997 611 | 2017-09-27,-75782.1300000012,177.92000000000002,40344229.6,38059136.79,78327584.25999999,0.00030217502729068535,0.7832758425999996 612 | 2017-09-28,-75782.1300000012,177.92000000000002,40358377.32,37995084.28,78277679.47,-0.0006371291859881278,0.7827767946999997 613 | 2017-09-29,-75782.1300000012,177.92000000000002,40505767.0,38100890.38,78530875.25,0.0032345846442347614,0.7853087524999997 614 | 2017-10-09,-75782.1300000012,177.92000000000002,40988373.18,38390321.26,79302912.31,0.009831000323659245,0.7930291230999996 615 | 2017-10-10,-75782.1300000012,177.92000000000002,41069141.88,38488277.23,79481636.97999999,0.0022536961732420036,0.7948163697999996 616 | 2017-10-11,-75782.1300000012,177.92000000000002,41204601.02,38548461.56,79677280.45,0.0024614927099355643,0.7967728044999998 617 | 2017-10-12,-75782.1300000012,177.92000000000002,41312926.1,38523659.699999996,79760803.66999999,0.0010482689610922247,0.7976080366999995 618 | 2017-10-13,-75782.1300000012,177.92000000000002,41397918.0,38573946.04,79896081.91,0.0016960491090298735,0.7989608190999996 619 | 2017-10-16,-75782.1300000012,177.92000000000002,41318205.1,38436853.19,79679276.16,-0.0027135967724202237,0.7967927615999997 620 | 2017-10-17,-75782.1300000012,177.92000000000002,41314193.06,38363699.08,79602110.00999999,-0.0009684594755234865,0.7960211000999996 621 | 2017-10-18,-75782.1300000012,177.92000000000002,41642441.28,38474624.83,80041283.97999999,0.00551711468382976,0.8004128397999997 622 | 2017-10-19,-75782.1300000012,177.92000000000002,41506137.5,38342424.09,79772779.46000001,-0.0033545753722176164,0.7977277945999999 623 | 2017-10-20,-75782.1300000012,177.92000000000002,41459682.3,38438901.050000004,79822801.22,0.0006270529914915723,0.7982280121999997 624 | 2017-10-23,-75782.1300000012,177.92000000000002,41501386.4,38462223.9,79887828.16999999,0.0008146412930407632,0.7988782816999996 625 | 2017-10-24,-75782.1300000012,177.92000000000002,41803345.2,38548120.25,80275683.32,0.0048549967984441444,0.8027568331999997 626 | 2017-10-25,-75782.1300000012,177.92000000000002,41988638.1,38646531.300000004,80559387.27000001,0.0035341206485792753,0.8055938726999999 627 | 2017-10-26,-75782.1300000012,177.92000000000002,42164217.64,38767923.89,80856359.4,0.003686375232779149,0.8085635939999999 628 | 2017-10-27,-75782.1300000012,177.92000000000002,42463959.26,38873047.37,81261224.5,0.0050072140645995855,0.8126122449999998 629 | 2017-10-27,-75782.1300000012,177.92000000000002,42463959.26,38873047.37,81261224.5,0.0,0.8126122449999998 630 | -------------------------------------------------------------------------------- /tests/test_factor.py: -------------------------------------------------------------------------------- 1 | import tushare as ts 2 | from wolfquant.factors import trade_factors 3 | import matplotlib.pyplot as plt 4 | 5 | 6 | def test_trade_factors(factors): 7 | data = ts.get_k_data('000300', index=True) 8 | data = factors(data, 5).dropna().set_index('date') 9 | # 画图 10 | fig = plt.figure(figsize=(7, 5)) 11 | ax = fig.add_subplot(2, 1, 1) 12 | ax.set_xticklabels([]) 13 | data['close'].plot(lw=1) 14 | plt.title('hs300') 15 | plt.ylabel('close_price') 16 | plt.grid(True) 17 | fig.add_subplot(2, 1, 2) 18 | data[data.columns[-1]].plot(color='k', lw=0.75, linestyle='-', label='factor') 19 | plt.legend(loc=2, prop={'size': 9}) 20 | plt.ylabel('factor values') 21 | plt.grid(True) 22 | plt.setp(plt.gca().get_xticklabels(), rotation=30) 23 | plt.show() 24 | 25 | 26 | if __name__ == '__main__': 27 | test_trade_factors(trade_factors.ROC) 28 | -------------------------------------------------------------------------------- /tests/test_interface.py: -------------------------------------------------------------------------------- 1 | from wolfquant.interface import MdGateway 2 | 3 | 4 | def test_get_data(): 5 | import time 6 | from wolfquant import config 7 | user_info = config('../config.json')['user_info'] 8 | new_getway = MdGateway() 9 | new_getway.connect(user_info['brokerID'], 10 | user_info['userID'], 11 | user_info['password'], 12 | user_info['register_front'], 13 | ['rb1801']) 14 | try: 15 | while 1: 16 | time.sleep(1) 17 | print(new_getway._snapshot_cache) 18 | except KeyboardInterrupt: 19 | pass 20 | 21 | 22 | if __name__ == '__main__': 23 | test_get_data() 24 | -------------------------------------------------------------------------------- /tests/test_ml.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import numpy as np 3 | import tushare as ts 4 | from sklearn.linear_model import LogisticRegression 5 | from sklearn.ensemble import RandomForestClassifier 6 | from sklearn.discriminant_analysis import LinearDiscriminantAnalysis, QuadraticDiscriminantAnalysis 7 | from sklearn.svm import LinearSVC, SVC 8 | from sklearn.metrics import confusion_matrix 9 | from wolfquant.utils.factor_utils import Factor_pipeline 10 | from wolfquant.factors import trade_factors as tf 11 | 12 | # 获取数据 13 | datasets = ts.get_k_data('000300', start='2005-01-01', index=True).set_index('date') 14 | datasets.index = pd.to_datetime(datasets.index, format='%Y-%m-%d') 15 | 16 | # 构建特征 17 | datasets = Factor_pipeline(datasets).add(tf.SMA, 50)\ 18 | .add(tf.EWMA, 200)\ 19 | .add(tf.BBANDS, 50)\ 20 | .add(tf.CCI, 20)\ 21 | .add(tf.ForceIndex, 1)\ 22 | .add(tf.EVM, 14)\ 23 | .add(tf.ROC, 5)\ 24 | .add(tf.LAGRETURN, 0)\ 25 | .data.dropna() 26 | 27 | # 构建标签 28 | datasets['direction'] = np.sign(datasets['LAGRETURN_0']).shift(-1) 29 | datasets = datasets.dropna() 30 | 31 | # 构建训练集和测试集 32 | X = datasets[datasets.columns[6:-2]] 33 | y = datasets['direction'] 34 | start_test = '2012-01-01' 35 | X_train = X.loc[:start_test] 36 | X_test = X.loc[start_test:] 37 | y_train = y.loc[:start_test] 38 | y_test = y.loc[start_test:] 39 | 40 | # 构建模型 41 | print('Hit rates/Confusion Matrices:\n') 42 | models = [('LR', LogisticRegression()), 43 | ('LDA', LinearDiscriminantAnalysis()), 44 | ('QDA', QuadraticDiscriminantAnalysis()), 45 | ('LSVC', LinearSVC()), 46 | ('RSVM', SVC()), 47 | ('RF', RandomForestClassifier(n_estimators=1000))] 48 | 49 | # 遍历模型 50 | for m in models: 51 | # 训练模型 52 | m[1].fit(X_train, y_train) 53 | # 预测模型 54 | pred = m[1].predict(X_test) 55 | # 输出hit-rate和交叉验证结果 56 | print("%s:\n%0.3f" % (m[0], m[1].score(X_test, y_test))) 57 | print("%s\n" % confusion_matrix(pred, y_test)) 58 | -------------------------------------------------------------------------------- /tests/test_strategy.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import numpy as np 3 | from wolfquant.api import run_backtest 4 | from wolfquant.strategy import Strategy 5 | 6 | 7 | class MovingAverageCrossStrategy(Strategy): 8 | """ 9 | Carries out a basic Moving Average Crossover strategy with a 10 | short/long simple weighted moving average. Default short/long 11 | windows are 100/400 periods respectively. 12 | results: 13 | Total Return: 6.05% 14 | Sharpe Ratio: 1.22 15 | Max Drawdown: 1.80% 16 | Drawdown Duration: 353 17 | 交易信号数: 3 18 | 下单数: 3 19 | 成交数: 3 20 | """ 21 | def init(self): 22 | self.short_window = 10 23 | self.long_window = 100 24 | self.bought = self._calculate_initial_bought() 25 | 26 | def _calculate_initial_bought(self): 27 | """ 28 | Adds keys to the bought dictionary for all symbols 29 | and sets them to 'OUT'. 30 | """ 31 | bought = {} 32 | for s in self.symbol_list: 33 | bought[s] = 'OUT' 34 | return bought 35 | 36 | def handle_bar(self, bar_dict): 37 | """ 38 | Generates a new set of signals based on the MAC 39 | SMA with the short window crossing the long window 40 | meaning a long entry and vice versa for a short entry. 41 | 42 | Parameters: 43 | bar_dict: 不同symbol的行情信息 44 | """ 45 | for symbol in self.symbol_list: 46 | bars = self.bars.get_latest_bars_values( 47 | symbol, "close", N=self.long_window) 48 | 49 | if bars is not None and bars != []: 50 | short_sma = np.mean(bars[-self.short_window:]) 51 | long_sma = np.mean(bars[-self.long_window:]) 52 | quantity = 10 53 | 54 | if short_sma > long_sma and self.bought[symbol] == "OUT": 55 | self.order_percent(symbol, 0.5) 56 | self.bought[symbol] = 'LONG' 57 | 58 | elif short_sma < long_sma and self.bought[symbol] == "LONG": 59 | self.order_shares(symbol, -quantity) 60 | self.bought[symbol] = 'OUT' 61 | 62 | 63 | class BuyAndHoldStrategy(Strategy): 64 | """一直持有策略 65 | results: 66 | Total Return: -2.74% 67 | Sharpe Ratio: -0.05 68 | Max Drawdown: 25.00% 69 | Drawdown Duration: 584 70 | 交易信号数: 1 71 | 下单数: 1 72 | 成交数: 1 73 | """ 74 | def init(self): 75 | self.bought = dict([(symbol, False) for symbol in self.symbol_list]) 76 | 77 | def handle_bar(self, bar_dict): 78 | for s in self.symbol_list: 79 | if self.bought[s] is False: 80 | self.order_shares(s, 10) 81 | self.bought[s] = True 82 | 83 | 84 | if __name__ == "__main__": 85 | run_backtest(MovingAverageCrossStrategy, { 86 | 'symbol_list': ['hs300', 'sh000001'], 87 | 'init_cash': 100000000.0, 88 | 'start': '2015-04-08', 89 | 'end': '2017-10-27' 90 | }) 91 | -------------------------------------------------------------------------------- /wolfquant/__init__.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | 4 | def config(filepath): 5 | """配置文件 6 | """ 7 | with open(filepath, encoding='utf8') as json_file: 8 | return json.load(json_file) -------------------------------------------------------------------------------- /wolfquant/api.py: -------------------------------------------------------------------------------- 1 | from wolfquant.backtest import Backtest 2 | from wolfquant.data import TushareDataHandler 3 | from wolfquant.event import SignalEvent, OrderEvent 4 | from wolfquant.execution import SimulatedExecutionHandler 5 | from wolfquant.portfolio import NaivePortfolio 6 | 7 | 8 | def run_backtest(strategy, config): 9 | """进行回测 10 | """ 11 | backtest = Backtest(config['symbol_list'], 12 | config['init_cash'], 13 | config['start'], 14 | config['end'], 15 | TushareDataHandler, 16 | SimulatedExecutionHandler, 17 | NaivePortfolio, 18 | strategy) 19 | backtest.simulate_trading() 20 | -------------------------------------------------------------------------------- /wolfquant/backtest.py: -------------------------------------------------------------------------------- 1 | import queue 2 | import pprint 3 | import time 4 | import sys 5 | 6 | 7 | class Backtest(object): 8 | """进行Bactest的组件和配置 9 | """ 10 | def __init__( 11 | self, 12 | symbol_list, 13 | initial_capital, 14 | start_date, 15 | end_date, 16 | data_handler, 17 | execution_handler, 18 | portfolio, 19 | strategy, 20 | heartbeat=0.0, 21 | csv_dir=None 22 | ): 23 | self.symbol_list = symbol_list # 交易列表 24 | self.initial_capital = initial_capital # 初始本金 25 | self.heartbeat = heartbeat # 心跳 26 | self.start_date = start_date # 开始日期 27 | self.end_date = end_date # 结束日期 28 | self.csv_dir = csv_dir # 读取的数据的路径 29 | 30 | self.data_handler_cls = data_handler # 行情数据 31 | self.execution_handler_cls = execution_handler # 交易 32 | self.portfolio_cls = portfolio # 组合 33 | self.strategy_cls = strategy # 策略 34 | 35 | self.events = queue.Queue() 36 | 37 | self.signals = 0 # 信号数 38 | self.orders = 0 # 订单数 39 | self.fills = 0 # 成交数 40 | 41 | self.__generate_trading_instances() 42 | 43 | def __generate_trading_instances(self): 44 | """生成交易实例对象 45 | """ 46 | print("=====================\n开始进行回测...\n=====================") 47 | self.data_handler = self.data_handler_cls(self.events, self.symbol_list, self.start_date, self.end_date, self.csv_dir) 48 | self.portfolio = self.portfolio_cls(self.data_handler, self.events, self.start_date, self.initial_capital) 49 | self.strategy = self.strategy_cls(self.data_handler, self.events, self.portfolio) 50 | self.execution_handler = self.execution_handler_cls(self.events) # 生成交易实例 51 | 52 | def __run_backtest(self): 53 | """执行回测 54 | """ 55 | i = 0 56 | while True: 57 | i += 1 58 | # 更新市场Bar 59 | if self.data_handler.continue_backtest is True: # 如果可以继续进行回测,就更细bar 60 | self.data_handler.update_bars() 61 | else: 62 | break 63 | 64 | # 处理事件 65 | while True: 66 | try: 67 | event = self.events.get(False) # 获取事件队列的第一个元素 68 | except queue.Empty: # 如果事件队列空了,就进入下一个bar 69 | break 70 | else: 71 | if event is not None: 72 | if event.type == 'MARKET': # 如果事件类型是行情,就计算交易信号 73 | bar_dict = self.data_handler.get_latest_bars_dict(self.symbol_list) 74 | self.strategy.handle_bar(bar_dict) # 运行策略 75 | self.portfolio.update_timeindex(event) # 更新时间戳 76 | elif event.type == 'SIGNAL': # 如果事件类型是交易信号,就根据交易信号生成订单 77 | self.signals += 1 78 | self.portfolio.update_signal(event) 79 | elif event.type == 'ORDER': # 如果事件类型是订单信号,就执行交易 80 | self.orders += 1 81 | self.execution_handler.execute_order(event) 82 | elif event.type == 'FILL': # 如果事件类型是成交,就更新portfolio 83 | self.fills += 1 84 | self.portfolio.update_fill(event) 85 | 86 | time.sleep(self.heartbeat) 87 | 88 | def __output_performance(self): 89 | """输出策略的表现 90 | """ 91 | self.portfolio.create_equity_curve_dataframe() # 交易结束后,创建portfolio的历史序列数据 92 | print("\n=====================\n创建统计描述...\n=====================") 93 | stats = self.portfolio.output_summary_stats() 94 | for name, value in stats: 95 | print('{}: {}'.format(name, value)) 96 | 97 | print('交易信号数: {}'.format(self.signals)) 98 | print("下单数: {}".format(self.orders)) 99 | print('成交数: {}'.format(self.fills)) 100 | 101 | def simulate_trading(self): 102 | """模拟回测并输出结果 103 | """ 104 | self.__run_backtest() 105 | self.__output_performance() 106 | -------------------------------------------------------------------------------- /wolfquant/data.py: -------------------------------------------------------------------------------- 1 | import os 2 | import tushare as ts 3 | import pandas as pd 4 | from abc import ABCMeta, abstractmethod 5 | from wolfquant.event import MarketEvent 6 | from wolfquant.utils.db_utils import get_daily_data_from_db_new 7 | 8 | 9 | class DataHandler(object): 10 | __metaclass__ = ABCMeta 11 | 12 | def __init__(self, events, symbol_list, start_date, end_date, csv_dir=None): 13 | self.csv_dir = csv_dir 14 | self.events = events 15 | self.symbol_list = symbol_list 16 | self.start_date = start_date 17 | self.end_date = end_date 18 | self.symbol_data = {} 19 | self.latest_symbol_data = {} 20 | self.continue_backtest = True 21 | self.init_data() 22 | 23 | @abstractmethod 24 | def init_data(self): 25 | raise NotImplementedError('Should implement init_data()') 26 | 27 | @abstractmethod 28 | def get_latest_bars(self, symbol, N=1): 29 | raise NotImplementedError('Should implement get_latest_bars()') 30 | 31 | @abstractmethod 32 | def update_bars(self): 33 | raise NotImplementedError('Should implement update_bars()') 34 | 35 | def get_latest_bars_dict(self, symbol_list, N=1): 36 | """获取多个证券的bar 37 | """ 38 | bar_dict = {} 39 | for symbol in symbol_list: 40 | bar_dict[symbol] = self.get_latest_bars(symbol, N=N) 41 | return bar_dict 42 | 43 | def get_latest_bars_values(self, symbol, column, N=1): 44 | bar_columns = ['symbol', 'datetime', 'open', 'close', 'high', 'low', 'volume'] 45 | bar_list = self.get_latest_bars(symbol, N=N) 46 | return [bar[bar_columns.index(column)] for bar in bar_list] 47 | 48 | def get_latest_bar_datetime(self, symbol): 49 | """获取最新的bar的执行日期 50 | """ 51 | bar_list = self.get_latest_bars(symbol) 52 | return bar_list[0][1] 53 | 54 | def get_data_number(self, symbol): 55 | return len(self.latest_symbol_data[symbol]) 56 | 57 | 58 | class HistoricDataHandler(DataHandler): 59 | def init_data(self): 60 | comb_index = None 61 | for s in self.symbol_list: 62 | self.symbol_data[s] = self.history(s) 63 | if comb_index is None: 64 | comb_index = self.symbol_data[s].index 65 | else: 66 | comb_index = comb_index.union(self.symbol_data[s].index) 67 | self.latest_symbol_data[s] = [] 68 | 69 | # 选取指定时间段的数据,并重置索引 70 | comb_index = comb_index[(comb_index >= self.start_date) * (comb_index <= self.end_date)] 71 | for s in self.symbol_list: 72 | self.symbol_data[s] = self.symbol_data[s].reindex(index=comb_index).fillna(0.0).iterrows() 73 | 74 | def history(self, symbol): 75 | """获取历史数据 76 | """ 77 | pass 78 | 79 | def __get_new_bar(self, symbol): 80 | for b in self.symbol_data[symbol]: 81 | yield tuple([symbol, b[0], b[1][0], b[1][1], b[1][2], b[1][3], b[1][4]]) 82 | 83 | def get_latest_bars(self, symbol, N=1): 84 | try: 85 | bar_list = self.latest_symbol_data[symbol] 86 | except KeyError: 87 | print("That symbol is not available in the historical data set.") 88 | else: 89 | return bar_list[-N:] 90 | 91 | def update_bars(self): 92 | for s in self.symbol_list: 93 | try: 94 | bar = self.__get_new_bar(s).__next__() 95 | except StopIteration: 96 | self.continue_backtest = False 97 | else: 98 | if bar is not None: 99 | self.latest_symbol_data[s].append(bar) 100 | self.events.put(MarketEvent()) 101 | 102 | 103 | class CsvDataHandler(HistoricDataHandler): 104 | def history(self, symbol): 105 | """获取历史数据 106 | """ 107 | return pd.io.parsers.read_csv(os.path.join(self.csv_dir, '%s.csv' % symbol), header=0, index_col=0, names=['datetime', 'open', 'close', 'high', 'low', 'volume'], parse_dates=True) 108 | 109 | 110 | class TushareDataHandler(HistoricDataHandler): 111 | def history(self, symbol): 112 | """获取历史数据 113 | """ 114 | data = ts.get_k_data(symbol.split('.')[0], start=self.start_date, end=self.end_date).set_index('date')[[ 115 | 'open', 'close', 'high', 'low', 'volume' 116 | ]] 117 | data.index = pd.to_datetime(data.index, format='%Y-%m-%d') 118 | return data 119 | 120 | 121 | class DataBaseDataHandler(HistoricDataHandler): 122 | def history(self, symbol): 123 | """获取历史护具 124 | """ 125 | return get_daily_data_from_db_new(symbol, self.start_date, self.end_date) -------------------------------------------------------------------------------- /wolfquant/event.py: -------------------------------------------------------------------------------- 1 | class Event(object): 2 | """ 3 | Event is base class providing an interface for all subsequent 4 | (inherited) events, that will trigger further events in the 5 | trading infrastructure. 6 | """ 7 | pass 8 | 9 | 10 | class MarketEvent(Event): 11 | """ 12 | Handles the event of receiving a new market update with 13 | corresponding bars. 14 | """ 15 | 16 | def __init__(self): 17 | """ 18 | Initialises the MarketEvent. 19 | """ 20 | self.type = 'MARKET' 21 | 22 | 23 | class SignalEvent(Event): 24 | """ 25 | Handles the event of sending a Signal from a Strategy object. 26 | This is received by a Portfolio object and acted upon. 27 | """ 28 | 29 | def __init__(self, strategy_id, symbol, datetime, signal_type, quantity, order_type): 30 | """ 31 | Initialises the SignalEvent. 32 | 33 | Parameters: 34 | strategy_id - The unique ID of the strategy sending the signal. 35 | symbol - The ticker symbol, e.g. 'GOOG'. 36 | datetime - The timestamp at which the signal was generated. 37 | signal_type - 'LONG' or 'SHORT'. 38 | quantity - 订单数 39 | order_style - 订单成交类型 40 | """ 41 | self.strategy_id = strategy_id 42 | self.type = 'SIGNAL' 43 | self.symbol = symbol 44 | self.datetime = datetime 45 | self.signal_type = signal_type 46 | self.quantity = quantity 47 | self.order_type = order_type 48 | 49 | 50 | class OrderEvent(Event): 51 | """ 52 | Handles the event of sending an Order to an execution system. 53 | The order contains a symbol (e.g. GOOG), a type (market or limit), 54 | quantity and a direction. 55 | """ 56 | 57 | def __init__(self, symbol, order_type, quantity, direction): 58 | """ 59 | Initialises the order type, setting whether it is 60 | a Market order ('MKT') or Limit order ('LMT'), has 61 | a quantity (integral) and its direction ('BUY' or 62 | 'SELL'). 63 | 64 | TODO: Must handle error checking here to obtain 65 | rational orders (i.e. no negative quantities etc). 66 | 67 | Parameters: 68 | symbol - The instrument to trade. 69 | order_type - 'MKT' or 'LMT' for Market or Limit. 70 | quantity - Non-negative integer for quantity. 71 | direction - 'BUY' or 'SELL' for long or short. 72 | """ 73 | self.type = 'ORDER' 74 | self.symbol = symbol 75 | self.order_type = order_type 76 | self.quantity = quantity 77 | self.direction = direction 78 | 79 | def print_order(self): 80 | """ 81 | Outputs the values within the Order. 82 | """ 83 | print( 84 | "Order: Symbol=%s, Type=%s, Quantity=%s, Direction=%s" % 85 | (self.symbol, self.order_type, self.quantity, self.direction) 86 | ) 87 | 88 | 89 | class FillEvent(Event): 90 | """ 91 | Encapsulates the notion of a Filled Order, as returned 92 | from a brokerage. Stores the quantity of an instrument 93 | actually filled and at what price. In addition, stores 94 | the commission of the trade from the brokerage. 95 | 96 | TODO: Currently does not support filling positions at 97 | different prices. This will be simulated by averaging 98 | the cost. 99 | """ 100 | 101 | def __init__(self, timeindex, symbol, exchange, quantity, 102 | direction, fill_cost, commission=None): 103 | """ 104 | Initialises the FillEvent object. Sets the symbol, exchange, 105 | quantity, direction, cost of fill and an optional 106 | commission. 107 | 108 | If commission is not provided, the Fill object will 109 | calculate it based on the trade size and Interactive 110 | Brokers fees. 111 | 112 | Parameters: 113 | timeindex - The bar-resolution when the order was filled. 114 | symbol - The instrument which was filled. 115 | exchange - The exchange where the order was filled. 116 | quantity - The filled quantity. 117 | direction - The direction of fill ('BUY' or 'SELL') 118 | fill_cost - The holdings value in dollars. 119 | commission - An optional commission sent from IB. 120 | """ 121 | self.type = 'FILL' 122 | self.timeindex = timeindex 123 | self.symbol = symbol 124 | self.exchange = exchange 125 | self.quantity = quantity 126 | self.direction = direction 127 | self.fill_cost = fill_cost 128 | 129 | # Calculate commission 130 | if commission is None: 131 | self.commission = self.calculate_ib_commission() 132 | else: 133 | self.commission = commission 134 | 135 | def calculate_ib_commission(self): 136 | """ 137 | Calculates the fees of trading based on an Interactive 138 | Brokers fee structure for API, in USD. 139 | 140 | This does not include exchange or ECN fees. 141 | 142 | Based on "US API Directed Orders": 143 | https://www.interactivebrokers.com/en/index.php?f=commission&p=stocks2 144 | """ 145 | full_cost = 1.3 146 | if self.quantity <= 500: 147 | full_cost = max(1.3, 0.013 * self.quantity) 148 | else: # Greater than 500 149 | full_cost = max(1.3, 0.008 * self.quantity) 150 | return full_cost 151 | -------------------------------------------------------------------------------- /wolfquant/execution.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime as dt 2 | from abc import ABCMeta, abstractmethod 3 | from wolfquant.event import FillEvent 4 | 5 | 6 | class ExecutionHandler(object): 7 | __metaclass__ = ABCMeta 8 | 9 | @abstractmethod 10 | def execute_order(self, event): 11 | raise NotImplementedError('Should implement execute_order()') 12 | 13 | 14 | class SimulatedExecutionHandler(ExecutionHandler): 15 | def __init__(self, events): 16 | self.events = events 17 | 18 | def execute_order(self, event): 19 | if event.type == 'ORDER': 20 | fill_event = FillEvent(dt.utcnow(), event.symbol, 'ARCA', event.quantity, event.direction, 1.3, None) 21 | self.events.put(fill_event) 22 | -------------------------------------------------------------------------------- /wolfquant/factors/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/wolfquant/factors/__init__.py -------------------------------------------------------------------------------- /wolfquant/factors/trade_factors.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import talib as ta 3 | 4 | 5 | ################################################################# 6 | # 滞后类指标 7 | ################################################################# 8 | def LAGRETURN(data, ndays): 9 | """滞后类收入指标 10 | args: 11 | - data: 标准的行情时间序列数据 12 | - ndays: 移动平均的天数 13 | return: 14 | - data: 加入滞后类指标的数据 15 | """ 16 | name = 'LAGRETURN_{}'.format(ndays) 17 | LAGRETURN = pd.Series(data['close'].shift(ndays).pct_change() * 100.0, name=name) 18 | data = data.join(LAGRETURN) 19 | return data 20 | 21 | 22 | ################################################################# 23 | # 移动平均线指标 24 | ################################################################# 25 | def SMA(data, ndays): 26 | """SMA: 简单的移动平均线 27 | args: 28 | - data: 标准的行情时间序列数据 29 | - ndays: 移动平均的天数 30 | return: 31 | - data: 加入移动平均指标的数据 32 | """ 33 | name = 'SMA_{}'.format(ndays) 34 | SMA = pd.Series(data['close'].rolling(ndays).mean(), name=name) 35 | data = data.join(SMA) 36 | return data 37 | 38 | 39 | def EWMA(data, ndays): 40 | """EWMA: 指数加权移动平均线 41 | args: 42 | - data: 标准的行情时间序列数据 43 | - ndays: 移动平均的天数 44 | return: 45 | - data: 加入移动平均指标的数据 46 | """ 47 | name = 'EWMA_{}'.format(ndays) 48 | EMA = pd.Series(data['close'].ewm(span=ndays, min_periods=ndays - 1).mean(), name=name) 49 | data = data.join(EMA) 50 | return data 51 | 52 | 53 | def MACD(data, fastperiod=12, slowperiod=26, signalperiod=9): 54 | """MACD指标:指数平滑移动平均线 55 | """ 56 | macd, macdsignal, macdhist = ta.MACD(data['close'].values, fastperiod=fastperiod, slowperiod=slowperiod, signalperiod=signalperiod) 57 | data['macd'] = macd 58 | data['macdsignal'] = macdsignal 59 | data['macdhist'] = macdhist 60 | return data 61 | 62 | 63 | ################################################################# 64 | # 布林线指标 65 | ################################################################# 66 | def BBANDS(data, ndays): 67 | """BBANDS: 布林线指标 68 | args: 69 | - data: 标准的行情时间序列数据 70 | - ndays: 移动平均的天数 71 | return: 72 | - data: 加入BBANDS指标的数据 73 | """ 74 | MA = pd.Series(data['close'].rolling(ndays).mean(), name='MA_{}'.format(ndays)) 75 | SD = pd.Series(data['close'].rolling(ndays).std()) 76 | b1 = pd.Series(MA + (2 * SD), name='Upper_BollingBond') 77 | b2 = pd.Series(MA - (2 * SD), name='Lower_BollingBond') 78 | data = data.join(MA).join(b1).join(b2) 79 | return data 80 | 81 | 82 | ################################################################# 83 | # 趋势类指标 84 | ################################################################# 85 | def CCI(data, ndays): 86 | """CCI: 属于超买和超卖的指标 87 | args: 88 | - data: 标准的行情时间序列数据 89 | - ndays: 移动平均的天数 90 | return: 91 | - data: 加入CCI指标的数据 92 | """ 93 | TP = (data['high'] + data['low'] + data['close']) / 3 94 | CCI = pd.Series((TP - TP.rolling(ndays).mean()) / (0.015 * TP.rolling(ndays).std()), name='CCI') 95 | data = data.join(CCI) 96 | return data 97 | 98 | 99 | def ForceIndex(data, ndays): 100 | """ForceIndex: 强力指标,该指标用来表示上升或下降趋势的力量大小,在零线上下移动来表示趋势的强弱。 101 | args: 102 | - data: 标准的行情时间序列数据 103 | - ndays: 移动平均的天数 104 | return: 105 | - data: 加入ForceIndex指标的数据 106 | """ 107 | FI = pd.Series(data['close'].diff(ndays) * data['volume'], name='ForceIndex') 108 | data = data.join(FI) 109 | return data 110 | 111 | 112 | ################################################################# 113 | # 波动类指标 114 | ################################################################# 115 | def EVM(data, ndays): 116 | """EVM: 简易波动指标,将价格与成交量的变化结合成为一个波动指标来反映股价或指数的变动情况。 117 | args: 118 | - data: 标准的行情时间序列数据 119 | - ndays: 移动平均的天数 120 | return: 121 | - data: 加入EVM指标的数据 122 | """ 123 | dm = (data['high'] + data['low']) / 2 - (data['high'].shift(1) + data['low'].shift(1)) / 2 124 | br = (data['volume'] / 100000000) / (data['high'] - data['low']) 125 | EVM = dm / br 126 | EVM_MA = pd.Series(EVM.rolling(ndays).mean(), name='EVM') 127 | data = data.join(EVM_MA) 128 | return data 129 | 130 | 131 | def ROC(data, ndays): 132 | """ROC: 变动率指标,今天的收盘价比较其N天前的收盘价的差除以N天前的收盘,以比率表示之。 133 | args: 134 | - data: 标准的行情时间序列数据 135 | - ndays: 移动平均的天数 136 | return: 137 | - data: 加入ROC指标的数据 138 | """ 139 | N = data['close'].diff(ndays) 140 | D = data['close'].shift(ndays) 141 | ROC = pd.Series(N / D, name='ROC') 142 | data = data.join(ROC) 143 | return data 144 | 145 | 146 | ################################################################# 147 | # 相对强弱指标 148 | ################################################################# 149 | def RSI(data, ndays): 150 | """RSI: 相对强弱指标,相对强弱指数RSI是根据一定时期内上涨点数和涨跌点数之和的比率制作出的一种技术曲线。 151 | args: 152 | - data: 标准的行情时间序列数据 153 | - ndays: 时间窗口 154 | return: 155 | - data: 加入RSI指标的数据 156 | """ 157 | RSI = pd.Series(ta.RSI(data['close'].values, timeperiod=ndays), name='RSI') 158 | data = data.join(RSI) 159 | return data 160 | -------------------------------------------------------------------------------- /wolfquant/interface/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import logging 3 | from time import sleep 4 | from queue import Queue, Empty 5 | from wolfquant.utils.api_utils import str2bytes 6 | from wolfquant.interface.future import ApiStruct, MdApi 7 | from wolfquant.utils.data_utils import TickDict 8 | 9 | 10 | class CtpMdApi(MdApi): 11 | def __init__(self, gateway, brokerID, userID, password, register_front): 12 | super(CtpMdApi, self).__init__() 13 | self.gateway = gateway 14 | self.requestID = 0 15 | self.brokerID = str2bytes(brokerID) 16 | self.userID = str2bytes(userID) 17 | self.password = str2bytes(password) 18 | self.register_front = str2bytes(register_front) 19 | self._req_id = 0 20 | self.logged_in = False 21 | self.connected = False 22 | 23 | def connect(self): 24 | """连接接口 25 | """ 26 | if not self.connected: 27 | self.Create() 28 | self.RegisterFront(self.register_front) 29 | self.Init() 30 | else: 31 | self.login() 32 | 33 | def login(self): 34 | """登录 35 | """ 36 | if not self.logged_in: 37 | req = ApiStruct.ReqUserLogin(BrokerID=self.brokerID, 38 | UserID=self.userID, 39 | Password=self.password) 40 | req_id = self.req_id 41 | self.ReqUserLogin(req, req_id) 42 | return req_id 43 | 44 | def subscribe(self, ins_id_list): 45 | """订阅合约""" 46 | if len(ins_id_list) > 0: 47 | ins_id_list = [str2bytes(i) for i in ins_id_list] 48 | self.SubscribeMarketData(ins_id_list) 49 | 50 | @property 51 | def req_id(self): 52 | self._req_id += 1 53 | return self._req_id 54 | 55 | def RegisterFront(self, front): 56 | front = str2bytes(front) 57 | if isinstance(front, bytes): 58 | return MdApi.RegisterFront(self, front) 59 | for front in front: 60 | MdApi.RegisterFront(self, front) 61 | 62 | def OnFrontConnected(self): 63 | """服务器连接 64 | """ 65 | self.connected = True 66 | self.login() 67 | 68 | def OnFrontDisconnected(self, nReason): 69 | """服务器失去连接 70 | """ 71 | self.connected = False 72 | self.logged_in = False 73 | self.gateway.on_debug('服务器断开,将自动重连。') 74 | 75 | def OnHeartBeatWarning(self, nTimeLapse): 76 | self.gateway.on_debug('OnHeartBeatWarning:', nTimeLapse) 77 | 78 | def OnRspUserLogin(self, pRspUserLogin, pRspInfo, nRequestID, bIsLast): 79 | """登录反馈 80 | """ 81 | print('用户登录:{}'.format(pRspInfo)) 82 | if pRspInfo.ErrorID == 0: 83 | self.logged_in = True 84 | print('交易日期:', self.GetTradingDay()) 85 | else: 86 | self.gateway.on_err(pRspInfo, sys._getframe().f_code.co_name) 87 | 88 | def OnRspSubMarketData(self, pSpecificInstrument, pRspInfo, nRequestID, bIsLast): 89 | print('连接市场数据:', pRspInfo) 90 | 91 | def OnRspUnSubMarketData(self, pSpecificInstrument, pRspInfo, nRequestID, bIsLast): 92 | print('OnRspUnSubMarketData:', pRspInfo) 93 | 94 | def OnRspError(self, pRspInfo, nRequestID, bIsLast): 95 | print('OnRspError:', pRspInfo) 96 | 97 | def OnRspUserLogout(self, pUserLogout, pRspInfo, nRequestID, bIsLast): 98 | """登出反馈 99 | """ 100 | if pRspInfo.ErrorID == 0: 101 | self.logged_in = False 102 | else: 103 | self.gateway.on_err(pRspInfo, sys._getframe().f_code.co_name) 104 | 105 | def OnRtnDepthMarketData(self, pDepthMarketData): 106 | """行情推送 107 | """ 108 | tick_dict = TickDict(pDepthMarketData) 109 | if tick_dict.is_valid: 110 | self.gateway.on_tick(tick_dict) 111 | 112 | 113 | class MdGateway(object): 114 | def __init__(self, retry_times=5, retry_interval=1): 115 | self._md_api = None 116 | self._retry_times = retry_times 117 | self._retry_interval = retry_interval 118 | self._snapshot_cache = {} 119 | self._tick_que = Queue() 120 | self.subscribed = [] 121 | 122 | def connect(self, user_id, password, broker_id, md_address, instrument_ids): 123 | self._md_api = CtpMdApi(self, user_id, password, broker_id, md_address) 124 | for i in range(self._retry_times): 125 | self._md_api.connect() 126 | sleep(self._retry_interval * (i + 1)) 127 | if self._md_api.logged_in: 128 | self.on_log('CTP 行情服务器登录成功') 129 | break 130 | else: 131 | raise RuntimeError('CTP 行情服务器连接或登录超时') 132 | self._md_api.subscribe(instrument_ids) 133 | self.on_log('数据同步完成。') 134 | 135 | def get_tick(self): 136 | while True: 137 | try: 138 | return self._tick_que.get(block=True, timeout=1) 139 | except Empty: 140 | self.on_debug('Get tick timeout.') 141 | 142 | def exit(self): 143 | """退出 144 | """ 145 | self._md_api.close() 146 | 147 | @property 148 | def snapshot(self): 149 | return self._snapshot_cache 150 | 151 | def on_tick(self, tick_dict): 152 | if tick_dict.order_book_id in self.subscribed: 153 | self._tick_que.put(tick_dict) 154 | self._snapshot_cache[tick_dict.order_book_id] = tick_dict 155 | 156 | def on_universe_changed(self, event): 157 | self.subscribed = event.universe 158 | 159 | @staticmethod 160 | def on_debug(debug): 161 | logging.debug(debug) 162 | 163 | @staticmethod 164 | def on_log(log): 165 | logging.info(log) 166 | 167 | @staticmethod 168 | def on_err(error, func_name): 169 | logging.error('CTP 错误,错误代码:%s,错误信息:%s' % (str(error.ErrorID), error.ErrorMsg.decode('utf8'))) 170 | 171 | 172 | if __name__ == '__main__': 173 | import time 174 | from wolfquant import config 175 | user_info = config('../../config.json')['user_info'] 176 | new_getway = MdGateway() 177 | new_getway.connect(user_info['brokerID'], 178 | user_info['userID'], 179 | user_info['password'], 180 | user_info['register_front'], 181 | ['RB1801']) 182 | try: 183 | while 1: 184 | time.sleep(1) 185 | except KeyboardInterrupt: 186 | pass 187 | -------------------------------------------------------------------------------- /wolfquant/interface/future/_MdApi.cpython-36m-x86_64-linux-gnu.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/wolfquant/interface/future/_MdApi.cpython-36m-x86_64-linux-gnu.so -------------------------------------------------------------------------------- /wolfquant/interface/future/_TraderApi.cpython-36m-x86_64-linux-gnu.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/wolfquant/interface/future/_TraderApi.cpython-36m-x86_64-linux-gnu.so -------------------------------------------------------------------------------- /wolfquant/interface/future/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from __future__ import absolute_import as _init 4 | 5 | __author__ = 'lovelylain' 6 | __version__ = '0.2.1' 7 | 8 | __all__ = ['ApiStruct', 'MdApi', 'TraderApi'] 9 | 10 | if 0: from . import ApiStruct 11 | 12 | class MdApi(object): 13 | def Create(self, pszFlowPath='', bIsUsingUdp=False, bIsMulticast=False): 14 | """创建MdApi 15 | @param pszFlowPath 存贮订阅信息文件的目录,默认为当前目录 16 | @return 创建出的UserApi 17 | modify for udp marketdata 18 | """ 19 | 20 | def GetApiVersion(self): 21 | """获取API的版本信息 22 | @retrun 获取到的版本号 23 | """ 24 | return '' 25 | 26 | def Release(self): 27 | """删除接口对象本身 28 | @remark 不再使用本接口对象时,调用该函数删除接口对象 29 | """ 30 | 31 | def Init(self): 32 | """初始化 33 | @remark 初始化运行环境,只有调用后,接口才开始工作 34 | """ 35 | 36 | def Join(self): 37 | """等待接口线程结束运行 38 | @return 线程退出代码 39 | """ 40 | return 0 41 | 42 | def GetTradingDay(self): 43 | """获取当前交易日 44 | @retrun 获取到的交易日 45 | @remark 只有登录成功后,才能得到正确的交易日 46 | """ 47 | return '' 48 | 49 | def RegisterFront(self, pszFrontAddress): 50 | """注册前置机网络地址 51 | @param pszFrontAddress:前置机网络地址。 52 | @remark 网络地址的格式为:“protocol: 53 | ipaddress:port”,如:”tcp: 54 | 127.0.0.1:17001”。 55 | @remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。 56 | """ 57 | 58 | def RegisterNameServer(self, pszNsAddress): 59 | """注册名字服务器网络地址 60 | @param pszNsAddress:名字服务器网络地址。 61 | @remark 网络地址的格式为:“protocol: 62 | ipaddress:port”,如:”tcp: 63 | 127.0.0.1:12001”。 64 | @remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”12001”代表服务器端口号。 65 | @remark RegisterNameServer优先于RegisterFront 66 | """ 67 | 68 | def RegisterFensUserInfo(self, pFensUserInfo): 69 | """注册名字服务器用户信息 70 | @param pFensUserInfo:用户信息。 71 | """ 72 | 73 | def SubscribeMarketData(self, pInstrumentIDs): 74 | """订阅行情。 75 | @param pInstrumentIDs 合约ID列表 76 | @remark 77 | """ 78 | return 0 79 | 80 | def UnSubscribeMarketData(self, pInstrumentIDs): 81 | """退订行情。 82 | @param pInstrumentIDs 合约ID列表 83 | @remark 84 | """ 85 | return 0 86 | 87 | def SubscribeForQuoteRsp(self, pInstrumentIDs): 88 | """订阅询价。 89 | @param pInstrumentIDs 合约ID列表 90 | @remark 91 | """ 92 | return 0 93 | 94 | def UnSubscribeForQuoteRsp(self, pInstrumentIDs): 95 | """退订询价。 96 | @param pInstrumentIDs 合约ID列表 97 | @remark 98 | """ 99 | return 0 100 | 101 | def ReqUserLogin(self, pReqUserLogin, nRequestID): 102 | """用户登录请求""" 103 | return 0 104 | 105 | def ReqUserLogout(self, pUserLogout, nRequestID): 106 | """登出请求""" 107 | return 0 108 | 109 | def OnFrontConnected(self): 110 | """当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。""" 111 | 112 | def OnFrontDisconnected(self, nReason): 113 | """当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 114 | @param nReason 错误原因 115 | 0x1001 网络读失败 116 | 0x1002 网络写失败 117 | 0x2001 接收心跳超时 118 | 0x2002 发送心跳失败 119 | 0x2003 收到错误报文 120 | """ 121 | 122 | def OnHeartBeatWarning(self, nTimeLapse): 123 | """心跳超时警告。当长时间未收到报文时,该方法被调用。 124 | @param nTimeLapse 距离上次接收报文的时间 125 | """ 126 | 127 | def OnRspUserLogin(self, pRspUserLogin, pRspInfo, nRequestID, bIsLast): 128 | """登录请求响应""" 129 | 130 | def OnRspUserLogout(self, pUserLogout, pRspInfo, nRequestID, bIsLast): 131 | """登出请求响应""" 132 | 133 | def OnRspError(self, pRspInfo, nRequestID, bIsLast): 134 | """错误应答""" 135 | 136 | def OnRspSubMarketData(self, pSpecificInstrument, pRspInfo, nRequestID, bIsLast): 137 | """订阅行情应答""" 138 | 139 | def OnRspUnSubMarketData(self, pSpecificInstrument, pRspInfo, nRequestID, bIsLast): 140 | """取消订阅行情应答""" 141 | 142 | def OnRspSubForQuoteRsp(self, pSpecificInstrument, pRspInfo, nRequestID, bIsLast): 143 | """订阅询价应答""" 144 | 145 | def OnRspUnSubForQuoteRsp(self, pSpecificInstrument, pRspInfo, nRequestID, bIsLast): 146 | """取消订阅询价应答""" 147 | 148 | def OnRtnDepthMarketData(self, pDepthMarketData): 149 | """深度行情通知""" 150 | 151 | def OnRtnForQuoteRsp(self, pForQuoteRsp): 152 | """询价通知""" 153 | 154 | 155 | class TraderApi(object): 156 | def Create(self, pszFlowPath=''): 157 | """创建TraderApi 158 | @param pszFlowPath 存贮订阅信息文件的目录,默认为当前目录 159 | @return 创建出的UserApi 160 | """ 161 | 162 | def GetApiVersion(self): 163 | """获取API的版本信息 164 | @retrun 获取到的版本号 165 | """ 166 | return '' 167 | 168 | def Release(self): 169 | """删除接口对象本身 170 | @remark 不再使用本接口对象时,调用该函数删除接口对象 171 | """ 172 | 173 | def Init(self): 174 | """初始化 175 | @remark 初始化运行环境,只有调用后,接口才开始工作 176 | """ 177 | 178 | def Join(self): 179 | """等待接口线程结束运行 180 | @return 线程退出代码 181 | """ 182 | return 0 183 | 184 | def GetTradingDay(self): 185 | """获取当前交易日 186 | @retrun 获取到的交易日 187 | @remark 只有登录成功后,才能得到正确的交易日 188 | """ 189 | return '' 190 | 191 | def RegisterFront(self, pszFrontAddress): 192 | """注册前置机网络地址 193 | @param pszFrontAddress:前置机网络地址。 194 | @remark 网络地址的格式为:“protocol: 195 | ipaddress:port”,如:”tcp: 196 | 127.0.0.1:17001”。 197 | @remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”17001”代表服务器端口号。 198 | """ 199 | 200 | def RegisterNameServer(self, pszNsAddress): 201 | """注册名字服务器网络地址 202 | @param pszNsAddress:名字服务器网络地址。 203 | @remark 网络地址的格式为:“protocol: 204 | ipaddress:port”,如:”tcp: 205 | 127.0.0.1:12001”。 206 | @remark “tcp”代表传输协议,“127.0.0.1”代表服务器地址。”12001”代表服务器端口号。 207 | @remark RegisterNameServer优先于RegisterFront 208 | """ 209 | 210 | def RegisterFensUserInfo(self, pFensUserInfo): 211 | """注册名字服务器用户信息 212 | @param pFensUserInfo:用户信息。 213 | """ 214 | 215 | def SubscribePrivateTopic(self, nResumeType): 216 | """订阅私有流。 217 | @param nResumeType 私有流重传方式 218 | THOST_TERT_RESTART:从本交易日开始重传 219 | THOST_TERT_RESUME:从上次收到的续传 220 | THOST_TERT_QUICK:只传送登录后私有流的内容 221 | @remark 该方法要在Init方法前调用。若不调用则不会收到私有流的数据。 222 | """ 223 | 224 | def SubscribePublicTopic(self, nResumeType): 225 | """订阅公共流。 226 | @param nResumeType 公共流重传方式 227 | THOST_TERT_RESTART:从本交易日开始重传 228 | THOST_TERT_RESUME:从上次收到的续传 229 | THOST_TERT_QUICK:只传送登录后公共流的内容 230 | @remark 该方法要在Init方法前调用。若不调用则不会收到公共流的数据。 231 | """ 232 | 233 | def ReqAuthenticate(self, pReqAuthenticate, nRequestID): 234 | """客户端认证请求""" 235 | return 0 236 | 237 | def ReqUserLogin(self, pReqUserLogin, nRequestID): 238 | """用户登录请求""" 239 | return 0 240 | 241 | def ReqUserLogout(self, pUserLogout, nRequestID): 242 | """登出请求""" 243 | return 0 244 | 245 | def ReqUserPasswordUpdate(self, pUserPasswordUpdate, nRequestID): 246 | """用户口令更新请求""" 247 | return 0 248 | 249 | def ReqTradingAccountPasswordUpdate(self, pTradingAccountPasswordUpdate, nRequestID): 250 | """资金账户口令更新请求""" 251 | return 0 252 | 253 | def ReqOrderInsert(self, pInputOrder, nRequestID): 254 | """报单录入请求""" 255 | return 0 256 | 257 | def ReqParkedOrderInsert(self, pParkedOrder, nRequestID): 258 | """预埋单录入请求""" 259 | return 0 260 | 261 | def ReqParkedOrderAction(self, pParkedOrderAction, nRequestID): 262 | """预埋撤单录入请求""" 263 | return 0 264 | 265 | def ReqOrderAction(self, pInputOrderAction, nRequestID): 266 | """报单操作请求""" 267 | return 0 268 | 269 | def ReqQueryMaxOrderVolume(self, pQueryMaxOrderVolume, nRequestID): 270 | """查询最大报单数量请求""" 271 | return 0 272 | 273 | def ReqSettlementInfoConfirm(self, pSettlementInfoConfirm, nRequestID): 274 | """投资者结算结果确认""" 275 | return 0 276 | 277 | def ReqRemoveParkedOrder(self, pRemoveParkedOrder, nRequestID): 278 | """请求删除预埋单""" 279 | return 0 280 | 281 | def ReqRemoveParkedOrderAction(self, pRemoveParkedOrderAction, nRequestID): 282 | """请求删除预埋撤单""" 283 | return 0 284 | 285 | def ReqExecOrderInsert(self, pInputExecOrder, nRequestID): 286 | """执行宣告录入请求""" 287 | return 0 288 | 289 | def ReqExecOrderAction(self, pInputExecOrderAction, nRequestID): 290 | """执行宣告操作请求""" 291 | return 0 292 | 293 | def ReqForQuoteInsert(self, pInputForQuote, nRequestID): 294 | """询价录入请求""" 295 | return 0 296 | 297 | def ReqQuoteInsert(self, pInputQuote, nRequestID): 298 | """报价录入请求""" 299 | return 0 300 | 301 | def ReqQuoteAction(self, pInputQuoteAction, nRequestID): 302 | """报价操作请求""" 303 | return 0 304 | 305 | def ReqCombActionInsert(self, pInputCombAction, nRequestID): 306 | """申请组合录入请求""" 307 | return 0 308 | 309 | def ReqQryOrder(self, pQryOrder, nRequestID): 310 | """请求查询报单""" 311 | return 0 312 | 313 | def ReqQryTrade(self, pQryTrade, nRequestID): 314 | """请求查询成交""" 315 | return 0 316 | 317 | def ReqQryInvestorPosition(self, pQryInvestorPosition, nRequestID): 318 | """请求查询投资者持仓""" 319 | return 0 320 | 321 | def ReqQryTradingAccount(self, pQryTradingAccount, nRequestID): 322 | """请求查询资金账户""" 323 | return 0 324 | 325 | def ReqQryInvestor(self, pQryInvestor, nRequestID): 326 | """请求查询投资者""" 327 | return 0 328 | 329 | def ReqQryTradingCode(self, pQryTradingCode, nRequestID): 330 | """请求查询交易编码""" 331 | return 0 332 | 333 | def ReqQryInstrumentMarginRate(self, pQryInstrumentMarginRate, nRequestID): 334 | """请求查询合约保证金率""" 335 | return 0 336 | 337 | def ReqQryInstrumentCommissionRate(self, pQryInstrumentCommissionRate, nRequestID): 338 | """请求查询合约手续费率""" 339 | return 0 340 | 341 | def ReqQryExchange(self, pQryExchange, nRequestID): 342 | """请求查询交易所""" 343 | return 0 344 | 345 | def ReqQryProduct(self, pQryProduct, nRequestID): 346 | """请求查询产品""" 347 | return 0 348 | 349 | def ReqQryInstrument(self, pQryInstrument, nRequestID): 350 | """请求查询合约""" 351 | return 0 352 | 353 | def ReqQryDepthMarketData(self, pQryDepthMarketData, nRequestID): 354 | """请求查询行情""" 355 | return 0 356 | 357 | def ReqQrySettlementInfo(self, pQrySettlementInfo, nRequestID): 358 | """请求查询投资者结算结果""" 359 | return 0 360 | 361 | def ReqQryTransferBank(self, pQryTransferBank, nRequestID): 362 | """请求查询转帐银行""" 363 | return 0 364 | 365 | def ReqQryInvestorPositionDetail(self, pQryInvestorPositionDetail, nRequestID): 366 | """请求查询投资者持仓明细""" 367 | return 0 368 | 369 | def ReqQryNotice(self, pQryNotice, nRequestID): 370 | """请求查询客户通知""" 371 | return 0 372 | 373 | def ReqQrySettlementInfoConfirm(self, pQrySettlementInfoConfirm, nRequestID): 374 | """请求查询结算信息确认""" 375 | return 0 376 | 377 | def ReqQryInvestorPositionCombineDetail(self, pQryInvestorPositionCombineDetail, nRequestID): 378 | """请求查询投资者持仓明细""" 379 | return 0 380 | 381 | def ReqQryCFMMCTradingAccountKey(self, pQryCFMMCTradingAccountKey, nRequestID): 382 | """请求查询保证金监管系统经纪公司资金账户密钥""" 383 | return 0 384 | 385 | def ReqQryEWarrantOffset(self, pQryEWarrantOffset, nRequestID): 386 | """请求查询仓单折抵信息""" 387 | return 0 388 | 389 | def ReqQryInvestorProductGroupMargin(self, pQryInvestorProductGroupMargin, nRequestID): 390 | """请求查询投资者品种/跨品种保证金""" 391 | return 0 392 | 393 | def ReqQryExchangeMarginRate(self, pQryExchangeMarginRate, nRequestID): 394 | """请求查询交易所保证金率""" 395 | return 0 396 | 397 | def ReqQryExchangeMarginRateAdjust(self, pQryExchangeMarginRateAdjust, nRequestID): 398 | """请求查询交易所调整保证金率""" 399 | return 0 400 | 401 | def ReqQryExchangeRate(self, pQryExchangeRate, nRequestID): 402 | """请求查询汇率""" 403 | return 0 404 | 405 | def ReqQrySecAgentACIDMap(self, pQrySecAgentACIDMap, nRequestID): 406 | """请求查询二级代理操作员银期权限""" 407 | return 0 408 | 409 | def ReqQryProductExchRate(self, pQryProductExchRate, nRequestID): 410 | """请求查询产品报价汇率""" 411 | return 0 412 | 413 | def ReqQryOptionInstrTradeCost(self, pQryOptionInstrTradeCost, nRequestID): 414 | """请求查询期权交易成本""" 415 | return 0 416 | 417 | def ReqQryOptionInstrCommRate(self, pQryOptionInstrCommRate, nRequestID): 418 | """请求查询期权合约手续费""" 419 | return 0 420 | 421 | def ReqQryExecOrder(self, pQryExecOrder, nRequestID): 422 | """请求查询执行宣告""" 423 | return 0 424 | 425 | def ReqQryForQuote(self, pQryForQuote, nRequestID): 426 | """请求查询询价""" 427 | return 0 428 | 429 | def ReqQryQuote(self, pQryQuote, nRequestID): 430 | """请求查询报价""" 431 | return 0 432 | 433 | def ReqQryCombInstrumentGuard(self, pQryCombInstrumentGuard, nRequestID): 434 | """请求查询组合合约安全系数""" 435 | return 0 436 | 437 | def ReqQryCombAction(self, pQryCombAction, nRequestID): 438 | """请求查询申请组合""" 439 | return 0 440 | 441 | def ReqQryTransferSerial(self, pQryTransferSerial, nRequestID): 442 | """请求查询转帐流水""" 443 | return 0 444 | 445 | def ReqQryAccountregister(self, pQryAccountregister, nRequestID): 446 | """请求查询银期签约关系""" 447 | return 0 448 | 449 | def ReqQryContractBank(self, pQryContractBank, nRequestID): 450 | """请求查询签约银行""" 451 | return 0 452 | 453 | def ReqQryParkedOrder(self, pQryParkedOrder, nRequestID): 454 | """请求查询预埋单""" 455 | return 0 456 | 457 | def ReqQryParkedOrderAction(self, pQryParkedOrderAction, nRequestID): 458 | """请求查询预埋撤单""" 459 | return 0 460 | 461 | def ReqQryTradingNotice(self, pQryTradingNotice, nRequestID): 462 | """请求查询交易通知""" 463 | return 0 464 | 465 | def ReqQryBrokerTradingParams(self, pQryBrokerTradingParams, nRequestID): 466 | """请求查询经纪公司交易参数""" 467 | return 0 468 | 469 | def ReqQryBrokerTradingAlgos(self, pQryBrokerTradingAlgos, nRequestID): 470 | """请求查询经纪公司交易算法""" 471 | return 0 472 | 473 | def ReqQueryCFMMCTradingAccountToken(self, pQueryCFMMCTradingAccountToken, nRequestID): 474 | """请求查询监控中心用户令牌""" 475 | return 0 476 | 477 | def ReqFromBankToFutureByFuture(self, pReqTransfer, nRequestID): 478 | """期货发起银行资金转期货请求""" 479 | return 0 480 | 481 | def ReqFromFutureToBankByFuture(self, pReqTransfer, nRequestID): 482 | """期货发起期货资金转银行请求""" 483 | return 0 484 | 485 | def ReqQueryBankAccountMoneyByFuture(self, pReqQueryAccount, nRequestID): 486 | """期货发起查询银行余额请求""" 487 | return 0 488 | 489 | def OnFrontConnected(self): 490 | """当客户端与交易后台建立起通信连接时(还未登录前),该方法被调用。""" 491 | 492 | def OnFrontDisconnected(self, nReason): 493 | """当客户端与交易后台通信连接断开时,该方法被调用。当发生这个情况后,API会自动重新连接,客户端可不做处理。 494 | @param nReason 错误原因 495 | 0x1001 网络读失败 496 | 0x1002 网络写失败 497 | 0x2001 接收心跳超时 498 | 0x2002 发送心跳失败 499 | 0x2003 收到错误报文 500 | """ 501 | 502 | def OnHeartBeatWarning(self, nTimeLapse): 503 | """心跳超时警告。当长时间未收到报文时,该方法被调用。 504 | @param nTimeLapse 距离上次接收报文的时间 505 | """ 506 | 507 | def OnRspAuthenticate(self, pRspAuthenticate, pRspInfo, nRequestID, bIsLast): 508 | """客户端认证响应""" 509 | 510 | def OnRspUserLogin(self, pRspUserLogin, pRspInfo, nRequestID, bIsLast): 511 | """登录请求响应""" 512 | 513 | def OnRspUserLogout(self, pUserLogout, pRspInfo, nRequestID, bIsLast): 514 | """登出请求响应""" 515 | 516 | def OnRspUserPasswordUpdate(self, pUserPasswordUpdate, pRspInfo, nRequestID, bIsLast): 517 | """用户口令更新请求响应""" 518 | 519 | def OnRspTradingAccountPasswordUpdate(self, pTradingAccountPasswordUpdate, pRspInfo, nRequestID, bIsLast): 520 | """资金账户口令更新请求响应""" 521 | 522 | def OnRspOrderInsert(self, pInputOrder, pRspInfo, nRequestID, bIsLast): 523 | """报单录入请求响应""" 524 | 525 | def OnRspParkedOrderInsert(self, pParkedOrder, pRspInfo, nRequestID, bIsLast): 526 | """预埋单录入请求响应""" 527 | 528 | def OnRspParkedOrderAction(self, pParkedOrderAction, pRspInfo, nRequestID, bIsLast): 529 | """预埋撤单录入请求响应""" 530 | 531 | def OnRspOrderAction(self, pInputOrderAction, pRspInfo, nRequestID, bIsLast): 532 | """报单操作请求响应""" 533 | 534 | def OnRspQueryMaxOrderVolume(self, pQueryMaxOrderVolume, pRspInfo, nRequestID, bIsLast): 535 | """查询最大报单数量响应""" 536 | 537 | def OnRspSettlementInfoConfirm(self, pSettlementInfoConfirm, pRspInfo, nRequestID, bIsLast): 538 | """投资者结算结果确认响应""" 539 | 540 | def OnRspRemoveParkedOrder(self, pRemoveParkedOrder, pRspInfo, nRequestID, bIsLast): 541 | """删除预埋单响应""" 542 | 543 | def OnRspRemoveParkedOrderAction(self, pRemoveParkedOrderAction, pRspInfo, nRequestID, bIsLast): 544 | """删除预埋撤单响应""" 545 | 546 | def OnRspExecOrderInsert(self, pInputExecOrder, pRspInfo, nRequestID, bIsLast): 547 | """执行宣告录入请求响应""" 548 | 549 | def OnRspExecOrderAction(self, pInputExecOrderAction, pRspInfo, nRequestID, bIsLast): 550 | """执行宣告操作请求响应""" 551 | 552 | def OnRspForQuoteInsert(self, pInputForQuote, pRspInfo, nRequestID, bIsLast): 553 | """询价录入请求响应""" 554 | 555 | def OnRspQuoteInsert(self, pInputQuote, pRspInfo, nRequestID, bIsLast): 556 | """报价录入请求响应""" 557 | 558 | def OnRspQuoteAction(self, pInputQuoteAction, pRspInfo, nRequestID, bIsLast): 559 | """报价操作请求响应""" 560 | 561 | def OnRspCombActionInsert(self, pInputCombAction, pRspInfo, nRequestID, bIsLast): 562 | """申请组合录入请求响应""" 563 | 564 | def OnRspQryOrder(self, pOrder, pRspInfo, nRequestID, bIsLast): 565 | """请求查询报单响应""" 566 | 567 | def OnRspQryTrade(self, pTrade, pRspInfo, nRequestID, bIsLast): 568 | """请求查询成交响应""" 569 | 570 | def OnRspQryInvestorPosition(self, pInvestorPosition, pRspInfo, nRequestID, bIsLast): 571 | """请求查询投资者持仓响应""" 572 | 573 | def OnRspQryTradingAccount(self, pTradingAccount, pRspInfo, nRequestID, bIsLast): 574 | """请求查询资金账户响应""" 575 | 576 | def OnRspQryInvestor(self, pInvestor, pRspInfo, nRequestID, bIsLast): 577 | """请求查询投资者响应""" 578 | 579 | def OnRspQryTradingCode(self, pTradingCode, pRspInfo, nRequestID, bIsLast): 580 | """请求查询交易编码响应""" 581 | 582 | def OnRspQryInstrumentMarginRate(self, pInstrumentMarginRate, pRspInfo, nRequestID, bIsLast): 583 | """请求查询合约保证金率响应""" 584 | 585 | def OnRspQryInstrumentCommissionRate(self, pInstrumentCommissionRate, pRspInfo, nRequestID, bIsLast): 586 | """请求查询合约手续费率响应""" 587 | 588 | def OnRspQryExchange(self, pExchange, pRspInfo, nRequestID, bIsLast): 589 | """请求查询交易所响应""" 590 | 591 | def OnRspQryProduct(self, pProduct, pRspInfo, nRequestID, bIsLast): 592 | """请求查询产品响应""" 593 | 594 | def OnRspQryInstrument(self, pInstrument, pRspInfo, nRequestID, bIsLast): 595 | """请求查询合约响应""" 596 | 597 | def OnRspQryDepthMarketData(self, pDepthMarketData, pRspInfo, nRequestID, bIsLast): 598 | """请求查询行情响应""" 599 | 600 | def OnRspQrySettlementInfo(self, pSettlementInfo, pRspInfo, nRequestID, bIsLast): 601 | """请求查询投资者结算结果响应""" 602 | 603 | def OnRspQryTransferBank(self, pTransferBank, pRspInfo, nRequestID, bIsLast): 604 | """请求查询转帐银行响应""" 605 | 606 | def OnRspQryInvestorPositionDetail(self, pInvestorPositionDetail, pRspInfo, nRequestID, bIsLast): 607 | """请求查询投资者持仓明细响应""" 608 | 609 | def OnRspQryNotice(self, pNotice, pRspInfo, nRequestID, bIsLast): 610 | """请求查询客户通知响应""" 611 | 612 | def OnRspQrySettlementInfoConfirm(self, pSettlementInfoConfirm, pRspInfo, nRequestID, bIsLast): 613 | """请求查询结算信息确认响应""" 614 | 615 | def OnRspQryInvestorPositionCombineDetail(self, pInvestorPositionCombineDetail, pRspInfo, nRequestID, bIsLast): 616 | """请求查询投资者持仓明细响应""" 617 | 618 | def OnRspQryCFMMCTradingAccountKey(self, pCFMMCTradingAccountKey, pRspInfo, nRequestID, bIsLast): 619 | """查询保证金监管系统经纪公司资金账户密钥响应""" 620 | 621 | def OnRspQryEWarrantOffset(self, pEWarrantOffset, pRspInfo, nRequestID, bIsLast): 622 | """请求查询仓单折抵信息响应""" 623 | 624 | def OnRspQryInvestorProductGroupMargin(self, pInvestorProductGroupMargin, pRspInfo, nRequestID, bIsLast): 625 | """请求查询投资者品种/跨品种保证金响应""" 626 | 627 | def OnRspQryExchangeMarginRate(self, pExchangeMarginRate, pRspInfo, nRequestID, bIsLast): 628 | """请求查询交易所保证金率响应""" 629 | 630 | def OnRspQryExchangeMarginRateAdjust(self, pExchangeMarginRateAdjust, pRspInfo, nRequestID, bIsLast): 631 | """请求查询交易所调整保证金率响应""" 632 | 633 | def OnRspQryExchangeRate(self, pExchangeRate, pRspInfo, nRequestID, bIsLast): 634 | """请求查询汇率响应""" 635 | 636 | def OnRspQrySecAgentACIDMap(self, pSecAgentACIDMap, pRspInfo, nRequestID, bIsLast): 637 | """请求查询二级代理操作员银期权限响应""" 638 | 639 | def OnRspQryProductExchRate(self, pProductExchRate, pRspInfo, nRequestID, bIsLast): 640 | """请求查询产品报价汇率""" 641 | 642 | def OnRspQryOptionInstrTradeCost(self, pOptionInstrTradeCost, pRspInfo, nRequestID, bIsLast): 643 | """请求查询期权交易成本响应""" 644 | 645 | def OnRspQryOptionInstrCommRate(self, pOptionInstrCommRate, pRspInfo, nRequestID, bIsLast): 646 | """请求查询期权合约手续费响应""" 647 | 648 | def OnRspQryExecOrder(self, pExecOrder, pRspInfo, nRequestID, bIsLast): 649 | """请求查询执行宣告响应""" 650 | 651 | def OnRspQryForQuote(self, pForQuote, pRspInfo, nRequestID, bIsLast): 652 | """请求查询询价响应""" 653 | 654 | def OnRspQryQuote(self, pQuote, pRspInfo, nRequestID, bIsLast): 655 | """请求查询报价响应""" 656 | 657 | def OnRspQryCombInstrumentGuard(self, pCombInstrumentGuard, pRspInfo, nRequestID, bIsLast): 658 | """请求查询组合合约安全系数响应""" 659 | 660 | def OnRspQryCombAction(self, pCombAction, pRspInfo, nRequestID, bIsLast): 661 | """请求查询申请组合响应""" 662 | 663 | def OnRspQryTransferSerial(self, pTransferSerial, pRspInfo, nRequestID, bIsLast): 664 | """请求查询转帐流水响应""" 665 | 666 | def OnRspQryAccountregister(self, pAccountregister, pRspInfo, nRequestID, bIsLast): 667 | """请求查询银期签约关系响应""" 668 | 669 | def OnRspError(self, pRspInfo, nRequestID, bIsLast): 670 | """错误应答""" 671 | 672 | def OnRtnOrder(self, pOrder): 673 | """报单通知""" 674 | 675 | def OnRtnTrade(self, pTrade): 676 | """成交通知""" 677 | 678 | def OnErrRtnOrderInsert(self, pInputOrder, pRspInfo): 679 | """报单录入错误回报""" 680 | 681 | def OnErrRtnOrderAction(self, pOrderAction, pRspInfo): 682 | """报单操作错误回报""" 683 | 684 | def OnRtnInstrumentStatus(self, pInstrumentStatus): 685 | """合约交易状态通知""" 686 | 687 | def OnRtnTradingNotice(self, pTradingNoticeInfo): 688 | """交易通知""" 689 | 690 | def OnRtnErrorConditionalOrder(self, pErrorConditionalOrder): 691 | """提示条件单校验错误""" 692 | 693 | def OnRtnExecOrder(self, pExecOrder): 694 | """执行宣告通知""" 695 | 696 | def OnErrRtnExecOrderInsert(self, pInputExecOrder, pRspInfo): 697 | """执行宣告录入错误回报""" 698 | 699 | def OnErrRtnExecOrderAction(self, pExecOrderAction, pRspInfo): 700 | """执行宣告操作错误回报""" 701 | 702 | def OnErrRtnForQuoteInsert(self, pInputForQuote, pRspInfo): 703 | """询价录入错误回报""" 704 | 705 | def OnRtnQuote(self, pQuote): 706 | """报价通知""" 707 | 708 | def OnErrRtnQuoteInsert(self, pInputQuote, pRspInfo): 709 | """报价录入错误回报""" 710 | 711 | def OnErrRtnQuoteAction(self, pQuoteAction, pRspInfo): 712 | """报价操作错误回报""" 713 | 714 | def OnRtnForQuoteRsp(self, pForQuoteRsp): 715 | """询价通知""" 716 | 717 | def OnRtnCFMMCTradingAccountToken(self, pCFMMCTradingAccountToken): 718 | """保证金监控中心用户令牌""" 719 | 720 | def OnRtnCombAction(self, pCombAction): 721 | """申请组合通知""" 722 | 723 | def OnErrRtnCombActionInsert(self, pInputCombAction, pRspInfo): 724 | """申请组合录入错误回报""" 725 | 726 | def OnRspQryContractBank(self, pContractBank, pRspInfo, nRequestID, bIsLast): 727 | """请求查询签约银行响应""" 728 | 729 | def OnRspQryParkedOrder(self, pParkedOrder, pRspInfo, nRequestID, bIsLast): 730 | """请求查询预埋单响应""" 731 | 732 | def OnRspQryParkedOrderAction(self, pParkedOrderAction, pRspInfo, nRequestID, bIsLast): 733 | """请求查询预埋撤单响应""" 734 | 735 | def OnRspQryTradingNotice(self, pTradingNotice, pRspInfo, nRequestID, bIsLast): 736 | """请求查询交易通知响应""" 737 | 738 | def OnRspQryBrokerTradingParams(self, pBrokerTradingParams, pRspInfo, nRequestID, bIsLast): 739 | """请求查询经纪公司交易参数响应""" 740 | 741 | def OnRspQryBrokerTradingAlgos(self, pBrokerTradingAlgos, pRspInfo, nRequestID, bIsLast): 742 | """请求查询经纪公司交易算法响应""" 743 | 744 | def OnRspQueryCFMMCTradingAccountToken(self, pQueryCFMMCTradingAccountToken, pRspInfo, nRequestID, bIsLast): 745 | """请求查询监控中心用户令牌""" 746 | 747 | def OnRtnFromBankToFutureByBank(self, pRspTransfer): 748 | """银行发起银行资金转期货通知""" 749 | 750 | def OnRtnFromFutureToBankByBank(self, pRspTransfer): 751 | """银行发起期货资金转银行通知""" 752 | 753 | def OnRtnRepealFromBankToFutureByBank(self, pRspRepeal): 754 | """银行发起冲正银行转期货通知""" 755 | 756 | def OnRtnRepealFromFutureToBankByBank(self, pRspRepeal): 757 | """银行发起冲正期货转银行通知""" 758 | 759 | def OnRtnFromBankToFutureByFuture(self, pRspTransfer): 760 | """期货发起银行资金转期货通知""" 761 | 762 | def OnRtnFromFutureToBankByFuture(self, pRspTransfer): 763 | """期货发起期货资金转银行通知""" 764 | 765 | def OnRtnRepealFromBankToFutureByFutureManual(self, pRspRepeal): 766 | """系统运行时期货端手工发起冲正银行转期货请求,银行处理完毕后报盘发回的通知""" 767 | 768 | def OnRtnRepealFromFutureToBankByFutureManual(self, pRspRepeal): 769 | """系统运行时期货端手工发起冲正期货转银行请求,银行处理完毕后报盘发回的通知""" 770 | 771 | def OnRtnQueryBankBalanceByFuture(self, pNotifyQueryAccount): 772 | """期货发起查询银行余额通知""" 773 | 774 | def OnErrRtnBankToFutureByFuture(self, pReqTransfer, pRspInfo): 775 | """期货发起银行资金转期货错误回报""" 776 | 777 | def OnErrRtnFutureToBankByFuture(self, pReqTransfer, pRspInfo): 778 | """期货发起期货资金转银行错误回报""" 779 | 780 | def OnErrRtnRepealBankToFutureByFutureManual(self, pReqRepeal, pRspInfo): 781 | """系统运行时期货端手工发起冲正银行转期货错误回报""" 782 | 783 | def OnErrRtnRepealFutureToBankByFutureManual(self, pReqRepeal, pRspInfo): 784 | """系统运行时期货端手工发起冲正期货转银行错误回报""" 785 | 786 | def OnErrRtnQueryBankBalanceByFuture(self, pReqQueryAccount, pRspInfo): 787 | """期货发起查询银行余额错误回报""" 788 | 789 | def OnRtnRepealFromBankToFutureByFuture(self, pRspRepeal): 790 | """期货发起冲正银行转期货请求,银行处理完毕后报盘发回的通知""" 791 | 792 | def OnRtnRepealFromFutureToBankByFuture(self, pRspRepeal): 793 | """期货发起冲正期货转银行请求,银行处理完毕后报盘发回的通知""" 794 | 795 | def OnRspFromBankToFutureByFuture(self, pReqTransfer, pRspInfo, nRequestID, bIsLast): 796 | """期货发起银行资金转期货应答""" 797 | 798 | def OnRspFromFutureToBankByFuture(self, pReqTransfer, pRspInfo, nRequestID, bIsLast): 799 | """期货发起期货资金转银行应答""" 800 | 801 | def OnRspQueryBankAccountMoneyByFuture(self, pReqQueryAccount, pRspInfo, nRequestID, bIsLast): 802 | """期货发起查询银行余额应答""" 803 | 804 | def OnRtnOpenAccountByBank(self, pOpenAccount): 805 | """银行发起银期开户通知""" 806 | 807 | def OnRtnCancelAccountByBank(self, pCancelAccount): 808 | """银行发起银期销户通知""" 809 | 810 | def OnRtnChangeAccountByBank(self, pChangeAccount): 811 | """银行发起变更银行账号通知""" 812 | 813 | 814 | def _init(Module, MdSpi, TraderSpi): 815 | globals()['ApiStruct'] = __import__(__name__+'.ApiStruct', None, None, 'x') 816 | 817 | class LazyProperty(object): 818 | def __get__(self, obj, cls): 819 | if obj is None: return self 820 | value = self.fget() 821 | name = self.fget.__name__ 822 | setattr(obj, name, value) 823 | delattr(cls, name) 824 | return value 825 | 826 | def lazy_property(func): 827 | self = LazyProperty() 828 | setattr(Module, func.__name__, self) 829 | self.fget = func 830 | return self 831 | 832 | @lazy_property 833 | def MdApi(): 834 | from ._MdApi import _init, MdApi; _init(ApiStruct) 835 | return type('MdApi', (MdApi,), MdSpi) 836 | 837 | @lazy_property 838 | def TraderApi(): 839 | from ._TraderApi import _init, TraderApi; _init(ApiStruct) 840 | return type('TraderApi', (TraderApi,), TraderSpi) 841 | 842 | 843 | def _init(init=_init, MdSpi=MdApi, TraderSpi=TraderApi): 844 | import sys 845 | from types import ModuleType, FunctionType as F 846 | 847 | f = (lambda f:F(f.__code__,env)) if sys.version_info[0] >= 3 else (lambda f:F(f.func_code,env)) 848 | mod = sys.modules[__name__]; Module = type(mod) 849 | if Module is ModuleType: 850 | class Module(ModuleType): pass 851 | mod = Module(__name__); env = mod.__dict__ 852 | env.update((k,v) for k,v in globals().items() if k.startswith('__') and k.endswith('__')) 853 | MdSpi = dict((k,f(v)) for k,v in MdSpi.__dict__.items() if k.startswith('On')) 854 | TraderSpi = dict((k,f(v)) for k,v in TraderSpi.__dict__.items() if k.startswith('On')) 855 | sys.modules[__name__] = mod 856 | else: 857 | env = mod.__dict__ 858 | for k in ('MdApi','TraderApi','_init'): del env[k] 859 | MdSpi = dict((k,v) for k,v in MdSpi.__dict__.items() if k.startswith('On')) 860 | TraderSpi = dict((k,v) for k,v in TraderSpi.__dict__.items() if k.startswith('On')) 861 | 862 | f(init)(Module, MdSpi, TraderSpi) 863 | _init() 864 | -------------------------------------------------------------------------------- /wolfquant/interface/future/libthostmduserapi.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/wolfquant/interface/future/libthostmduserapi.so -------------------------------------------------------------------------------- /wolfquant/interface/future/libthosttraderapi.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/wolfquant/interface/future/libthosttraderapi.so -------------------------------------------------------------------------------- /wolfquant/portfolio.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | from wolfquant.event import OrderEvent 3 | from abc import ABCMeta, abstractmethod 4 | from wolfquant.utils.backtest_utils import create_sharpe_ratio, create_drawdowns 5 | 6 | 7 | class Portfolio(object): 8 | __mateclass__ = ABCMeta 9 | 10 | @abstractmethod 11 | def update_signal(self, event): 12 | raise NotImplementedError("Should implement update_signal()") 13 | 14 | @abstractmethod 15 | def update_fill(self, event): 16 | raise NotImplementedError("Should implement update_fill()") 17 | 18 | 19 | class NaivePortfolio(Portfolio): 20 | """ 21 | Portfolio类包含所有资产的的仓位和市值。 22 | positions DataFrame存储着仓位数量的时间序列。 23 | holdings DataFrame存储现金和各个资产的市值,以及变化。 24 | """ 25 | def __init__(self, bars, events, start_date, initial_capital=100000.0): 26 | """ 27 | 初始化bars、时间队列、初始资本。 28 | 29 | Parameters: 30 | bars - The DataHandler object with current market data. 31 | events - The Event Queue object. 32 | start_date - The start date (bar) of the portfolio. 33 | initial_capital - The starting capital in USD. 34 | """ 35 | self.bars = bars 36 | self.events = events 37 | self.symbol_list = self.bars.symbol_list 38 | self.start_date = start_date 39 | self.initial_capital = initial_capital 40 | 41 | self.all_positions = self.construct_all_positions() 42 | self.current_positions = dict((k, v) for k, v in [(s, 0) for s in self.symbol_list]) 43 | self.all_holdings = self.construct_all_holdings() 44 | self.current_holdings = self.construct_current_holdings() 45 | 46 | def construct_all_positions(self): 47 | """ 48 | 构造仓位 49 | """ 50 | d = dict((k, v) for k, v in [(s, 0) for s in self.symbol_list]) 51 | d['datetime'] = self.start_date 52 | return [d] 53 | 54 | def construct_all_holdings(self): 55 | """ 56 | 构造持有资产 57 | """ 58 | d = dict((k, v) for k, v in [(s, 0.0) for s in self.symbol_list]) 59 | d['datetime'] = self.start_date 60 | d['cash'] = self.initial_capital # 现金 61 | d['commission'] = 0.0 # 佣金 62 | d['total'] = self.initial_capital 63 | return [d] 64 | 65 | def construct_current_holdings(self): 66 | """ 67 | This constructs the dictionary which will hold the instantaneous 68 | value of the portfolio across all symbols. 69 | """ 70 | d = dict((k, v) for k, v in [(s, 0.0) for s in self.symbol_list]) 71 | d['cash'] = self.initial_capital 72 | d['commission'] = 0.0 73 | d['total'] = self.initial_capital 74 | return d 75 | 76 | def update_timeindex(self, event): 77 | """Adds a new record to the positions matrix for the current 78 | market data bar. This reflects the PREVIOUS bar, i.e. all 79 | current market data at this stage is known (OHLCV). 80 | Makes use of a MarketEvent from the events queue. 81 | """ 82 | latest_datetime = self.bars.get_latest_bar_datetime(self.symbol_list[0]) 83 | 84 | # 更新仓位 85 | dp = dict((k, v) for k, v in [(s, 0) for s in self.symbol_list]) 86 | dp['datetime'] = latest_datetime 87 | 88 | for s in self.symbol_list: 89 | dp[s] = self.current_positions[s] 90 | 91 | # 添加当前仓位 92 | self.all_positions.append(dp) 93 | 94 | # 更新持仓 95 | dh = dict((k, v) for k, v in [(s, 0) for s in self.symbol_list]) 96 | dh['datetime'] = latest_datetime 97 | dh['cash'] = self.current_holdings['cash'] 98 | dh['commission'] = self.current_holdings['commission'] 99 | dh['total'] = self.current_holdings['cash'] 100 | 101 | for s in self.symbol_list: 102 | # Approximation to the real value? 103 | market_value = self.current_positions[s] * self.bars.get_latest_bars(s)[0][3] 104 | dh[s] = market_value 105 | dh['total'] += market_value 106 | 107 | # 添加当前持仓 108 | self.all_holdings.append(dh) 109 | 110 | # ====================== 111 | # FILL/POSITION HANDLING 112 | # ====================== 113 | def update_positions_from_fill(self, fill): 114 | """根据成交单更新仓位 115 | """ 116 | fill_dir = 0 117 | if fill.direction == 'BUY': 118 | fill_dir = 1 119 | if fill.direction == 'SELL': 120 | fill_dir = -1 121 | 122 | self.current_positions[fill.symbol] += fill_dir * fill.quantity 123 | 124 | def update_holdings_from_fill(self, fill): 125 | """Takes a Fill object and updates the holdings matrix to 126 | reflect the holdings value. 127 | 128 | Parameters: 129 | fill - The Fill object to update the holdings with. 130 | """ 131 | # 检查下单时买还是卖 132 | fill_dir = 0 133 | if fill.direction == 'BUY': 134 | fill_dir = 1 135 | if fill.direction == 'SELL': 136 | fill_dir = -1 137 | 138 | # 更新持仓列表 139 | fill_cost = self.bars.get_latest_bars(fill.symbol)[0][3] 140 | cost = fill_dir * fill_cost * fill.quantity 141 | self.current_holdings[fill.symbol] += cost 142 | self.current_holdings['commission'] += fill.commission 143 | self.current_holdings['cash'] -= (cost + fill.commission) 144 | self.current_holdings['total'] -= (cost + fill.commission) 145 | 146 | def update_fill(self, event): 147 | """下单后,更新仓位和持仓情况 148 | """ 149 | if event.type == 'FILL': 150 | self.update_positions_from_fill(event) 151 | self.update_holdings_from_fill(event) 152 | 153 | def generate_naive_order(self, signal): 154 | """ 155 | Simply files an Order object as a constant quantity 156 | sizing of the signal object, without risk management or 157 | position sizing considerations. 158 | 159 | Parameters: 160 | signal - The tuple containing Signal information. 161 | quantity - 生成订单 162 | """ 163 | order = None 164 | 165 | symbol = signal.symbol 166 | direction = signal.signal_type 167 | # 确定下单数 168 | mkt_quantity = signal.quantity 169 | cur_quantity = self.current_positions[symbol] 170 | order_type = signal.order_type 171 | if direction == 'LONG': 172 | order = OrderEvent(symbol, order_type, mkt_quantity, 'BUY') 173 | 174 | if direction == 'SHORT': 175 | order = OrderEvent(symbol, order_type, mkt_quantity, 'SELL') 176 | 177 | if direction == 'EXIT' and cur_quantity > 0: 178 | order = OrderEvent(symbol, order_type, abs(cur_quantity), 'SELL') 179 | if direction == 'EXIT' and cur_quantity < 0: 180 | order = OrderEvent(symbol, order_type, abs(cur_quantity), 'BUY') 181 | return order 182 | 183 | def update_signal(self, event): 184 | """根据交易信号生成订单 185 | """ 186 | if event.type == 'SIGNAL': 187 | order_event = self.generate_naive_order(event) 188 | self.events.put(order_event) 189 | 190 | # ======================== 191 | # POST-BACKTEST STATISTICS 192 | # ======================== 193 | def create_equity_curve_dataframe(self): 194 | """Creates a pandas DataFrame from the all_holdings 195 | list of dictionaries. 196 | """ 197 | curve = pd.DataFrame(self.all_holdings) 198 | curve.set_index('datetime', inplace=True) 199 | curve['returns'] = curve['total'].pct_change() 200 | curve['equity_curve'] = (1.0 + curve['returns']).cumprod() 201 | self.equity_curve = curve 202 | 203 | def output_summary_stats(self): 204 | """创建投资组合的一个统计总结 205 | """ 206 | import matplotlib.pyplot as plt 207 | total_return = self.equity_curve['equity_curve'][-1] 208 | returns = self.equity_curve['returns'] 209 | pnl = self.equity_curve['equity_curve'] 210 | sharpe_ratio = create_sharpe_ratio(returns) 211 | max_dd, dd_duration = create_drawdowns(pnl) 212 | stats = [("Total Return", "%0.2f%%" % ((total_return - 1.0) * 100.0)), 213 | ("Sharpe Ratio", "%0.2f" % sharpe_ratio), 214 | ("Max Drawdown", "%0.2f%%" % (max_dd * 100.0)), 215 | ("Drawdown Duration", "%d" % dd_duration)] 216 | plt.clf() 217 | plt.plot(self.equity_curve.index, pnl) 218 | plt.savefig('output/cumulative_return') 219 | self.equity_curve.to_csv('output/equity.csv') 220 | return stats 221 | -------------------------------------------------------------------------------- /wolfquant/strategy.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from abc import ABCMeta, abstractmethod 3 | from wolfquant.event import SignalEvent, OrderEvent 4 | 5 | 6 | class Strategy(object): 7 | _metaclass_ = ABCMeta 8 | 9 | def __init__(self, bars, events, portfolio): 10 | self.strategy_id = 1 11 | self.bars = bars 12 | self.event = events 13 | self.portfolio = portfolio 14 | self.symbol_list = self.bars.symbol_list 15 | self.init() 16 | 17 | @abstractmethod 18 | def init(self): 19 | raise NotImplementedError("Should implement init()") 20 | 21 | @abstractmethod 22 | def handle_bar(self): 23 | raise NotImplementedError("Should implement handle_bar()") 24 | 25 | ################################################### 26 | # 一些成交方法 27 | ################################################### 28 | def order_shares(self, symbol, amount, style='MKT'): 29 | """按照数量下单 30 | args: 31 | symbol: 股票代码 32 | amount: 下单数量 33 | style: 下单方式 34 | """ 35 | if self.checkout_tradeable(symbol): 36 | direction = 'LONG' if amount > 0 else 'SHORT' 37 | cost = self.bars.get_latest_bars(symbol)[0][3] 38 | cash = self.portfolio.current_holdings['cash'] 39 | current_holding = self.portfolio.current_holdings[symbol] 40 | dt = self.bars.get_latest_bar_datetime(symbol) 41 | target_value = cost * amount 42 | if target_value > cash: 43 | print("【订单信息】{}-因资金不足未创建订单".format(dt)) 44 | elif target_value <= cash and target_value + current_holding > 0: 45 | signal = SignalEvent(self.strategy_id, symbol, dt, direction, amount, style) 46 | self.event.put(signal) 47 | print("【订单信息】{}-{}-{}-{}-{}".format(dt, direction, symbol, abs(amount), cost)) 48 | elif target_value + current_holding < 0: 49 | self.clear_position(symbol, style=style) 50 | print("【订单信息】{}-订单金额超过所持有股票市值,对该股票进行清仓".format(dt)) 51 | else: 52 | print("【订单信息】{}-{}-{}-{}未成交".format(dt, direction, symbol, amount)) 53 | 54 | def clear_position(self, symbol, style='MKT'): 55 | """清空仓位 56 | """ 57 | dt = self.bars.get_latest_bar_datetime(symbol) 58 | signal = SignalEvent(self.strategy_id, symbol, dt, 'EXIT', None, style) 59 | self.event.put(signal) 60 | 61 | def order_value(self, symbol, value, style='MKT'): 62 | """按照资金下单 63 | """ 64 | if self.checkout_tradeable(symbol): 65 | cost = self.bars.get_latest_bars(symbol)[0][3] 66 | target_amount = np.int(value // cost) # 获取目标数量 67 | self.order_shares(symbol, target_amount) # 下订单 68 | 69 | def order_percent(self, symbol, percent, style='MKT'): 70 | """按照一定的百分比进行下单 71 | """ 72 | if self.checkout_tradeable(symbol): 73 | # 判断仓位是否是小于1 74 | if percent < 0 or percent > 1: 75 | raise ValueError("percent should between 0 and 1") 76 | target_value = self.portfolio.current_holdings['total'] * percent 77 | self.order_value(symbol, target_value, style=style) 78 | 79 | def order_target_percent(self, symbol, percent, style='MKT'): 80 | """按照目标仓位下单 81 | """ 82 | if self.checkout_tradeable(symbol): 83 | # 判断仓位是否是小于1 84 | if percent < 0 or percent > 1: 85 | raise ValueError("percent should between 0 and 1") 86 | 87 | current_percent = self.portfolio.current_holdings[symbol] / self.portfolio.current_holdings['total'] 88 | target_percent = percent - current_percent 89 | self.order_percent(symbol, target_percent, style=style) 90 | 91 | def checkout_tradeable(self, symbol): 92 | """检查一下当前的股票是否可以成交 93 | """ 94 | bar = self.bars.get_latest_bars(symbol) 95 | if bar is not None and bar != []: 96 | return True 97 | else: 98 | return False 99 | -------------------------------------------------------------------------------- /wolfquant/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rickyall/wolfquant/7528510d31b4eec0ea912982be4a43e198ce20fd/wolfquant/utils/__init__.py -------------------------------------------------------------------------------- /wolfquant/utils/api_utils.py: -------------------------------------------------------------------------------- 1 | def str2bytes(obj, encoding='utf8'): 2 | if isinstance(obj, str): 3 | return obj.encode(encoding) 4 | else: 5 | return obj 6 | 7 | 8 | def bytes2str(obj, encoding='utf8'): 9 | if isinstance(obj, bytes): 10 | return obj.decode(encoding) 11 | else: 12 | return obj 13 | 14 | 15 | def make_order_book_id(symbol): 16 | symbol = bytes2str(symbol) 17 | if len(symbol) < 4: 18 | return None 19 | if symbol[-4] not in '0123456789': 20 | order_book_id = symbol[:2] + '1' + symbol[-3:] 21 | else: 22 | order_book_id = symbol 23 | return order_book_id.upper() 24 | -------------------------------------------------------------------------------- /wolfquant/utils/backtest_utils.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | 4 | 5 | def create_sharpe_ratio(returns, periods=252): 6 | """夏普比率 7 | """ 8 | if np.std(returns) == 0: 9 | return 0. 10 | else: 11 | return np.sqrt(periods) * np.mean(returns) / np.std(returns) 12 | 13 | 14 | def create_drawdowns(equity_curve): 15 | """最大回撤 16 | """ 17 | hwm = [0] 18 | eq_idx = equity_curve.index 19 | drawdown = pd.Series(index=eq_idx) 20 | duration = pd.Series(index=eq_idx) 21 | 22 | for t in range(1, len(eq_idx)): 23 | cur_hwm = max(hwm[t - 1], equity_curve[t]) 24 | hwm.append(cur_hwm) 25 | drawdown[t] = hwm[t] - equity_curve[t] 26 | duration[t] = 0 if drawdown[t] == 0 else duration[t - 1] + 1 27 | 28 | return drawdown.max(), duration.max() -------------------------------------------------------------------------------- /wolfquant/utils/data_utils.py: -------------------------------------------------------------------------------- 1 | from wolfquant.utils.api_utils import make_order_book_id, bytes2str 2 | 3 | 4 | class DataDict(dict): 5 | def __init__(self, d=None): 6 | if d: 7 | super(DataDict, self).__init__(d) 8 | else: 9 | super(DataDict, self).__init__() 10 | 11 | def copy(self): 12 | return DataDict(super(DataDict, self).copy()) 13 | 14 | def __getattr__(self, item): 15 | return self.__getitem__(item) 16 | 17 | def __setattr__(self, key, value): 18 | self.__setitem__(key, value) 19 | 20 | 21 | class TickDict(DataDict): 22 | def __init__(self, data=None): 23 | super(TickDict, self).__init__() 24 | self.order_book_id = None 25 | self.date = None 26 | self.time = None 27 | self.open = None 28 | self.last = None 29 | self.low = None 30 | self.high = None 31 | self.prev_close = None 32 | self.volume = None 33 | self.total_turnover = None 34 | self.open_interest = None 35 | self.prev_settlement = None 36 | 37 | self.b1 = None 38 | self.b2 = None 39 | self.b3 = None 40 | self.b4 = None 41 | self.b5 = None 42 | 43 | self.b1_v = None 44 | self.b2_v = None 45 | self.b3_v = None 46 | self.b4_v = None 47 | self.b5_v = None 48 | 49 | self.a1 = None 50 | self.a2 = None 51 | self.a3 = None 52 | self.a4 = None 53 | self.a5 = None 54 | 55 | self.a1_v = None 56 | self.a2_v = None 57 | self.a3_v = None 58 | self.a4_v = None 59 | self.a5_v = None 60 | 61 | self.limit_down = None 62 | self.limit_up = None 63 | 64 | self.is_valid = False 65 | 66 | if data: 67 | self.update_data(data) 68 | 69 | def update_data(self, data): 70 | self.order_book_id = make_order_book_id(data.InstrumentID) 71 | try: 72 | self.date = int(data.TradingDay) 73 | self.time = int((bytes2str(data.UpdateTime).replace(':', ''))) * 1000 + int(data.UpdateMillisec) 74 | self.open = data.OpenPrice 75 | self.last = data.LastPrice 76 | self.low = data.LowestPrice 77 | self.high = data.HighestPrice 78 | self.prev_close = data.PreClosePrice 79 | self.volume = data.Volume 80 | self.total_turnover = data.Turnover 81 | self.open_interest = data.OpenInterest 82 | self.prev_settlement = data.SettlementPrice 83 | 84 | self.b1 = data.BidPrice1 85 | self.b2 = data.BidPrice2 86 | self.b3 = data.BidPrice3 87 | self.b4 = data.BidPrice4 88 | self.b5 = data.BidPrice5 89 | self.b1_v = data.BidVolume1 90 | self.b2_v = data.BidVolume2 91 | self.b3_v = data.BidVolume3 92 | self.b4_v = data.BidVolume4 93 | self.b5_v = data.BidVolume5 94 | self.a1 = data.AskPrice1 95 | self.a2 = data.AskPrice2 96 | self.a3 = data.AskPrice3 97 | self.a4 = data.AskPrice4 98 | self.a5 = data.AskPrice5 99 | self.a1_v = data.AskVolume1 100 | self.a2_v = data.AskVolume2 101 | self.a3_v = data.AskVolume3 102 | self.a4_v = data.AskVolume4 103 | self.a5_v = data.AskVolume5 104 | 105 | self.limit_up = data.UpperLimitPrice 106 | self.limit_down = data.LowerLimitPrice 107 | self.is_valid = True 108 | except ValueError: 109 | self.is_valid = False 110 | -------------------------------------------------------------------------------- /wolfquant/utils/db_utils.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import pandas as pd 3 | import pandas.io.sql as psql 4 | import pymysql as mdb 5 | 6 | db_host = 'localhost' 7 | db_user = 'sec_user' 8 | db_pass = 'Yutian630403' 9 | db_name = 'securities_master' 10 | 11 | 12 | def get_daily_data_from_db_new(ticker, start_date, end_date): 13 | con = mdb.connect(db_host, db_user, db_pass, db_name) 14 | sql = """SELECT dp.price_date, open_price, high_price, low_price, close_price, volume, adj_close_price 15 | FROM symbol AS sym 16 | INNER JOIN daily_price AS dp 17 | ON dp.symbol_id = sym.id 18 | WHERE sym.ticker = '%s' 19 | AND dp.price_date> = '%s' 20 | AND dp.price_date <= '%s' 21 | ORDER BY dp.price_date ASC;""" % (ticker, start_date, end_date) 22 | data = psql.read_sql(sql, con=con, index_col='price_date') 23 | return data 24 | 25 | 26 | def get_daily_data_from_db(ticker, data_type, start_date, end_date): 27 | con = mdb.connect(db_host, db_user, db_pass, db_name) 28 | data_type = 'dp.' + data_type 29 | sql = """SELECT dp.price_date, %s 30 | FROM symbol AS sym 31 | INNER JOIN daily_price AS dp 32 | ON dp.symbol_id = sym.id 33 | WHERE sym.ticker = '%s' 34 | AND dp.price_date> = '%s' 35 | AND dp.price_date< = '%s' 36 | ORDER BY dp.price_date ASC;""" % (data_type, ticker, start_date, end_date) 37 | data = psql.read_sql(sql, con=con, index_col='price_date') 38 | return data 39 | 40 | 41 | def simulate(start_date, end_date, tickers, initial_allocation): 42 | adj_close_price = {ticker: get_daily_data_from_db(ticker, 'adj_close_price', start_date, end_date) for ticker in tickers} 43 | adj_close_price_comb = pd.concat(adj_close_price, axis=1) 44 | ret = adj_close_price_comb.pct_change() 45 | ret_port = (ret*initial_allocation).sum(axis=1) 46 | ret_avg_port = ret_port.mean() 47 | vol_port = ret_port.std() 48 | rf = 0 49 | sharp_ratio_port = np.sqrt(252)*(ret_avg_port-rf)/vol_port 50 | return(sharp_ratio_port) 51 | 52 | 53 | def optimize(start_date, end_date, tickers): 54 | adj_close_price = {ticker: get_daily_data_from_db(ticker, 'adj_close_price', start_date, end_date) for ticker in tickers} 55 | adj_close_price_comb = pd.concat(adj_close_price, axis=1) 56 | ret = adj_close_price_comb.pct_change() 57 | ret_avg = np.mat(ret.mean().as_matrix()).T 58 | rf = 0 59 | cov = np.mat(ret.cov().as_matrix()) 60 | cov_inv = np.linalg.inv(cov) 61 | A = (ret_avg-rf).T*cov_inv*(ret_avg-rf) 62 | lmd = -1/A.item(0) 63 | w = -lmd*cov_inv*(ret_avg-rf) 64 | x = w/w.sum() 65 | return x.flatten().tolist()[0] 66 | 67 | 68 | def get_snp_500_tickers(): 69 | con = mdb.connect(db_host, db_user, db_pass, db_name) 70 | sql = """SELECT ticker FROM symbol;""" 71 | data = psql.read_sql(sql, con=con, columns='ticker') 72 | return data['ticker'].tolist() 73 | -------------------------------------------------------------------------------- /wolfquant/utils/factor_utils.py: -------------------------------------------------------------------------------- 1 | 2 | class Factor_pipeline(object): 3 | def __init__(self, data): 4 | self.data = data 5 | 6 | def add(self, func, *args, **kwargs): 7 | """添加变量 8 | """ 9 | self.data = func(self.data, *args, **kwargs) 10 | return self 11 | --------------------------------------------------------------------------------