|
| 1 | +# 简介 |
| 2 | + |
| 3 | +AlgoPlus是上期技术CTP API的Python封装。 |
| 4 | + |
| 5 | +# 官网 |
| 6 | + |
| 7 | +<http://algo.plus> |
| 8 | + |
| 9 | +# 安装 |
| 10 | + |
| 11 | +首先配置Python环境,然后安装:```pip install AlgoPlus```。 或者下载AlgoPlus包文件,解压后放在项目目录中。 |
| 12 | + |
| 13 | +# 版本对应关系 |
| 14 | + |
| 15 | +| AlgoPlus版本号 | CTP API版本 | Python版本 | |
| 16 | +| :----: | :----: | :----: | |
| 17 | +| 3.0 | v6.6.9_20220914 9:57:19.2466 | 3.7、3.8、3.9 | |
| 18 | + |
| 19 | +# 入门视频教程 |
| 20 | + |
| 21 | +* [配置Python环境与安装AlgoPlus](https://www.bilibili.com/video/BV1p54y1m77t) |
| 22 | +* [CTP API的工作原理](https://www.bilibili.com/video/BV17v411C73r) |
| 23 | + |
| 24 | +# 应用范例 |
| 25 | + |
| 26 | +这里就给大家介绍介个基于AlgoPlus实现的应用范例,供大家参考。 |
| 27 | + |
| 28 | +## 1、获取实时行情 |
| 29 | + |
| 30 | +发布实时行情是交易所实现价值发现职能的重要工作,而且是交易决策的重要依据。 |
| 31 | + |
| 32 | +CTP通过一个独立的MdApi接口发布行情。MdApi功能比较单一,只需要在与服务器建立连接后订阅相关合约,就可以自动接收到到实时行情。 |
| 33 | + |
| 34 | +AlgoPlus对MdApi进行了封装,我们只需要将账户信息及合约名称作为参数传进去,就可以接收到字典形式的实时行情数据。 |
| 35 | + |
| 36 | +演示这个功能的例子是`examples/get_tick.py`,运行之后可以看到如下的输出结果: |
| 37 | + |
| 38 | + |
| 39 | + |
| 40 | +从输出日志可以看到,AlgoPlus第一步连接服务器,第二步登陆账户,第三步订阅行情,最后就是接收行情数据。 |
| 41 | + |
| 42 | +### 1.1 期货合约规范: |
| 43 | + |
| 44 | +* 上期/能源所:小写+4个数字 |
| 45 | +* 大商所:小写+4个数字 |
| 46 | +* 中金所:大写+4个数字 |
| 47 | +* 郑商所:大写+3个数字 |
| 48 | + |
| 49 | +### 1.2 期权合约规范: |
| 50 | + |
| 51 | +* 上期所/能源所:小写+4个数字+C(或者P)+行权价 |
| 52 | +* 郑商所:大写+3个数字+C(或者P)+行权价 |
| 53 | +* 中金所:大写+4个数字+-C-(或者-P-)+行权价 |
| 54 | +* 大商所:小写+4个数字+-C-(或者-P-)+行权价 |
| 55 | + |
| 56 | +## 2、将行情存为CSV文件 |
| 57 | + |
| 58 | +因为MdApi只推送实时行情,所以存储数据是量化交易至关重要的一项工作。虽然有多种数据库可以选择,但是简单起见,`examples/tick_to_csv.py`使用了csv文件。运行这个例子后,实时行情数据自动被存入`MarketData`文件夹下的csv文件中。 |
| 59 | + |
| 60 | +## 3、合成K线 |
| 61 | + |
| 62 | +MdApi推送的实时行情是固定时间间隔(一般间隔是500ms)的快照,也就是我们常说Tick数据。 |
| 63 | + |
| 64 | +而交易决策的逻辑基础往往是K线数据,所谓的K线就是用固定时间间隔内开盘价、最高价、最低价、收盘价代理此间所有Tick。 |
| 65 | + |
| 66 | +K线自诞生以来就被二级市场所广泛使用。合理的选择K线周期,可以帮助我们抓住主线趋势,避免陷于短期波动。 |
| 67 | + |
| 68 | +`examples/get_bar.py`为大家演示了如何将Tick数据合成1分钟K线数据,字段内容如下: |
| 69 | + |
| 70 | +```python |
| 71 | +{ |
| 72 | + 'InstrumentID': b'', # 合约代码 |
| 73 | + 'UpdateTime': b'00:46:00', # K线开始时间 |
| 74 | + 'LastPrice': 3454.0, # 收盘价 |
| 75 | + 'HighPrice': 3454.0, # 最高价 |
| 76 | + 'LowPrice': 3454.0, # 最低价 |
| 77 | + 'OpenPrice': 3454.0, # 开盘价 |
| 78 | + 'BarVolume': 7, # 成交量 |
| 79 | + 'BarTurnover': 24178.0, # 成交额 |
| 80 | + 'BarSettlement': 3454.0, # K线成交均价 |
| 81 | + 'BVolume': 0, # 主动买量 |
| 82 | + 'SVolume': 7, # 主动卖量 |
| 83 | + 'FVolume': 0, # 非主动买卖量 |
| 84 | + 'DayVolume': 1381157, # 全天成交量 |
| 85 | + 'DayTurnover': 4771897578.0, # 全天成交额 |
| 86 | + 'DaySettlement': 3455.000103536383, # 全天成交均价 |
| 87 | + 'OpenInterest': 1577415.0, # 持仓量 |
| 88 | + 'TradingDay': b'20200508' # 交易日 |
| 89 | +} |
| 90 | +``` |
| 91 | + |
| 92 | +除了1分钟K线之外,大家也可以参考如下条件合成其他周期K线: |
| 93 | + |
| 94 | +```python |
| 95 | +# 1分钟K线条件 |
| 96 | +is_new_1minute = (pDepthMarketData['UpdateTime'][:-2] != last_update_time[:-2]) and pDepthMarketData['UpdateTime'] != b'21:00:00' |
| 97 | +# 5分钟K线条件 |
| 98 | +is_new_5minute = is_new_1minute and int(pDepthMarketData['UpdateTime'][-4]) % 5 == 0 |
| 99 | +# 10分钟K线条件 |
| 100 | +is_new_10minute = is_new_1minute and pDepthMarketData['UpdateTime'][-4] == b"0" |
| 101 | +# 15分钟K线条件 |
| 102 | +is_new_10minute = is_new_1minute and int(pDepthMarketData['UpdateTime'][-5:-3]) % 15 == 0 |
| 103 | +# 30分钟K线条件 |
| 104 | +is_new_30minute = is_new_1minute and int(pDepthMarketData['UpdateTime'][-5:-3]) % 30 == 0 |
| 105 | +# 60分钟K线条件 |
| 106 | +is_new_hour = is_new_1minute and int(pDepthMarketData['UpdateTime'][-5:-3]) % 60 == 0 |
| 107 | +``` |
| 108 | + |
| 109 | +运行结果如下: |
| 110 | + |
| 111 | + |
| 112 | + |
| 113 | +## 4、看穿式认证 |
| 114 | + |
| 115 | +由于监管要求,接入期货公司的交易程序必须经过看穿式认证。简单的说,就是用交易程序在期货公司提供的仿真环境中完成指定的交易、查询任务就可以了。完成后,期货公司会提供用于生产环境的授权码。所谓的直连模式和中继模式,只要是自己用的都属于直连模式。 |
| 116 | + |
| 117 | +`examples/authenticate.py`这个例子虽然是为了方便大家做认证,但是其中的基础操作对熟悉交易接口是很有帮助的,例如: |
| 118 | + |
| 119 | +```python |
| 120 | +# 买开仓 |
| 121 | +self.buy_open(...) |
| 122 | +# 卖平仓 |
| 123 | +self.sell_close(...) |
| 124 | +# 卖开仓 |
| 125 | +self.sell_open(...) |
| 126 | +# 买平仓 |
| 127 | +self.buy_close(...) |
| 128 | +# 撤单 |
| 129 | +self.req_order_action(...) |
| 130 | +# 查询订单 |
| 131 | +self.req_qry_order(...) |
| 132 | +# 查询成交 |
| 133 | +self.req_qry_trade() |
| 134 | +# 查询持仓 |
| 135 | +self.req_qry_investor_position() |
| 136 | +# 查询资金 |
| 137 | +self.req_qry_trading_account() |
| 138 | +``` |
| 139 | + |
| 140 | +需要注意的是交易接口的查询功能是有流控限制的,每秒限制只能查询1次。买卖报单以及撤单不受流控限制。 |
| 141 | + |
| 142 | + |
| 143 | + |
| 144 | +## 5、滚动交易 |
| 145 | + |
| 146 | +延时是很多量化交易会关注的问题,但是这又是一个很复杂的问题。 |
| 147 | + |
| 148 | +为了简单起见,我们设计了`examples/rolling_trade.py`这个滚动交易策略:收到前次报单成交回报时发起新的交易请求。完成300次交易之后,我们统计一下1秒内的交易次数,就可以计算出交易环境的延时,包括网络、交易程序、期货公司系统、交易所系统总的用时。 |
| 149 | + |
| 150 | +我使用simnow的7*24测试环境在阿里云服务器上运行该例子,1s内完成110笔成交。但是,需要说明的是,这个数据并不真实,因为7*24测试环境负载非常低。建议大家在正常的交易时间使用simnow仿真环境测试,可以获得相对更有价值的数据。 |
| 151 | + |
| 152 | + |
| 153 | + |
| 154 | +## 6、盈损管理 |
| 155 | + |
| 156 | +`examples/risk_manager.py`是一个相对复杂的例子,启动后可以监控账户的所有的成交,包括从快期或者其他终端软件报的单,当达到止盈止损条件时,就会自动平仓。启动前需要设置好止盈止损参数: |
| 157 | + |
| 158 | +```python |
| 159 | +pl_parameter = { |
| 160 | + 'StrategyID': 9, |
| 161 | + # 盈损参数,'0'代表止盈, '1'代表止损,绝对价差 |
| 162 | + 'ProfitLossParameter': { |
| 163 | + b'rb2010': {'0': [2], '1': [2]}, |
| 164 | + b'ni2007': {'0': [20], '1': [20]}, |
| 165 | + }, |
| 166 | +} |
| 167 | +``` |
| 168 | + |
| 169 | +简单起见,这里只实现了固定止盈止损,大家可以参考实现更复杂、有效的止损策略。这篇文章为大家提供一些关于止盈止损的思路:[http://algo.plus/researches/0002.html](http://algo.plus/researches/0002.html) |
| 170 | + |
| 171 | +另外,我们也可以将这个策略部署到服务器上,成为属于自己的云端条件单系统。 |
| 172 | + |
| 173 | +因为目的是为了让大家快速熟悉AlgoPlus,所以很多问题都浅尝辄止,以后有机会我们再进行深入探讨,也欢迎大家在后台留言讨论。 |
| 174 | + |
| 175 | +## 7、订阅全市场行情并落地为csv文件 |
| 176 | + |
| 177 | +期货合约都是有期限的,订阅全市场行情需要先使用`AlgoPlus.CTP.TraderApi.run_query_instrument`查询当前挂牌交易的所有合约,然后再交给`run_mdrecorder`订阅并存储。`subscribe_all.py`演示了具体如何使用。 |
| 178 | + |
| 179 | +# 仿真交易测试 |
| 180 | + |
| 181 | +## 1、`SimNow同步仿真环境` |
| 182 | + |
| 183 | +``` |
| 184 | +BrokerID = "9999" |
| 185 | +TraderFrontAddress = "tcp://180.168.146.187:10201" |
| 186 | +MdFrontAddress = "tcp://180.168.146.187:10211" |
| 187 | +AppID = "simnow_client_test" |
| 188 | +AuthCode = "0000000000000000" |
| 189 | +``` |
| 190 | + |
| 191 | +## 2、`SimNow同步仿真环境` |
| 192 | + |
| 193 | +``` |
| 194 | +BrokerID = "9999" |
| 195 | +TraderFrontAddress = tcp://180.168.146.187:10202 |
| 196 | +MdFrontAddress = tcp://180.168.146.187:10212 |
| 197 | +AppID = "simnow_client_test" |
| 198 | +AuthCode = "0000000000000000" |
| 199 | +``` |
| 200 | + |
| 201 | +## 3、`SimNow同步仿真环境` |
| 202 | + |
| 203 | +``` |
| 204 | +BrokerID = "9999" |
| 205 | +TraderFrontAddress = "tcp://218.202.237.33:10203" |
| 206 | +MdFrontAddress = "tcp://218.202.237.33:10213" |
| 207 | +AppID = "simnow_client_test" |
| 208 | +AuthCode = "0000000000000000" |
| 209 | +``` |
| 210 | + |
| 211 | +## 4、`SimNow7*24仿真环境` |
| 212 | + |
| 213 | +``` |
| 214 | +BrokerID = "9999" |
| 215 | +TraderFrontAddress = "tcp://180.168.146.187:10130" |
| 216 | +MdFrontAddress = "tcp://180.168.146.187:10131" |
| 217 | +AppID = "simnow_client_test" |
| 218 | +AuthCode = "0000000000000000" |
| 219 | +``` |
| 220 | + |
| 221 | +# 地址 |
| 222 | + |
| 223 | +1. 码云:<https://gitee.com/AlgoPlus/> |
| 224 | +2. GitHub:<https://github.com/keyalgo/AlgoPlus> |
| 225 | + |
| 226 | +### 自媒体账号 |
| 227 | + |
| 228 | +* bilibili账号:**AlgoPlus** |
| 229 | + |
| 230 | +* 微信公众号:**AlgoPlus** |
| 231 | + |
| 232 | + |
| 233 | + |
| 234 | +* QQ群:**866469866** |
| 235 | + |
| 236 | + |
0 commit comments