├── .gitignore ├── LICENSE ├── README.md ├── algorithm.md ├── architect.md ├── assets ├── alpha_backtest_report.PNG ├── data_service_api.png ├── datacore_architect.png ├── doubleMA.png ├── doubleMA_tradeapi.PNG ├── event_report.png ├── framework.png ├── mdlink-sina.png ├── plot_trades.png ├── pnl_img.png ├── pnl_img2.png ├── procedure.png ├── quantos-qq.jpg ├── quantos.jpg ├── solution_case1.png ├── solution_case2.png ├── solution_case3.png ├── solution_case4.png ├── solution_case5.png ├── tkpro.png ├── token.png ├── trade_api.png ├── tradesim_entrust.PNG ├── tradesim_pnl.PNG ├── tradesim_trade.PNG ├── tradesim_web.PNG └── vnTrader.PNG ├── datasolution.md ├── dataspecification.md ├── dev ├── task-mdlink-tencent.md └── task-tick2bar.md ├── faq └── faq.md ├── jaqs.md ├── jaqs ├── backtest_framework.md ├── dataview_formula.md ├── dataview_function_list.md ├── query_data_function_list.md └── research_framework.md ├── prerequisites.md ├── releasenotes.md ├── samples ├── calendar_spread.md ├── dual_thrust.md └── graham.md ├── security.md ├── strategy_tutorial_1_alpha.md ├── strategy_tutorial_2_timing.md ├── tradesimguide.md ├── tradesolution.md ├── tusharepro.md └── usercase.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Node rules: 2 | ## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 3 | .grunt 4 | 5 | ## Dependency directory 6 | ## Commenting this out is preferred by some people, see 7 | ## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git 8 | node_modules 9 | 10 | # Book build output 11 | _book 12 | 13 | # eBook build output 14 | *.epub 15 | *.mobi 16 | *.pdf 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 关于quantOS 2 | 3 | quantOS致力于提供量化开源系统的一站式解决方案。 4 | 5 | 在这里,我们希望与您一起: 6 | 7 | * 开发完备的量化投资工具 8 | * 探索科学的量化研究方法 9 | * 交流一切关于量化投资的有意思的事情 10 | 11 | 这里有《乱世华尔街》的作者,有tushare和vn.py的创始人,还有一大波技术大牛。 12 | 13 | 详细的信息,可以登录[官方网站](http://www.quantos.org)了解。 14 | 15 | 16 | # 本书内容 17 | 18 | 19 | ## 快速入门 20 | 21 | * [quantOS上手指南](prerequisites.md) 22 | * [quantOS可以做什么](architect.md) 23 | * [量化策略样例(1):选股](strategy_tutorial_1_alpha.md) 24 | * [量化策略样例(2):择时](strategy_tutorial_2_timing.md) 25 | * [如何进行仿真交易](tradesimguide.md) 26 | * [我只想使用数据,该怎么做](tusharepro.md) 27 | * [提问的艺术](https://github.com/quantOS-org/JAQS/blob/master/doc/how_to_ask_questions.md) 28 | 29 | ## 高级进阶 30 | * [quantOS典型应用场景分析](usercase.md) 31 | * [数据系统解决方案](datasolution.md) 32 | * [策略系统JAQS解析](jaqs.md) 33 | * [交易系统解决方案](tradesolution.md) 34 | * [如何进行算法交易](algorithm.md) 35 | * [数据处理神器DataView](https://github.com/quantOS-org/JAQS/blob/master/doc/data_view.md) 36 | * [quantOS数据规范](dataspecification.md) 37 | * [quantOS安全机制](security.md) 38 | 39 | ## 安装指南 40 | 41 | * [1.JAQS安装指南](https://github.com/quantOS-org/JAQS/blob/master/doc/install.md) 42 | * [2.DataCore安装指南](https://github.com/quantOS-org/DataCore/blob/master/doc/install.md) 43 | 44 | ## 常见问题 45 | 46 | * [常见问题](faq/faq.md) 47 | 48 | ## 更多策略样例 49 | 50 | * [格雷厄姆选股策略](samples/graham.md) 51 | * [商品期货的Dual Thrust日内交易策略](samples/dual_thrust.md) 52 | * [Calendar Spread交易策略](samples/calendar_spread.md) 53 | 54 | ## quantOS最新发布动态 55 | 56 | * [最新发布动态](releasenotes.md) 57 | 58 | ## 社区开放式开发任务 59 | 60 | * [mdlink腾讯](dev/task-mdlink-tencent.md) (已完成) 61 | 62 | * [将tk转换成分钟线](dev/task-tick2bar.md) (已完成) 63 | -------------------------------------------------------------------------------- /algorithm.md: -------------------------------------------------------------------------------- 1 | # 如何进行算法交易 2 | 3 | 作者:vanvency, PKUJohnson 4 | 5 | 算法交易是专业投资者的必备工具,这里为大家介绍如何在TradeSim上进行算法交易。 6 | 7 | 8 | ## 使用TradeApi下单 9 | 10 | TradeSim支持使用TradeApi进行算法交易。支持的算法包括VWAP,TWAP等 11 | 12 | ### 以VWAP为例,样例代码如下: 13 | 14 | ```py 15 | from jaqs.trade.tradeapi import TradeApi 16 | 17 | # 登录仿真系统 18 | tapi = TradeApi(addr="tcp://gw.quantos.org:8901") # tcp://gw.quantos.org:8901是仿真系统地址 19 | user_info, msg = tapi.login("demo", "666666") # 示例账户,用户需要改为自己注册的账户 20 | 21 | # 选择策略号 22 | tapi.use_strategy(123) # 123为给你分配的策略号,可以从user_info中获得 23 | 24 | # VWAP算法参数 25 | params = { 26 | "participate_rate": {"600000.SH": 0.5}, 27 | "urgency": {"600000.SH": 5}, 28 | "price_range": {"600000.SH": [16.5,17.1]}, 29 | "lifetime": 5000, 30 | "min_unit_size": {"600000.SH": 500} 31 | } 32 | 33 | # 下单接口,供支持三种下单风格 34 | 35 | # Single Order Style 36 | task_id, msg = tapi.place_order("600000.SH", "Buy", 17, 100, "vwap", params) 37 | print "msg:", msg 38 | print "task_id:", task_id 39 | 40 | # Batch Order Style 41 | orders = [ 42 | {"security":"600030.SH", "action" : "Buy", "price": 16.10, "size":1000}, 43 | {"security":"600868.SH", "action" : "Buy", "price": 5.89, "size":1000}, 44 | ] 45 | 46 | params = { 47 | "participate_rate": {"600030.SH": 0.5, "600868.SH": 0.5}, 48 | "urgency": {"600030.SH": 5, "600868.SH": 5}, 49 | "lifetime": 5000 50 | } 51 | 52 | task_id, msg = tapi.place_batch_order(orders, "vwap", params) 53 | print "msg:", msg 54 | print "task_id:", task_id 55 | 56 | # Basket Order Style 57 | orders = [ 58 | {"security":"600030.SH", "ref_price": 16.10, "inc_size":1000}, 59 | {"security":"600868.SH", "ref_price": 5.89, "inc_size":-1000}, 60 | ] 61 | 62 | params = { 63 | "participate_rate": {"600030.SH": 0.5, "600868.SH": 0.5}, 64 | "urgency": {"600030.SH": 5, "600868.SH": 5}, 65 | "lifetime": 5000, 66 | } 67 | 68 | task_id, msg = tapi.basket_order(orders, "vwap", params) 69 | print "msg:", msg 70 | print "task_id:", task_id 71 | 72 | ``` 73 | 74 | ### 以TWAP为例,样例代码如下: 75 | 76 | ```py 77 | from tradeapi import TradeApi 78 | 79 | # 登录仿真系统 80 | tapi = TradeApi(addr="tcp://gw.quantos.org:8901") # tcp://gw.quantos.org:8901是仿真系统地址 81 | user_info, msg = tapi.login("demo", "666666") # 示例账户,用户需要改为自己注册的账户 82 | 83 | # 选择策略号 84 | tapi.use_strategy(123) # 123为给你分配的策略号,可以从user_info中获得 85 | 86 | # 下单接口,供支持三种下单风格 87 | 88 | # Single Order Style 89 | params = { 90 | "urgency": {"600868.SH": 5}, 91 | "cycle": 1000, 92 | "max_unit_size": {"600868.SH": 5}, 93 | "lifetime": 5000, 94 | "price_range": {"600868.SH": [5.8, 6.2]}, 95 | "smart_speed": [0.8,1.1,1.3] 96 | } 97 | 98 | task_id, msg = tapi.place_order("600868.SH", "Buy", 6.57, 100, "twap", params) 99 | 100 | # Batch Order Style 101 | orders = [ 102 | {"security":"600030.SH", "action" : "Buy", "price": 16.10, "size":1000}, 103 | {"security":"600868.SH", "action" : "Buy", "price": 5.89, "size":1000}, 104 | ] 105 | 106 | params = { 107 | "urgency": {"600030.SH": 5, "600868.SH": 5}, 108 | "cycle": 1000, 109 | "lifetime": 5000, 110 | "price_range_factor":0.1 111 | } 112 | 113 | task_id, msg = tapi.place_batch_order(orders, "twap", params) 114 | 115 | ``` 116 | 117 | 查询、成交回报等使用方法,请参考TradeApi的使用说明。 118 | 119 | -------------------------------------------------------------------------------- /architect.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # quantOS可以做什么? 4 | 5 | 6 | 作者:quantOS.org 7 | 8 | quantOS致力于提供量化开源系统的一站式解决方案. 9 | ## quantOS有哪些特点 10 | 11 | 12 | *  **完全开源**:所有软件完全开源, 用户可以免费使用.涉及三个核心的业务组件:数据、策略和交易。 13 | 14 | *  **免费数据**:提供策略研究必须的、高质量的、可持续的研究数据, 15 | *  **本地策略**:提供包括Alpha、CTA、套利等策略模板和回测框架,用户可以快速实现策略,本地化部署。 16 | *  **仿真交易**:提供免费在线仿真交易模拟环境,帮助用户进行策略验证。 17 | *  **实盘交易**:提供多种成熟的实盘交易解决方案,适用不同的用户。 18 | 19 | ## quantOS的业务框架 20 | 21 | quantOS推荐的量化交易的业务框架如下图所示: 22 | 23 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/framework.png?raw=true) 24 | 25 | quantOS业务框架以策略研究平台JAQS为核心,通过标准化的数据Api(`DataApi`)和交易Api(`TradeApi`),将数据、策略、交易的连接打通,提供了一站式的解决方案。 26 | 27 | 涉及三个核心的业务组件:数据、策略和交易。 28 | 29 | - **在数据系统上**,quantOS提供两种选择: 30 | - 提供在线数据服务(data.quantos.org)。 31 | - 开源`DataCore`数据系统,客户可适配自己的数据源,本地化部署。 32 | - **在策略系统上**,JAQS策略系统采用Python开发并完全开源,并提供了规范化的研究流程和常见类型策略的支持,提供回测框架。用户可下载到本地后,实现自己的策略,保障客户的策略安全。 33 | - **在交易系统上**,quantOS提供多种选择: 34 | - 提供一个在线仿真服务TradeSim,供用户策略验证的有效性。 35 | - 实现了与vn.py的深度集成,可通过vn.py进行实盘交易。 36 | - 使用企业版的交易软件TKPro进行实盘交易。 37 | 38 | 39 | -------------------------------------------------------------------------------- /assets/alpha_backtest_report.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/alpha_backtest_report.PNG -------------------------------------------------------------------------------- /assets/data_service_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/data_service_api.png -------------------------------------------------------------------------------- /assets/datacore_architect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/datacore_architect.png -------------------------------------------------------------------------------- /assets/doubleMA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/doubleMA.png -------------------------------------------------------------------------------- /assets/doubleMA_tradeapi.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/doubleMA_tradeapi.PNG -------------------------------------------------------------------------------- /assets/event_report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/event_report.png -------------------------------------------------------------------------------- /assets/framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/framework.png -------------------------------------------------------------------------------- /assets/mdlink-sina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/mdlink-sina.png -------------------------------------------------------------------------------- /assets/plot_trades.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/plot_trades.png -------------------------------------------------------------------------------- /assets/pnl_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/pnl_img.png -------------------------------------------------------------------------------- /assets/pnl_img2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/pnl_img2.png -------------------------------------------------------------------------------- /assets/procedure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/procedure.png -------------------------------------------------------------------------------- /assets/quantos-qq.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/quantos-qq.jpg -------------------------------------------------------------------------------- /assets/quantos.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/quantos.jpg -------------------------------------------------------------------------------- /assets/solution_case1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/solution_case1.png -------------------------------------------------------------------------------- /assets/solution_case2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/solution_case2.png -------------------------------------------------------------------------------- /assets/solution_case3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/solution_case3.png -------------------------------------------------------------------------------- /assets/solution_case4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/solution_case4.png -------------------------------------------------------------------------------- /assets/solution_case5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/solution_case5.png -------------------------------------------------------------------------------- /assets/tkpro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/tkpro.png -------------------------------------------------------------------------------- /assets/token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/token.png -------------------------------------------------------------------------------- /assets/trade_api.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/trade_api.png -------------------------------------------------------------------------------- /assets/tradesim_entrust.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/tradesim_entrust.PNG -------------------------------------------------------------------------------- /assets/tradesim_pnl.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/tradesim_pnl.PNG -------------------------------------------------------------------------------- /assets/tradesim_trade.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/tradesim_trade.PNG -------------------------------------------------------------------------------- /assets/tradesim_web.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/tradesim_web.PNG -------------------------------------------------------------------------------- /assets/vnTrader.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quantOS-org/quantOSUserGuide/3daf22ada3e0a35f59f4312618121ca2f9fa7975/assets/vnTrader.PNG -------------------------------------------------------------------------------- /datasolution.md: -------------------------------------------------------------------------------- 1 | # 数据系统解决方案 2 | 3 | 作者:米哥、PKUJohnson,symbol 4 | 5 | 数据是量化研究的基础原料,我们提供两种模式的数据系统解决方案: 6 | 7 | | 解决方案 | 适用对象 | 重要前提条件 | 8 | | :--- | :--- | :--- | 9 | | 使用在线数据平台 | 普通投资者 | 在www.quantos.org注册账户 | 10 | | 使用DataCore搭建本地数据系统 | 机构用户 | 需要有本地数据源。 | 11 | 12 | ## 方案1:使用在线数据平台 13 | 14 | 在线数据平台由TusharePro提供,数据包括: 15 | 16 | | 数据接口 | 主要内容 | 备注 | 17 | | :--- | :--- | :--- | 18 | | daily | 提供历史日线数据 | | 19 | | bar | 提供历史分时数据和实时分时数据 | 支持的范围包括:1分钟、5分钟、15分钟 | 20 | | bar\_quote | 提供历史分时数据和实时分时数据 | 支持的范围包括:1分钟、5分钟、15分钟 | 21 | | quote | 提供实时行情快照 | | 22 | | query | 提供参考数据查询服务 | 范围非常广泛,包括证券信息、财务数据、指数、基金数据等 | 23 | 24 | 用户只需要通过如下步骤,即可使用: 25 | 26 | 1、在[http://www.quantos.org](http://www.quantos.org)上注册用户。 27 | 28 | 2、在Github上下载DataApi,项目地址如下:[https://github.com/quantOS-org/DataApi](https://github.com/quantOS-org/DataApi)。 29 | 30 | 3、根据需求,获取相应的数据。 31 | 32 | 参考代码如下: 33 | 34 | ```py 35 | from data_api import DataApi 36 | 37 | api = DataApi(addr="tcp://data.quantos.org:8910") # 在线数据源 38 | 39 | api.login("手机号", "token") #认证模块,需要修改成www.quantos.org的注册用户 40 | 41 | symbol = 'T1712.CFE, TF1712.CFE, rb1712.SHF' 42 | fields = 'open,high,low,last,volume' 43 | 44 | # 获取实时行情 45 | df, msg = api.quote(symbol=symbol, fields=fields) 46 | print(df) 47 | print(msg) 48 | 49 | # 获取实时分钟线, trade_date = 0 表示获取实时分钟线, freq='1M' 表示1分钟线 50 | df, msg = api.bar(symbol=symbol, trade_date=0, freq='1M', start_time=90000, end_time=150000) 51 | print(df) 52 | print(msg) 53 | 54 | # 获取日线数据 55 | df, msg = api.daily( 56 | symbol="600832.SH, 600030.SH", 57 | start_date="2012-10-26", 58 | end_date="2012-11-30", 59 | fields="", 60 | adjust_mode="post") 61 | 62 | # 获取证券信息 63 | df, msg = api.query( 64 | view="jz.instrumentInfo", 65 | fields="status,list_date, fullname_en, market", 66 | filter="inst_type=1", 67 | data_format='pandas') 68 | ``` 69 | 70 | **在线数据服务有一个限制,不提供行情订阅推送功能,只能查询。** 71 | 72 | 对于一般普通用户,如果上述数据能满足你的要求,我们推荐你使用这种方案。 73 | 74 | 如果您拥有自己的数据源,且有数据系统本地化部署的要求,可以使用DataCore开源项目,搭建本地数据系统。 75 | 76 | ## 方案2:使用DataCore搭建本地数据系统 77 | 78 | DataCore是一款企业级开源量化数据系统,通过标准化接口提供高速实时行情、历史行情和参考数据等核心服务,覆盖股票、商品期货、股指期货、国债期货等品种,适配CTP、万得、聚源、Tushare等各类数据。 79 | 80 | 搭建本地数据系统,需要有一些前提条件: 81 | 82 | * 用于提供行情的实时行情源 83 | * 历史市场数据(如分钟线) 84 | * 参考数据库(如万得、聚源等厂商提供的参考数据库) 85 | 86 | ### 一、构建本地行情系统 87 | 88 | DataCore本地行情系统的逻辑架构如下: 89 | 90 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/datacore_architect.png?raw=true) 91 | 92 | 整个行情系统由几个部分构成: 93 | 94 | * mdlink系列,用于行情源接口转换,包括 95 | * mdlink\_ctp:CTP期货行情接口 96 | * mdlink\_tdf:万得宏汇行情接口 97 | * mdlink\_sina:新浪股票行情接口 98 | * mdlink\_merge:把多个行情源聚合成统一的行情服务,提供全标的广播接口 99 | * qms(query market data service):用于生成实时分钟线,提供实时行情查询 100 | * dataserver:综合数据服务器,提供集成的数据服务,包括实时行情按照代码订阅推送,实时行情查询。 101 | 102 | 构建工作分如下几步: 103 | 104 | 1、准备工作,包括: 105 | 106 | * 下载可执行程序。下载地址如下:[http://www.quantos.org/datacore/download.html](http://www.quantos.org/datacore/download.html) 107 | * 准备相应的行情账号。 108 | * 期货账号,可以使用SimNow的账号,请从SimNow官网注册。[http://www.simnow.com.cn/static/register1.action](http://www.simnow.com.cn/static/register1.action),特别注意,SimNow用手机注册后,会分配一个InvestorID,请登录查看。 109 | * 万得宏汇行情接口,这个你只能找万得买了。如果你搞不到万得宏汇的行情账户,可以使用新浪的股票行情接口,不过质量就要你自己评估了。 110 | 111 | 2、部署mdlink和qms。部署过程请参考:[http://www.quantos.org/datacore/doc.html](http://www.quantos.org/datacore/doc.html) 112 | 113 | 这里务必要注意几点: 114 | 115 | **(1)需要自行修改程序里面的账号配置,同一种标的,只能提供一个源。** 116 | 117 | **(2)注意不同程序之间的访问端口,按照文档的要求进行配置。** 118 | 119 | 3、部署dataserver。部署过程请参考:[http://www.quantos.org/datacore/doc.html](http://www.quantos.org/datacore/doc.html) 120 | 121 | 这里务必要注意几点: 122 | 123 | **(1)dataserver基于Java开发,请安装Java8环境。** 124 | 125 | **(2)dataserver需要连接qms和mdlink\_merge。** 126 | 127 | 4、使用DataApi,访问本地数据服务器,看看行情服务是否正常。实时行情相关的API是: 128 | 129 | | API接口 | 含义 | 130 | | :--- | :--- | 131 | | quote | 获取当前行情切片 | 132 | | bar | 获取分钟线 | 133 | | subscribe | 订阅分钟线 | 134 | 135 | ```py 136 | from data_api import DataApi # data_api为存放DataApi的文件夹名 137 | 138 | api = DataApi(addr="tcp://127.0.0.1:8910") # 根据本地实际情况修改 139 | 140 | # api.login("手机号", "token") 141 | 142 | symbol = 'T1712.CFE, TF1712.CFE, rb1712.SHF' 143 | fields = 'open,high,low,last,volume' 144 | 145 | # 获取实时行情 146 | df, msg = api.quote(symbol=symbol, fields=fields) 147 | print(df) 148 | print(msg) 149 | 150 | # 获取实时分钟线, trade_date = 0 表示获取实时分钟线, freq='1M' 表示1分钟线 151 | df, msg = api.bar(symbol=symbol, trade_date=0, freq='1M', start_time=90000, end_time=150000) 152 | print(df) 153 | print(msg) 154 | 155 | # 订阅实时行情 156 | # 行情回调函数,k可以忽略,v是一个字典,保存quote数据 157 | def on_quote(k,v): 158 | print v['symbol'] // 标的代码 159 | print v['last'] // 最新成交价 160 | print v['time'] // 最新成交时间 161 | 162 | subs_list,msg = api.subscribe(symbol=symbol, func=on_quote,fields=fields) 163 | ``` 164 | 165 | 以上是代码示例。 166 | 167 | ### 二、构建本地历史市场数据系统 168 | 169 | DataCore 1.2 版本开始支持本地历史市场数据查询,包括历史Tick查询和历史分钟线查询。mdlink/qms可以保存收到的Tick数据,利用这些数据可以增量构建本地历史市场数据。如果需要存量历史市场数据,则需要自己准备相应数据,并转为指定格式的h5文件。DataCore的本地历史市场数据架构如下所示: 170 | ![](https://github.com/PKUJohnson/LearnJaqsByExample/blob/master/image/case5-5.png) 171 | 172 | #### 数据文件准备 173 | 174 | 一种类型的数据每个市场每个交易日各存为一个h5文件,目前支持tk(Tick)、1M(1分钟线)、5M(5分钟线)、15M(15分钟线)四种类型数据,例如SHF市场20171225交易日的数据可存为如下文件: 175 | 176 | ``` 177 | /data/SHF/2017/SHF20171214-tk.H5 178 | /data/SHF/2017/SHF20171214-1M.H5 179 | /data/SHF/2017/SHF20171214-5M.H5 180 | /data/SHF/2017/SHF20171214-15M.H5 181 | ``` 182 | 183 | 使用pandas的HDFStore进行h5文件存储,h5文件的数据存储格式为:每个标的存为一个group,该group中存放DataFrame格式的数据。例如: 184 | ``` 185 | SHF20171214-1m 186 | | cu1801.SHF (DataFrame格式1分钟线) 187 | | cu1802.SHF (DataFrame格式1分钟线) 188 | | au1801.SHF (DataFrame格式1分钟线) 189 | | au1802.SHF (DataFrame格式1分钟线) 190 | ``` 191 | 192 | HDFStore使用方法如下所示: 193 | ```python 194 | import pandas as pd 195 | # 获取数据代码省略 196 | store = pd.HDFStore(filename, "a") 197 | store['600030.SH'] = df1 198 | store['000001.SH'] = df2 199 | store.close() 200 | ``` 201 | 202 | ##### Tick文件数据格式 203 | 204 | Tick文件的文件名格式为"@MKT@YYYYMMDD-tk.h5",其中@MKT表示市场名,@YYYYMMDD表示交易日。 205 | 206 | Tick数据每个标的的DataFrame包含的字段及其类型如下所示: 207 | 208 | |field |type |value | 209 | |-------------|----------|--------| 210 | |last |int64 |* 10000 | 211 | |vwap |int64 |* 10000 | 212 | |open |int64 |* 10000 | 213 | |high |int64 |* 10000 | 214 | |low |int64 |* 10000 | 215 | |close |int64 |* 10000 | 216 | |settle |int64 |* 10000 | 217 | |iopv |int64 |* 10000 | 218 | |limit_up |int64 |* 10000 | 219 | |limit_down |int64 |* 10000 | 220 | |preclose |int64 |* 10000 | 221 | |presettle |int64 |* 10000 | 222 | |oi |int64 | | 223 | |volume |int64 | | 224 | |turnover |int64 | | 225 | |date |int64 | | 226 | |trade_date |int64 | | 227 | |time |int64 | | 228 | |preoi |int64 | | 229 | |index |datetime | | 230 | |askprice1 |int64 |* 10000 | 231 | |askprice2 |int64 |* 10000 | 232 | |askprice3 |int64 |* 10000 | 233 | |askprice4 |int64 |* 10000 | 234 | |askprice5 |int64 |* 10000 | 235 | |bidprice1 |int64 |* 10000 | 236 | |bidprice2 |int64 |* 10000 | 237 | |bidprice3 |int64 |* 10000 | 238 | |bidprice4 |int64 |* 10000 | 239 | |bidprice5 |int64 |* 10000 | 240 | |askvolume1 |int64 | | 241 | |askvolume2 |int64 | | 242 | |askvolume3 |int64 | | 243 | |askvolume4 |int64 | | 244 | |askvolume5 |int64 | | 245 | |bidvolume1 |int64 | | 246 | |bidvolume2 |int64 | | 247 | |bidvolume3 |int64 | | 248 | |bidvolume4 |int64 | | 249 | |bidvolume5 |int64 | | 250 | 251 | 其中value栏"*10000"表示需要将原值乘10000以后存转为int64类型,简单来讲,所有价格相关的字段都需要乘10000然后转int64。 252 | 253 | ##### 分钟线文件数据格式 254 | 255 | 1分钟线文件的文件名格式为"@MKT@YYYYMMDD-1M.h5",5分钟线文件的文件名格式为"@MKT@YYYYMMDD-5M.h5",15分钟线文件的文件名格式为"@MKT@YYYYMMDD-15M.h5",@MKT表示市场名,@YYYYMMDD表示交易日。 256 | 257 | 分钟线数据每个标的的DataFrame包含的字段及其类型如下所示: 258 | 259 | |field         |type     |value   | 260 | |---------------|----------|--------| 261 | |open           |int64     |* 10000 | 262 | |high           |int64     |* 10000 | 263 | |low |int64 |* 10000 | 264 | |close |int64 |* 10000 | 265 | |settle |int64 |* 10000 | 266 | |oi |int64 | | 267 | |volume |int64 | | 268 | |turnover |int64 | | 269 | |total_volume |int64 | | 270 | |total_turnover |int64 | | 271 | |date |int64 | | 272 | |trade_date |int64 | | 273 | |time |int64 | | 274 | |index |datetime | | 275 | |askprice1 |int64 |* 10000 | 276 | |askprice2 |int64 |* 10000 | 277 | |askprice3 |int64 |* 10000 | 278 | |askprice4 |int64 |* 10000 | 279 | |askprice5 |int64 |* 10000 | 280 | |bidprice1 |int64 |* 10000 | 281 | |bidprice2 |int64 |* 10000 | 282 | |bidprice3 |int64 |* 10000 | 283 | |bidprice4 |int64 |* 10000 | 284 | |bidprice5 |int64 |* 10000 | 285 | |askvolume1 |int64 | | 286 | |askvolume2 |int64 | | 287 | |askvolume3 |int64 | | 288 | |askvolume4 |int64 | | 289 | |askvolume5 |int64 | | 290 | |bidvolume1 |int64 | | 291 | |bidvolume2 |int64 | | 292 | |bidvolume3 |int64 | | 293 | |bidvolume4 |int64 | | 294 | |bidvolume5     |int64     |       | 295 | 296 | ##### 利用QMS保存的tk文件生成数据文件 297 | 298 | 目前运行mdlink和qms系统后,会在data/tk文件夹下按市场保存收到的tick数据,如下所示: 299 | ``` 300 | 617134798 Dec 14 15:20 SHF20171214.tk 301 | 62738353 Dec 14 16:34 CFE20171214.tk 302 | 391967678 Dec 14 15:00 CZC20171214.tk 303 | 424926986 Dec 14 15:03 DCE20171214.tk 304 | 1608054336 Dec 14 16:39 SH20171214.tk 305 | 2395156236 Dec 14 16:39 SZ20171214.tk 306 | ``` 307 | 308 | 我们提供了python版的tkreader工具来读取这些二进制tk文件,并将其转换为h5格式的Tick文件和分钟线文件。 309 | 310 | 使用tkreader读取示例如下: 311 | ```python 312 | from tkreader import TkReader 313 | user = "phone number" 314 | passwd = "your token" 315 | tkreader = TkReader() 316 | file_name = "SHF20171218.tk" 317 | start_time = "21:00:00" 318 | end_time = "15:00:00" 319 | 320 | if( not tkreader.login(user, passwd)): 321 | print("login failed") 322 | return False 323 | 324 | if (not tkreader.open(file_name,"", start_time, end_time)): 325 | print("can't open file %s " %file_name) 326 | return False 327 | tk = tkreader.get_next() 328 | while tk is not None: 329 | print(tk['symbol']) 330 | print(tk['date']) 331 | print(tk['time']) 332 | print(tk['last']) 333 | ``` 334 | 读出的Tick数据字段参考DataApi使用文档的quote字段。 335 | 336 | 将tk文件转为h5格式Tick数据可以使用tkreader.py文件中的tk_to_h5函数来完成,使用示例在tkreader.py文件的main函数下。 337 | 338 | 339 | 将tk文件转为h5格式分钟线数据可以使用tk2bar.py中的tk2bar类来完成,使用示例在tk2bar.py的main函数下。 340 | 341 | #### DataServer配置数据文件路径 342 | 修改etc/dataserver-dev.conf文件下的his_bar项,如下所示: 343 | ``` 344 | "his_bar" : { 345 | "bar1m_path" : "D:/store/data/raw_data/BarONE/@MKT/@YYYY/@MKT@YYYYMMDD-1M.h5", 346 | "bar5m_path" : "D:/store/data/raw_data/BarFIVE/@MKT/@YYYY/@MKT@YYYYMMDD-5M.h5", 347 | "bar15m_path" : "D:/store/data/raw_data/BarQUARTER/@MKT/@YYYY/@MKT@YYYYMMDD-15M.h5", 348 | "tick_path" : "D:/store/data/raw_data/Tick/@MKT/@YYYY/@MKT@YYYYMMDD-tk.h5" 349 | } 350 | ``` 351 | 将数据文件的存放路径配置到his_bar里面:1分钟线数据文件路径配置到bar1m_path, 352 | 5分钟线数据文件路径配置到bar5m_path,15分钟线数据文件路径配置到bar15m_path,Tick数据文件路径配置到tick_path。 353 | 354 | 注意:@MKT、@YYYY和@YYYYMMDD为程序可识别的通配符,@MKT表示市场名,@YYYY表示年份,@YYYYMMDD表示日期。文件名中的通配符必须保留,文件名格式固定为@MKT@YYYYMMDD-XX.h5,不可修改。文件路径中的通配符可去掉,如: 355 | ``` 356 | "his_bar" : { 357 | "bar1m_path" : "D:/store/data/raw_data/@MKT@YYYYMMDD-1M.h5", 358 | "bar5m_path" : "D:/store/data/raw_data/@MKT@YYYYMMDD-5M.h5", 359 | "bar15m_path" : "D:/store/data/raw_data/@MKT@YYYYMMDD-15M.h5", 360 | "tick_path" : "D:/store/data/raw_data/@MKT@YYYYMMDD-tk.h5" 361 | } 362 | ``` 363 | 配置好后本地运行DataServer,使用DataApi连接本地DataServer就可以获取分钟线数据和Tick数据了。 364 | 365 | 366 | ### 三、构建本地参考数据系统 367 | 368 | comming soon...... 369 | 370 | -------------------------------------------------------------------------------- /dataspecification.md: -------------------------------------------------------------------------------- 1 | # quantOS数据规范 2 | 3 | 作者:PKUJohnson, symbol, vanvency 4 | 5 | 为了让quantOS各系统和谐工作,我们制定了必不可少的数据规范。 6 | 7 | ## 数据字典规范 8 | 9 | ## 市场代码(marketcode) 10 | 11 | | 市场名称 | 市场代码 | 12 | | :--- | :--- | 13 | | 深交所 | SZ | 14 | | 上交所 | SH | 15 | | 中金所 | CFE | 16 | | 郑商所 | CZC | 17 | | 大商所 | DCE | 18 | | 上期所 | SHF | 19 | | 上金所 | SGE | 20 | | 中证指数 | CSI | 21 | | 港交所 | HK | 22 | 23 | ### 标的代码(symbol) 24 | 25 | symbol由标的原始代码加市场代码组合而成,中间以'.'隔开,如'000001.SH'。 26 | 27 | 多标的输入时以逗号 \(','\) 隔开如:'000001.SH, cu1709.SHF' 28 | 29 | ### Bar类型(freq) 30 | 31 | | Bar类型 | 说明 | 32 | | :--- | :--- | 33 | | 15S | 15秒线 | 34 | | 30S | 30秒线 | 35 | | 1M | 1分钟线 | 36 | | 5M | 5分钟线 | 37 | | 15M | 15分钟线 | 38 | | 1d | 日线 | 39 | | 1w | 周线 | 40 | | 1m | 月线 | 41 | 42 | ### 证券类型定义 \(insttype\) 43 | 44 | | 证券类型 | inst\_type | 45 | | :--- | :--- | 46 | | 股票 | 1 | 47 | | 封闭式基金 | 2 | 48 | | LOF基金 | 3 | 49 | | ETF基金 | 4 | 50 | | 分级基金 | 5 | 51 | | 国债商品 | 6 | 52 | | 商品 | 7 | 53 | | 可转债 | 8 | 54 | | 回购 | 10 | 55 | | 国债 | 11 | 56 | | 地方政府债 | 12 | 57 | | 金融债 | 13 | 58 | | 企业债 | 14 | 59 | | 公司债 | 15 | 60 | | 资产支持证券 | 16 | 61 | | 可交换债 | 17 | 62 | | 可分离转债存债 | 18 | 63 | | 政府支持机构债 | 19 | 64 | | 转股换股 | 20 | 65 | | 指数 | 100 | 66 | | 股指期货 | 101 | 67 | | 国债期货 | 102 | 68 | | 商品期货 | 103 | 69 | | 股指ETF期权 | 201 | 70 | | 股指期货期权 | 202 | 71 | | 商品期货期权 | 203 | 72 | 73 | ### 交易行为(action) 74 | 75 | | 交易行为 | 含义 | 76 | | :--- | :--- | 77 | | Buy | 买入(多头开仓) | 78 | | Sell | 卖出(多头平仓) | 79 | | Short | 空头开仓 | 80 | | Cover | 空头平仓 | 81 | | CoverYesterday | 空头平昨仓 | 82 | | CoverToday | 空头平今仓 | 83 | | SellYesterday | 多头平昨仓 | 84 | | SellToday | 多头平今仓 | 85 | 86 | ### 订单状态(order\_status) 87 | 88 | | 订单状态 | 含义 | 89 | | :--- | :--- | 90 | | New | 订单生成 | 91 | | Accepted | 订单已被接受 | 92 | | Rejected | 订单已被拒绝 | 93 | | Filled | 订单已完全成交 | 94 | | Cancelled | 订单已取消(可能有部分成交) | 95 | 96 | ## 基础数据规范 97 | 98 | 重要基础数据我们进行了统一的规范,主要包括: 99 | 100 | ### 证券信息(instrument) 101 | 102 | | instcode | jzcode | market | buylot | pricetick | multiplier | insttype | symbol | 103 | | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | 104 | | 000300 | 4 | 2 | 100 | 0.01 | 1 | 100 | 000300.SH | 105 | | 000905 | 5 | 2 | 100 | 0.01 | 1 | 100 | 000905.SH | 106 | | 000016 | 6 | 2 | 100 | 0.01 | 1 | 100 | 000016.SH | 107 | 108 | 其中的jzcode由我们统一编码,其他字段包括最小交易单位,最小价格,合约乘数,证券类型等。 109 | 110 | ### 交易日历(calendar) 111 | 112 | | date | 113 | | :--- | 114 | | 20041022 | 115 | | 20041025 | 116 | | 20041026 | 117 | | 20041027 | 118 | 119 | calendar只列出了所有的A股交易日。 120 | 121 | ### 市场信息(market) 122 | 123 | | market | marketcode | auctbeg1 | auctend1 | auctbeg2 | auctend2 | 124 | | :--- | :--- | :--- | :--- | :--- | :--- | 125 | | 1 | SZ | 930 | 1130 | 1300 | 1500 | 126 | | 2 | SH | 930 | 1130 | 1300 | 1500 | 127 | | 3 | CFE | 915 | 1130 | 1300 | 1515 | 128 | | 4 | CZC | 900 | 1015 | 1030 | 1130 | 129 | 130 | 市场信息中,最重要的是市场代码\(marketcode\),还有该市场的交易时间段定义。 131 | 132 | **基础数据是其他项目的依赖,请从**[**http://www.quantos.org/downloads/basedata/**](http://www.quantos.org/downloads/basedata/)**下载最新的基础数据。** 133 | 134 | -------------------------------------------------------------------------------- /dev/task-mdlink-tencent.md: -------------------------------------------------------------------------------- 1 | 2 | # quantOS开源社区开放式开发任务书 mdlink-tencent 3 | 4 | ## 需求概览 5 | 6 | DataCore是一款企业级开源量化数据系统,通过标准化接口提供高速实时行情、历史行情和参考数据等核心服务,覆盖股票、商品期货、股指期货、国债期货等品种,适配CTP、万得、聚源、Tushare等各类数据。 7 | 8 | DataCore的内部逻辑架构如下: 9 | 10 | ![](/assets/datacore_architect.png) 11 | 12 | 这个架构可支持用户根据自己的实际情况,对接自己的行情源。 13 | 14 | 考虑到互联网广大用户获取行情的复杂度,我们拟提供免费的解决方案,即通过对互联网免费行情源进行封装,为用户提供实时行情服务。 15 | 16 | 目前互联网上两个免费的股票行情源是: 17 | 18 | - 新浪的股票数据接口:http://hq.sinajs.cn/list=股票代码,如:sh600000,sz000913 (这里sh是上海,sz为深圳),参看http://finalbone.iteye.com/blog/424608 19 | - 腾讯的股票数据接口:http://qt.gtimg.cn/q=sz000858,参看http://blog.csdn.net/robertsong2004/article/details/46340621 20 | 21 | 新浪行情源我们已经对接好了,还需要开发一个腾讯行情源 **mdlink-tencent** ,可以参考mdlink-sina的代码,进行适当的修改。 22 | 23 | mdlink-sina的地址如下: 24 | 25 | [https://github.com/quantOS-org/DataCore/tree/master/mdlink/src/mdlink/mdlink\_sina](https://github.com/quantOS-org/DataCore/tree/master/mdlink/src/mdlink/mdlink_sina) 26 | 27 | ## 接口规范 28 | 29 | 这里我们讲解一下mdlink-sina的接口规范,在开发mdlink-tencent时,需要遵循同样的规范。 30 | 31 | ![](/assets/mdlink-sina.png) 32 | 33 | 规范1:由于新浪提供的方式是行情查询,mdlink-sina需要提供全市场的股票行情,因此需要不断查询新浪的行情数据,并且保存在自己的内存中。查询频率需要参数化配置。 34 | 35 | 规范2:mdlink-sina对外提供服务的方式是zmq+protobuf,是一种广播模式,任何客户端连上mdlink-sina后,都会接受到其publish的所有行情。publish的行情报文是protobuf格式,具体请参看代码和protobuf报文定义,地址如下: 36 | 37 | [https://github.com/quantOS-org/DataCore/blob/master/mdlink/src/protocol/md.proto](https://github.com/quantOS-org/DataCore/blob/master/mdlink/src/protocol/md.proto) 38 | 39 | 规范3:项目采用C++开发,cmake负责编译,编译文件配置是: 40 | 41 | [https://github.com/quantOS-org/DataCore/blob/master/mdlink/src/mdlink/mdlink\_sina/CMakeLists.txt](https://github.com/quantOS-org/DataCore/blob/master/mdlink/src/mdlink/mdlink_sina/CMakeLists.txt) 42 | 43 | 新项目需要按照相同的方式处理,同时在linux和windows平台上编译成功才行。 44 | 45 | ## 如何开发 **mdlink-tencent** 46 | 47 | 整个开发建议分成三步: 48 | 49 | 1、分析一下 [新浪接口](http://qt.gtimg.cn/q=股票代码) 和 [腾讯接口](http://hq.sinajs.cn/list=股票代码) 之间的报文区别和对应关系,确定好报文结果的解析方法。 50 | 51 | 2、拷贝一份mdlink-sina,对文件名进行适当修改,在此基础上加入腾讯行情源的处理逻辑。 52 | 53 | 3、编译通过后,测试行情发布的正确性。 54 | 55 | -------------------------------------------------------------------------------- /dev/task-tick2bar.md: -------------------------------------------------------------------------------- 1 | 2 | # quantOS开源社区开放式开发任务书 tick2bar 3 | 4 | ## 需求概览 5 | 6 | 在目前的DataCore工程中,已经完美支持了实时行情的接收和处理,并由qms将实时行情转换成分钟线,供用户使用。 7 | 8 | qms同时记录和保存了所有的tick数据,位于data/tk目录下,按照市场分开存储,如下: 9 | 10 | ``` 11 | 617134798 Dec 14 15:20 SHF20171214.tk 12 | 62738353 Dec 14 16:34 CFE20171214.tk 13 | 391967678 Dec 14 15:00 CZC20171214.tk 14 | 424926986 Dec 14 15:03 DCE20171214.tk 15 | 1608054336 Dec 14 16:39 SH20171214.tk 16 | 2395156236 Dec 14 16:39 SZ20171214.tk 17 | ``` 18 | 19 | 目前遗留的问题是,用户无法通过DataCore获取历史分钟数据,历史tick。 20 | 21 | 我们提供的解决方案是: 22 | 23 | + 从每天存储的tick文件读取出所有的tick,转存成HDF5. 转换工具从这里[下载](https://www.quantos.org/datacore/download.html) 24 | + 从tick.H5文件合并分钟线,并保存成Bar.H5文件。 25 | + DataCore会发布一个模块,支持从HDF5中读取数据,提供历史tick,分钟线给用户使用。 26 | 27 | **_划重点_**: 28 | 29 | **本次的开发任务是,从tick.H5文件合并分钟线,并保存成Bar.H5文件** 30 | 31 | ## 开发要求 32 | 33 | 1. 本任务要求使用python开发。 34 | 35 | 2. 首先使用我们提供的TkReader,将SHF20171214.tk转换成SHF20171214.H5(HDF5格式,按标的存储,每个标的是一个DataFrame) 36 | 37 | 3. 通过python将SHF20171214.H5转换成分钟线(1m,5m,15m),存储成SHF20171214-1m.H5,SHF20171214-5m.H5,SHF20171214-15m.H5. 38 | 39 | 4. 分钟线计算的几个注意事项: 40 | + (1) 分钟线的open, high, low, close, volume, turnover指这个时间段的统计数据。 41 | + (2) 如果某个时间段内没有任何tick,需要用前一分钟的close补齐, volume和turnover为0。 42 | + (3) 1分钟bar的时间点标注是93100,93200,93300,。。。,113000,130100,130200,130300,。。。,150000. 43 | + (4) 其他分钟的时间点,规则参考1分钟。 44 | + (5) 商品期货国内有夜盘,夜盘分钟线也需要合成,商品期货夜盘时间统一为21:00-2:30,不到2:30就收盘的品种统一补齐到2:30。 45 | + (6) 分钟线里面的ask/bid信息,记录本时段内最后一笔tick的ask/bid信息。如果本时段没有任何tick,则全部为0. 46 | + (7) total_turnover和total_volume,记录截止该时段结束前该标的日内成交总量和成交总额,即该时段结束前收到的最后一笔tick的turnover和volume值。 47 | + (8) settle和oi同total_turnover和total_volume类似,取时段结束前收到的最后一笔tick的settle和oi值 48 | + (9) 中金所股指期货交易时间段为9:30-11:30, 13:00-15:00; 国债期货交易时间为9:15-11:30, 13:00-15:15 49 | + (10) 其他市场交易时间段参考mdlink/etc下的Market.csv文件 50 | + (11) 生成h5文件后可以用HDFView打开文件查看数据结构等 51 | 52 | 5. 增加偏移量选项(offset),单位为秒。生成分钟线的时间段做对应偏移,如offset=3, 则9:00:03-9:01:03之间的数据生成9:31:00的分钟线。 53 | 54 | 6. 转出的HDF5数据,保存目录结构如下: 55 | ``` 56 | /data/SHF/2017/SHF20171214-tk.H5 57 | /data/SHF/2017/SHF20171214-1M.H5 58 | /data/SHF/2017/SHF20171214-5M.H5 59 | /data/SHF/2017/SHF20171214-15M.H5 60 | ``` 61 | 这里的SHF是上期所,其他还包括SH,SZ,CFE,DCE,CZC 62 | 63 | 7. HDF5文件结构 64 | ``` 65 | SHF20171214-1m 66 | | cu1801.SHF (DataFrame保存分钟线) 67 | | cu1802.SHF (DataFrame保存分钟线) 68 | | au1801.SHF (DataFrame保存分钟线) 69 | | au1802.SHF (DataFrame保存分钟线) 70 | ``` 71 | 72 | tick数据每个标的的DataFrame包含的字段及其类型包括: 73 | 74 | |field |type |value | 75 | |-------------|----------|--------| 76 | |last |int64 |* 10000 | 77 | |vwap |int64 |* 10000 | 78 | |open |int64 |* 10000 | 79 | |high |int64 |* 10000 | 80 | |low |int64 |* 10000 | 81 | |close |int64 |* 10000 | 82 | |settle |int64 |* 10000 | 83 | |iopv |int64 |* 10000 | 84 | |limit_up |int64 |* 10000 | 85 | |limit_down |int64 |* 10000 | 86 | |preclose |int64 |* 10000 | 87 | |presettle |int64 |* 10000 | 88 | |oi |int64 | | 89 | |volume |int64 | | 90 | |turnover |int64 | | 91 | |date |int64 | | 92 | |trade_date |int64 | | 93 | |time |int64 | | 94 | |preoi |int64 | | 95 | |index |datetime | | 96 | |askprice1 |int64 |* 10000 | 97 | |askprice2 |int64 |* 10000 | 98 | |askprice3 |int64 |* 10000 | 99 | |askprice4 |int64 |* 10000 | 100 | |askprice5 |int64 |* 10000 | 101 | |bidprice1 |int64 |* 10000 | 102 | |bidprice2 |int64 |* 10000 | 103 | |bidprice3 |int64 |* 10000 | 104 | |bidprice4 |int64 |* 10000 | 105 | |bidprice5 |int64 |* 10000 | 106 | |askvolume1 |int64 | | 107 | |askvolume2 |int64 | | 108 | |askvolume3 |int64 | | 109 | |askvolume4 |int64 | | 110 | |askvolume5 |int64 | | 111 | |bidvolume1 |int64 | | 112 | |bidvolume2 |int64 | | 113 | |bidvolume3 |int64 | | 114 | |bidvolume4 |int64 | | 115 | |bidvolume5 |int64 | | 116 | 117 | 118 | 根据tick数据合成bar数据,字段如下: 119 | 120 | 121 | |field         |type     |value   | 122 | |---------------|----------|--------| 123 | |open           |int64     |* 10000 | 124 | |high           |int64     |* 10000 | 125 | |low |int64 |* 10000 | 126 | |close |int64 |* 10000 | 127 | |settle |int64 |* 10000 | 128 | |oi |int64 | | 129 | |volume |int64 | | 130 | |turnover |int64 | | 131 | |total_volume |int64 | | 132 | |total_turnover |int64 | | 133 | |date |int64 | | 134 | |trade_date |int64 | | 135 | |time |int64 | | 136 | |index |datetime | | 137 | |askprice1 |int64 |* 10000 | 138 | |askprice2 |int64 |* 10000 | 139 | |askprice3 |int64 |* 10000 | 140 | |askprice4 |int64 |* 10000 | 141 | |askprice5 |int64 |* 10000 | 142 | |bidprice1 |int64 |* 10000 | 143 | |bidprice2 |int64 |* 10000 | 144 | |bidprice3 |int64 |* 10000 | 145 | |bidprice4 |int64 |* 10000 | 146 | |bidprice5 |int64 |* 10000 | 147 | |askvolume1 |int64 | | 148 | |askvolume2 |int64 | | 149 | |askvolume3 |int64 | | 150 | |askvolume4 |int64 | | 151 | |askvolume5 |int64 | | 152 | |bidvolume1 |int64 | | 153 | |bidvolume2 |int64 | | 154 | |bidvolume3 |int64 | | 155 | |bidvolume4 |int64 | | 156 | |bidvolume5     |int64     |       | 157 | 158 | 159 | ## 招募开发达人 160 | 161 | 要求: 162 | 163 | + 有热情,志愿从事开源开发 164 | + 精通python,熟悉Pandas 165 | + 如果有一点关于K线的知识就更好了 166 | 167 | 联系方式: 168 | 169 | 在微信、QQ群@群主,要求加入开发即可。 170 | 171 | 参与开发的志愿者,将获得更多更深入的理论指导,并获得广泛的署名权。 172 | -------------------------------------------------------------------------------- /faq/faq.md: -------------------------------------------------------------------------------- 1 | # 常见问题 2 | 3 | 请使用`Ctrl + F`搜索。 4 | 5 | 6 | 1. 实盘支持哪些券商、通道? 7 | 8 | 答:quantOS系统使用vn.py进行实盘交易。vn.py已经实现了与国内各大主流交易系统的对接,可满足个人用户的单帐户交易要求。JAQS和vn.py之间通过TradeApi进行标准化对接,可做到仿真与实盘交易无缝对接。具体列表请见vnpy的gitbuh页面https://github.com/vnpy/vnpy。 9 | 10 | 2. quantOS的软件在哪里下载? 11 | 12 | 答:可以从github下载,地址为https://github.com/quantOS-org。 13 | 14 | 3. DataApi和TradeApi中的用户名密码和登录网站的用户名密码是什么关系? 15 | 16 | 答:两套用户名和密码相同。原来使用用户名和密码登录DataApi和TradeApi,改成使用token登录。 17 | 18 | 4. python-snappy的安装,为什么用pip就会报错? 19 | 20 | 答:请见官网JAQS安装指南 https://www.quantos.org/jaqs/doc.html 21 | 22 | 5. 能否支持使用TA-lib? 23 | 24 | 答:支持。 25 | 26 | 6. 若在国外没有中国手机如何注册? 27 | 28 | 答:现在只支持中国大陆手机号注册。 29 | 30 | 7. 哪里可以找到策略模型的示例? 31 | 32 | 答:策略模型样例请见jaqs-example文件夹,包括alpha策略,事件驱动策略。 33 | 34 | 8. 如何处理编码问题? 35 | 36 | 答:在程序头部加入一行 # encoding: utf-8。 37 | 38 | 9. 如何修改data_config和trade_config的密码配置? 39 | 40 | 答:请见quantOS用户登录指南,https://www.quantos.org/courses/index.html 41 | 42 | 10. 实时的tick数据如何获取?是否提供? 43 | 44 | 答:quantOS系统不提供tick数据。 45 | 46 | 11. 有没有将几大组件拼在一起的案例(包括tradesim仿真交易) 47 | 48 | 答:请见quantOSUserGuide中“两个量化交易策略样例”一节,地址为https://github.com/quantOS-org/quantOSUserGuide。 49 | 50 | 12. 目前提供的数据接口有那些?支持那些指数? 51 | 52 | 答:请见数据API的介绍文档,地址为https://www.quantos.org/jaqs/doc.html 53 | 54 | 13. 有么有专门针对商品期货的交易策略样例(包括Universe)? 55 | 56 | 答:请见jaqs-eventdriven中的CalendarSpread.py,DoubleMA.py,DualThrust.py策略。 57 | 58 | 14. tusharepro是否收费? 59 | 60 | 答:不收费 61 | 62 | 15. 回测结果的统计指标哪里看?都有那些? 63 | 64 | 答:回测的统计指标包括年化收益率,年化波动率,beta值和Sharpe ratio,在策略相应的report.html中可以看到。 65 | 66 | 16. TradeSim是否支持期权模拟?如何使用? 67 | 68 | 答:支持。 69 | 70 | 17. 外盘交易支持吗? 71 | 72 | 答:具体列表请见vnpy的gitbuh页面https://github.com/vnpy/vnpy。 73 | 18. 如何安装`python-snappy`包? 74 | 75 | 见[如何安装python-snappy包](https://github.com/quantOS-org/JAQS/blob/master/doc/install.md#如何安装python-snappy包) 76 | 77 | 19. 关于价格的复权 78 | 79 | 股票Alpha策略回测框架`AlphaBacktestInstance`使用真实价格回测,自动对除权除息进行调整,详见[JAQS策略系统解析](https://github.com/quantOS-org/quantOSUserGuide/blob/master/jaqs.md);事件驱动择时策略回测框架`EventBacktestInstance`在日线回测时,数据来自`data_api.daily`接口,可以自选复权方式,目前默认使用后复权,防止计算均线等指标出错,在分钟线回测时,均为真实价格。   80 | 价格后复权的计算方法是从取数据的`start_date`作为复权起始日,所以不同的`start_date`会导致不同的价格序列,但不影响每日收益的正确性。 81 | 82 | 20. 为何数据API总是返回`-1,no_connection` 83 | 84 | 可能是使用者所处网络环境有相关限制,可使用telnet工具测试数据IP端口是否畅通 85 | 86 | 21. 很多调用返回的`msg`/`err_msg`是什么 87 | 88 | 这是报错信息,格式为数字+逗号+信息,数字0表示无报错,其他表示有错误发生;逗号用于分隔;信息为错误内容。如无报错通常为`0,`,登录失败为`-1,LOGIN FAILURE` 89 | 90 | -------------------------------------------------------------------------------- /jaqs.md: -------------------------------------------------------------------------------- 1 | # JAQS策略系统 2 | 3 | ## JAQS能做什么 4 | 5 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/procedure.png?raw=true) 6 | 7 | 策略开发的完整流程一般是以下四步的循环往复,JAQS在这四步都提供了支持: 8 | 9 | 1. **数据**收集处理:我们提供了标准接口`DataApi`, 便利接口`DataService`, 高效工具`DataView` 10 | 11 | 2. 对数据进行**研究**:我们提供进行信号/事件研究的`SignalDigger` 12 | 13 | 3. 根据研究结果开发策略并**回测**:我们提供两种策略回测框架,Alpha选股和事件驱动择时(如CTA、套利) 14 | 15 | 4. 对回测结果进行**分析**:我们提供直观简洁的报告`Report`,以及分析内容丰富、可进一步开发的分析器`Analyzer` 16 | 17 | ## 数据收集处理的三重境界 18 | 19 | ### 一重境界:使用标准的DataApi 20 | 21 | `DataApi`是用Python实现的的api调用接口,从在线数据平台查询并返回`DataFrame`格式的数据和消息,采用预定义的标准接口格式和数据格式,是最基础的数据查询方式。 22 | 23 | 以指数成分查询为例: 24 | 25 | ```py 26 | res, msg = data_api.query(view="lb.indexCons", 27 | fields="", 28 | filter="index_code=000300.SH&start_date=20150101&end_date=20170901", 29 | orderby="symbol") 30 | ``` 31 | 32 | 详细文档,参见[这里](http://www.quantos.org/jaqs/doc.html) 33 | 34 | ### 二重境界:使用较方便的DataService 35 | 36 | `DataService`专为JAQS设计,它仍利用`DataApi`的接口进行查询,但对一些常用功能进行了封装,调用起来更加方便。 37 | 38 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/data_service_api.png?raw=true) 39 | 40 | 例如,指数成分查询命令为: 41 | 42 | ```py 43 | res = data_service.get_index_comp(index='000300.SH', start_date=20150101, end_date=20170901) 44 | ``` 45 | 46 | 比使用`DataApi`简化了很多。 47 | 48 | 详细文档,参见代码注释。 49 | 50 | ### 三重境界:使用神器DataView 51 | 52 | `DataView`可以理解为一个针对具体研究对象的小型数据库。可以方便地构建、增删、查询、存储读取等。 53 | 54 | #### 亮点 55 | 56 | * 极简数据获取:不需要记忆API调用方法,只需要给出字段名称,即可自动通过对应API查询市场数据与基础数据 57 | 58 | * 极简数据调用:时间序列数据、截面数据、面板数据 59 | 60 | * 自动数据对齐:市场数据根据交易日对齐,财务数据根据财报发布时间对齐 61 | 62 | * 衍生数据计算:通过输入数学公式,可自动调用内置函数计算Rank, Quantile, MA, Max等 63 | 64 | * 易用数据存取:存储、读取只需提供路径 65 | 66 | 有了这些特色,使用`DataView`就像拥有了一个数据助理,告诉他需求,就能全部收集、整理好交给你。例如,下面短短几行代码,就完成了自动获取沪深300成份股从2015年1月1日到2017年9月1日的数据,包括是否属于指数成分、成分权重、申万二级行业分组、OHLC价格、成交量成交额、每股收益、ROE,并对这些数据做了对齐操作,存储在`'save_folder'`文件夹内。 67 | 68 | ```py 69 | props = {'start_date': 20150101, 'end_date': 20170901, 'universe': '000300.SH', 70 | 'fields': ('open,high,low,close,vwap,volume,turnover,eps_basic,roe,sw2' 71 | ), 72 | 'freq': 1} 73 | 74 | dv = DataView() 75 | dv.init_from_config(props, ds) 76 | dv.prepare_data() 77 | 78 | dv.save_dataview('save_folder') 79 | ``` 80 | 81 | 详细文档,参见[这里](http://www.quantos.org/jaqs/doc.html)。 82 | 83 | ## 信号研究与事件研究 84 | 85 | 对投资机会的识别和对未来的预测是投资的基础,这就涉及到各种各样的**信号**。成交量和成交价的相关系数可以作为信号,股价是否创出半年新高也可以作为信号。 86 | 87 | _注:此处我们所讲的信号指Alpha策略研究中的信号_ 88 | 89 | 很多时候我们希望对信号进行快速的测试,JAQS提供`SignalDigger`作为测试、研究信号的工具。它根据每天横截面上所有股票的信号及价格,对信号的收益预测能力、信息比率(IC)等进行分析,包括并不仅限于: 90 | 91 | * 分组每日收益 92 | 93 | * 分组累计收益 94 | 95 | * 纯多头组合收益 96 | 97 | * 纯空头组合收益 98 | 99 | * 多空每日收益差别 100 | 101 | * 多空组合累计收益 102 | 103 | * 每日IC 104 | 105 | * IC分布 106 | 107 | * 月度IC 108 | 109 | * 事件发生后n天平均收益、分布等 110 | 111 | ### 收益分析报告 112 | 113 | ![](https://raw.githubusercontent.com/quantOS-org/jaqs/master/doc/img/returns_report.png?raw=true) 114 | 115 | _注:目前的收益分析方式是根据因子值对股票池内股票分组,后续我们会提供基于截面回归的方式。_ 116 | 117 | ### 信息系数分析报告 118 | 119 | ![](https://raw.githubusercontent.com/quantOS-org/jaqs/master/doc/img/ic_report.png?raw=true) 120 | 121 | ### 事件分析报告 122 | 123 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/event_report.png?raw=true) 124 | 125 | ## 策略回测 126 | 127 | ### Alpha策略回测 128 | 129 | #### 我们对Alpha策略的定义 130 | 131 | * 在一个股票**池**内进行投资 132 | 133 | * 衡量投资业绩的基准是股票池的指数或其他某个指数,投资收益与基准收益之差称作**超额收益** 134 | 135 | * 通过对股票池内投资标的及投资多少进行**选择**,以此追求超额收益 136 | 137 | #### 股票Alpha回测中的坑 138 | 139 | * 未来函数 140 | 141 | * 选股时用到了当天收盘价,却以开盘价进行买卖。 142 | 143 | * 三季报10月底才发布,却在10月初用这个数据进行选股。 144 | 145 | * 停牌没有检测股票是否停牌,在停牌期间进行买卖操作。 146 | 147 | * 涨跌停买入开盘涨停的股票或卖出开盘跌停的股票。 148 | 149 | * 除权除息由于分红、配送股等原因,股价或持仓量发生变化,却未做出相应调整。 150 | 151 | * 指数成分指数(如沪深300)成分是每天动态变化的,2014年1月沪深300中的300支股票,到了2017年可能只有不到200支留在沪深300中。如果只使用静态股票池,无论是用2014年的还是2017年的,都会导致问题。 152 | 153 | * 退市在退市前有持仓,且没有卖出,一直持有下去或在退市后以错误的价格卖出。 154 | 155 | 坑之所以成为坑,是因为总有人前赴后继地往里掉。相比浪费大量时间一个个掉下去、爬上来,不如站在巨人肩头,从一开始就避免这常见问题。JAQS的Alpha策略回测系统已实现对以上问题的**自动处理**,帮大家避坑: 156 | 157 | * 未来函数:任何一天,只提供截止当天的数据 158 | 159 | * 停牌:自动过滤停牌 160 | 161 | * 涨跌停:自动过滤涨跌停 162 | 163 | * 指数成分:使用日频动态指数成分,自动过滤非成份股 164 | 165 | * 除权除息:以真实价格成交,发生除权除息时默认进行再投资对仓位做相应调整,与真实情况一致 166 | 167 | * 退市:在股票退市前,将其仓位清空 168 | 169 | #### JAQS想解决的问题 170 | 171 | 1. 想到/听到一个不错的想法,花1小时将其转化为策略,却**浪费1天甚至好几天实现策略**,错过了机会、消散了激情:JAQS把重复的数据处理、回测逻辑替大家做好,回测时可专注于策略本身 172 | 173 | 2. 使用在线网站或其他研究性编程语言(MATLAB、R等)初步测试了策略,却难以实现对**细节的控制**及进一步的**自定义开发**,也难以方便地对接行情数据和交易系统:JAQS作为可完全本地化运行的开源软件,使用者具有完全的控制力;同时JAQS作为quantOS的一员,可直接接入DataCore数据系统、TradeSim模拟交易及实盘交易系统。 174 | 175 | #### 用JAQS实现Alpha策略 176 | 177 | 无论是用什么方法来做策略,最终都归结于**在每只股票上的权重是多少**这个问题,我们的回测框架正是基于此,使用者只需在每次调仓时求得**一系列权重**,其中每个值代表在对应股票上的权重。这一步是策略的核心,至于具体的回测逻辑和发单成交,则已由回测框架代劳,一般不需考虑(\#TODO 这一句怎么写比较好)。 178 | 179 | 更具体来说,我们把求得权重这一过程,分为**两个子过程**: 180 | 181 | 1. 对股票池进行筛选 182 | 183 | 2. 给筛选后的股票池中的股票赋予权重 184 | 185 | 在实现上,我们遵循**模块化设计**的原则,通过定义函数来实现以上子过程,格式为: 186 | 187 | ```py 188 | # 函数头固定为context和user_options,前者存储了一些全局变量,后者是用户自定义的参数 189 | def selection_function(context, user_options=None): 190 | # context.snapshot为DataFrame类型,内存储了当前交易日股票池内所有标的、所有字段的数据 191 | # 我们取出'total_profit_growth'这一字段,并赋值给growth_rate变量(数据类型为Seires),以备使用 192 | growth_rate = context.snapshot['total_profit_growth'] 193 | # 我们要求增长率growth_rate大于5%,condition是一个值为bool类型的Series 194 | condition = growth_rate > 0.05 195 | # 返回值固定为一个Series,index为股票代码,value为True or False,True表示选中该股票,False表示不选 196 | return condition 197 | ``` 198 | 199 | ```py 200 | # 函数头固定为context和user_options,前者存储了一些全局变量,后者是用户自定义的参数 201 | def weight_function(context, user_options=None): 202 | # context.snapshot_sub为DataFrame类型,内存储了当前交易日【筛选后】股票池内所有标的、所有字段的数据 203 | # 我们取出'total_mv'这一字段,并赋值给market_value变量(数据类型为Seires),以备使用 204 | market_value = context.snapshot_sub['total_mv'] 205 | # 我们令权重为总市值(market_value)的相反数,即市值越小,买的越多 206 | weights = 1.0 / market_value 207 | # 返回值固定为一个Series,index为股票代码,value为float,数值大小代表权重大小 208 | return weights 209 | ``` 210 | 211 | 此外,使用者也可以将自己研究得到的目标仓位它存入`context`中,直接在权重函数中返回,达到按自定义仓位回测的目的。 212 | 213 | 214 | 215 | ### 择时策略回测 216 | 217 | #### 我们对择时策略的定义 218 | 219 | 择时即“选择时机“,依据是数据。也即不断根据最新的市场数据,做出交易决策。这里可以与Alpha策略做一对比: 220 | 221 | * Alpha策略总是有持仓,而择时策略不一定随时都有持仓。 222 | 223 | * Alpha策略以权重为目标,构建投资组合,而择时策略既可能以持仓为目标,也可能以买/卖量为目标。 224 | 225 | #### 择时策略如何运行 226 | 227 | * 实盘时,策略通过`on_data`接收数据系统发来的最新行情信息,并进行决策。 228 | 229 | * 回测时,遍历历史数据(日线/分钟线/tick),并调用策略的`on_data`,以模拟实盘情况。 230 | 231 | _注:为了处理不同频率的数据,`on_data`实际上分为`on_tick`和`on_quote`,前者负责处理Bar类型数据,后者负责处理Tick类型数据。因为Bar数据可以进行对齐,而Tick数据一般难以对齐。_ 232 | 233 | #### JAQS解决的问题 234 | 235 | * 事件驱动引擎:满足大部分非高频策略的需求。 236 | 237 | * 简洁的策略框架:集成父类`EventDrivenStrategy`,修改几个关键函数,即可写出自己的策略。 238 | 239 | * 回测与实盘一致性: 240 | 241 | 择时策略不像Alpha策略逻辑简单清晰(算权重、发单、成交),每一个决策都前后关联,因而此类策略回测的一个重点就是回测与实盘的一致性。由于数据精度、市场冲击等因素,完全一致是不可能的,只能做到尽量一致,包括 242 | 243 | * 代码一致性:回测所用的策略代码,可以少修改甚至不修改上实盘 244 | 245 | JAQS的运行主程序以及交易API都实现了回测和实盘两个版本,回测过的策略,无需修改策略逻辑,可**直接切换**到实盘运行。 246 | 247 | * 结果一致性:同一段时间,回测的模拟交易结果,应和实盘运行相同策略的交易结果接近甚至相同 248 | 249 | JAQS的择时策略回测实现了撮合器,可根据订单类型模拟撮合成交。 250 | 251 | #### 用JAQS实现择时策略 252 | 253 | 前文已经讲到,择时策略回测是对历史数据的遍历,因而要实现一个策略,主要是实现`on_data`函数,例如: 254 | 255 | ```py 256 | # 我们使用Bar数据回测,因而用`on_bar`而不是`on_tick` 257 | # on_bar作为策略类的一个成员函数,因而有`self`参数 258 | # `bar`是接收到的行情,含有高开低收、成交量等信息 259 | def on_bar(self, bar): 260 | price = bar.close # Bar的close价格 261 | symbol = bar.symbol # 标的代码 262 | if price < 11: 263 | buy_size = 1 # 购买1手/股 264 | # 调用trade_api进行发单 265 | self.ctx.trade_api.place_order(symbol, 'Buy', price + 2, buy_size) 266 | ``` 267 | 268 | 这个函数实现了当价格低于11时,以(价格+2)买1手/股标的策略。 269 | 270 | 除了`on_data`外,还需要实现初始化函数`initialize`, 成交回报函数`on_trade`等,具体参见[本手册第一章]()。 271 | 272 | ### 回测结果保存 273 | 274 | 回测结果指成交信息和配置信息。Alpha策略和择时策略均使用统一的方法将这些信息本地保存,以备分析。 275 | 276 | ```py 277 | # backtest_instance是运行回测的主程序, folder_path是要保存的目录 278 | backtest_instance.save_results(folder_path) 279 | ``` 280 | 281 | 调用`save_results`后,成交信息会保存为`trades.csv`文件,配置信息保存为`props.json`文件。由于策略盈亏完全由成交决定,所以基于这些标准化的成交信息,我们在分析时即可复原所有的成交、持仓、盈亏信息。 282 | 283 | ## 回测/交易结果分析 284 | 285 | ### 回测结果 286 | 287 | 上一部分说到,回测后,会把成交信息会保存为`trades.csv`文件,配置信息保存为`props.json`文件。由于策略盈亏完全由成交决定,所以基于这些标准化的成交信息,我们即可复原所有的成交、持仓、盈亏信息。 288 | 289 | 成交信息格式如下: 290 | 291 | | index | commission | entrust\_action | entrust\_no | fill\_date | fill\_no | fill\_price | fill\_size | fill\_time | symbol | task\_id | 292 | | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | 293 | | 0 | 0.0 | Buy | 56 | 20170103 | 201701030001 | 7.22 | 201000.0 | 143000 | 601111.SH | 201701030001 | 294 | | 1 | 0.0 | Buy | 54 | 20170103 | 201701030002 | 29.38 | 49300.0 | 143000 | 600754.SH | 201701030001 | 295 | | 2 | 0.0 | Buy | 42 | 20170103 | 201701030003 | 26.65 | 54400.0 | 143000 | 600009.SH | 201701030001 | 296 | 297 | 可以看到其中只有成交价、成交量、成交方向等基本信息。 298 | 299 | ### 结果分析 300 | 301 | 我们使用`Analyzer`模块读取基本成交信息,并结合价格信息分析。 302 | 303 | 对于每一笔交易,`Analyzer`计算: 304 | 305 | * 买量BuyVolume, 卖量SellVolume, 总成交量CumVolume, 总成交额CumTurnOver 306 | 307 | * 仓位position 308 | 309 | * 平均持仓成本AvgPosPrice 310 | 311 | * 手续费commission 312 | 313 | 对于每天的交易情况,除了以上信息的每日加总,每个标的的收盘价,`Analyzer`还会求出 314 | 315 | * 交易盈亏trading\_pnl 316 | 317 | * 持仓盈亏holding\_pnl 318 | 319 | * 总盈亏total\_pnl 320 | 321 | 此外,我们还提供了预置的画图函数,画出策略pnl,及在每个标的上的具体买卖情况. 322 | 323 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/pnl_img2.png?raw=true) 324 | 325 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/plot_trades.png?raw=true) 326 | 327 | ### 报告生成 328 | 329 | `Analyzer`分析完毕后,会把主要信息(如PnL)保存,生成HTML格式的回测报告。 330 | 331 | 报告由`Report`对象调用`Jinja2`包通过模板生成,使用者可以自定义模板,添加关心的指标,生成属于个性化的回测报告。 332 | 333 | -------------------------------------------------------------------------------- /jaqs/backtest_framework.md: -------------------------------------------------------------------------------- 1 | # JAQS回测框架介绍 2 | 3 | JAQS有`jaqs.data`, `jaqs.research`, `jaqs.trade`, `jaqs.util`几个模块,其中回测、仿真、实盘交易都在交易模块`jaqs.trade`中实现,本文主要介绍JAQS完成**回测**所需的各个子模块。 4 | 5 | ## 回测所需模块分析 6 | 7 | 我们把回测拆分为回测实例、策略、仓位管理、交易系统这4个子模块,下面来解释为什么: 8 | 9 | 首先,任何简单或复杂的策略的运行,都包含**决策**和**执行**这两个方面。决策即**在什么时候做什么事**,比如”当股票价格低于10元时购买200股“,”当两个期货合约价差达到3000元时卖出高价合约买入低价合约“,”每分钟按市价买入1000股股票,直到持仓为8000股“,”当模型预测小于-3时卖出对应标的“。执行即**将决策付诸实施**,通常需按一定规则来做,比如发送特定数据类型的一串信息,按顺序包含标的代码、订单类型、订单方向、订单价格、订单数量等。交易所规定的通信方式往往比较复杂,也更偏底层,而且不同交易所的规则可能不同,我们不希望在实现策略时费心考虑”我在交易哪个交易所的哪个品种“,”有哪些指令可以使用“这样的问题,因此自然地,我们会**把决策和执行分开**。分开后,前者称为交易策略,从较抽象的层面实现我们的想法;后者称为交易系统,专门负责把各种各样的决策用交易所接受的方式执行。 10 | 11 | 现在我们知道需要**交易策略**和**交易系统**两个模块,接下来我们继续拆分交易策略。 12 | 13 | 对于全自动运行的程序化交易策略,**持仓管理**十分重要,策略需要这些信息辅助决策,交易员也需要这些信息来进行监控。这里所说的持仓管理包括已发出订单的记录、撤销订单的记录、成交记录、仓位更新等,这些信息的更新与管理方式往往是固定的,如当前持仓量总是根据成交回报而更新。因此这些固定的操作也应抽象为一个子模块——**持仓管理模块**。 14 | 15 | 策略往往有参数,例如一个用到均线的策略,就需要设置均线的长度(5日、10日等),在运行策略前,需要初始化相关变量并读入这些参数配置。参数值是策略的一部分,但**读取参数**这个步骤则是固定的。除此之外,还有链接数据库、连接交易系统、按一定顺序启动并初始化各个模块等步骤,都应该从策略中分离出来。我们把这些步骤放置于**交易实例模块**中。回测时,我们还额外需要取出历史数据,模拟实盘的方式把数据交给策略,并把策略产生的订单模拟撮合,这些流程性的东西同样放在实例模块中。由于实盘与回测在这些流程上有所差异,我们分别实现了**回测实例模块**与**实盘实例模块**。 16 | 17 | 上文提到了交易系统,策略和交易系统间需要一套标准的方式来交互,即一套**API**;对于回测,需要对订单进行**模拟撮合**,因而还需要**撮合器。** 18 | 19 | 最后,为了满足模块间的相互访问及存储全局变量的需要, 20 | 21 | 作一**总结**,完成回测总共需要以下模块: 22 | 23 | - 回测实例`BackestInstance` 24 | - 策略`Strategy` 25 | - 持仓管理`PortfolioManager` 26 | - 交易API `TradeApi` 27 | - 模拟撮合器`Simulator` 28 | - 运行上下文`Context` 29 | 30 | ## 回测示例代码 31 | 32 | 下面这段代码来自[双均线策略示例](https://github.com/quantOS-org/JAQS/blob/master/example/eventdriven/DoubleMA.py)。 33 | 34 | ```python 35 | tapi = BacktestTradeApi() # 交易API 36 | ins = EventBacktestInstance() # 回测实例 37 | ds = RemoteDataService() # 数据API 38 | strat = DoubleMaStrategy() # 策略示例 39 | pm = PortfolioManager() # 持仓管理 40 | 41 | # 运行上下文,包含数据API,交易API,策略,持仓管理,回测实例 42 | context = model.Context(data_api=ds, trade_api=tapi, 43 | strategy=strat, pm=pm 44 | instance=ins) 45 | 46 | # 策略配置参数字典(为简化代码,未展示所有参数) 47 | props = { 48 | "symbol" : '600519.SH', 49 | "start_date" : 20170101, 50 | "end_date" : 20171104, 51 | "init_balance" : 50000 52 | } 53 | ins.init_from_config(props) # 从配置字典中初始化回测实例 54 | 55 | ins.run() # 调用回测实例的run方法,运行回测 56 | 57 | ins.save_results(folder_path=result_dir_path) # 调用回测示例的save_results方法,存储回测结果 58 | ``` 59 | 60 | 61 | 62 | ## 参考资料 63 | 64 | FIX: https://www.fixtrading.org/ 65 | 66 | -------------------------------------------------------------------------------- /jaqs/dataview_formula.md: -------------------------------------------------------------------------------- 1 | # DataView的formula相关 2 | 3 | ## `DataView`简介 4 | 5 | `DataView`本质是一个**数据存储器**,一个研究可能只使用一个`DataView`,用以保证数据在使用过程中的**一致性**。同时,`DataView`也**封装**了增、删、改、查、I/O等操作,增加**便利性**。 6 | 7 | ## Formula相关 8 | 9 | ### 设计`add_formula`接口的原因 10 | 11 | 由数据库取到的数据构建而成的`DataView`,只含有数据提供商所提供的数据,而对这些数据进行清洗、进而构造各种各样的**衍生**数据、指标、信号是研究和回测中非常常用的。纯粹的存储器只提供数据出入的接口,如果需要添加衍生数据,需要取出原始数据,计算后再放回存储器中;而`DataView`还提供了`add_formula`接口,让用户可以通过**传入数学公式的方式,流程化、自动化地进行数据计算、对齐并添加到`DataView`中**。 12 | 13 | `add_formula`的signature为`void add_formula(new_field_name, formula, is_quarterly)`。`new_field_name`为字符串,是给运算结果的命名;`is_quarterly`为bool值,表示公式运算结果是日频率还是季度频率(目前只支持这两种频率)`formula`是用字符串表示的数学公式。抽象来看`formula`具有以下形式: 14 | $$ 15 | f( x_1, x_2, \dots, x_n) 16 | $$ 17 | 其中$f$是下方列表中支持的运算或函数,$x_i$为`DataView`中已经存在的字段名。 18 | 19 | ### formula运算时的几个默认操作 20 | 21 | 1. 指数成分:`DataView`中包含一段时间内universe的所有股票,但每天universe的股票是变化的,在进行一些横截面运算时(如排序),会先将当天非指数成分的数据置为NaN,再运算 22 | 2. 季度数据的自动展开和对齐:当不同频率的数据一起运算时,会将季度数据按照公布日期(ann_date)展开并对齐到交易日,再和日频数据运算。 23 | 24 | ### 公式支持的运算、函数说明 25 | 26 | | 分类 | 说明 | 公式 | 示例 | 27 | | ----------------- | ---------------------------------------- | ------------------------------- | ---------------------------------------- | 28 | | 四则运算 | 加法运算 | + | close + open | 29 | | 四则运算 | 减法运算 | - | close - open | 30 | | 四则运算 | 乘法运算 | * | vwap * volume | 31 | | 四则运算 | 除法运算 | / | close / open | 32 | | 基本数学函数 | 符号函数,返回值为{-1, 0, 1} | Sign(x) | Sign(close-open) | 33 | | 基本数学函数 | 绝对值函数 | Abs(x) | Abs(close-open) | 34 | | 基本数学函数 | 自然对数 | Log(x) | Log(close/open) | 35 | | 基本数学函数 | 对x取负 | -x | -close | 36 | | 基本数学函数 | 幂函数 | ^ | close ^ 2 | 37 | | 基本数学函数 | 幂函数x^y | Pow(x,y) | Pow(close,2) | 38 | | 基本数学函数 | 保持符号的幂函数,等价于Sign(x) * (Abs(x)^e) | SignedPower(x,e) | SignedPower(close-open, 0.5) | 39 | | 基本数学函数 | 取余函数 | % | oi % 10 | 40 | | 逻辑运算 | 判断是否相等 | == | close == open | 41 | | 逻辑运算 | 判断是否不等 | != | close != open | 42 | | 逻辑运算 | 大于 | > | close > open | 43 | | 逻辑运算 | 小于 | < | close < open | 44 | | 逻辑运算 | 大于等于 | >= | close >= open | 45 | | 逻辑运算 | 小于等于 | <= | close <= open | 46 | | 逻辑运算 | 逻辑与 | && | (close > open) && (close > vwap) | 47 | | 逻辑运算 | 逻辑或 | | | 48 | | 逻辑运算 | 逻辑非 | ! | !(close>open) | 49 | | 逻辑运算 | 判断值是否为NaN | IsNan(x) | IsNan(net_profit) | 50 | | 三角函数 | 正弦函数 | Sin(x) | Sin(close/open) | 51 | | 三角函数 | 余弦函数 | Cos(x) | Cos(close/open) | 52 | | 三角函数 | 正切函数 | Tan(x) | Tan(close/open) | 53 | | 三角函数 | 开平方函数 | Sqrt(x) | Sqrt(close^2 + open^2) | 54 | | 取整函数 | 向上取整 | Ceil(x) | Ceil(high) | 55 | | 取整函数 | 向下取整 | Floor(x) | Floor(low) | 56 | | 取整函数 | 四舍五入 | Round(x) | Round(close) | 57 | | 选择函数 | 取 x 和 y 同位置上的较大值组成新的DataFrame返回 | Max(x,y) | Max(close, open) | 58 | | 选择函数 | 取 x 和 y 同位置上的较小值组成新的DataFrame返回 | Min(x,y) | Min(close,open) | 59 | | 选择函数 | cond为True取x的值,反之取y的值 | If(cond,x,y) | If(close > open, close, open) 表示取open和close的较大值 | 60 | | 时间序列函数 - 基本数学运算 | 指标n个周期前的值 | Delay(x,n) | Delay(close,1) 表示前一天收盘价 | 61 | | 时间序列函数 - 基本数学运算 | 指标在过去n天的和 | Ts_Sum(x,n) | Sum(volume,5) 表示一周成交量 | 62 | | 时间序列函数 - 基本数学运算 | 指标在过去 n 天的积 | Ts_Product(x,n) | Product(close/Delay(close,1),5) - 1 表示过去5天累计收益 | 63 | | 时间序列函数 - 基本数学运算 | 指标当前值与n天前的值的差 | Delta(x,n) | Delta(close,5) | 64 | | 时间序列函数 - 基本数学运算 | 计算指标相比n天前的变化率,默认计算百分比变化率;当log为1是,计算对数变化率 | Return(x,n,log) | Return(close,5,True)计算一周对数收益 | 65 | | 时间序列函数 - 基本数学运算 | 计算指标在过去n天的平均值 | Ts_Mean(x,n) | Ts_Mean(close,5) | 66 | | 时间序列函数 - 统计 | 指标在过去n天的标准差 | StdDev(x,n) | StdDev(close/Delay(close,1)-1, 10) | 67 | | 时间序列函数 - 统计 | 两个指标在过去n天的协方差 | Covariance(x,y,n) | Covariance(close, open, 10) | 68 | | 时间序列函数 - 统计 | 两个指标在过去n天的相关系数 | Correlation(x,y,n) | Correlation(close,open, 10) | 69 | | 时间序列函数 - 统计 | 计算指标在过去n天的最小值 | Ts_Min(x,n) | Ts_Min(close,5) | 70 | | 时间序列函数 - 统计 | 计算指标在过去n天的最大值 | Ts_Max(x,n) | Ts_Max(close,5) | 71 | | 时间序列函数 - 统计 | 计算指标在过去n天的偏度 | Ts_Skewness(x,n) | Ts_Skewness(close,20) | 72 | | 时间序列函数 - 统计 | 计算指标在过去n天的峰度 | Ts_Kurtosis(x,n) | Ts_Kurtosis(close,20) | 73 | | 时间序列函数 - 排名 | 计算指标在过去n天的排名,返回值为名次 | Ts_Rank(x, n) | Ts_Rank(close, 5) | 74 | | 时间序列函数 - 排名 | 计算指标在过去n天的百分比,返回值为[0.0, 1.0] | Ts_Percentile(x, n) | Ts_Percentile(close, 5) | 75 | | 时间序列函数 - 排名 | 计算指标在过去n天所属的quantile,返回值为表示quantile的整数 | Ts_Quantile(x, n) | Ts_Quantile(close, 5) | 76 | | 时间序列函数 - 排名 | 指数移动平均,以halflife的衰减对x进行指数移动平均 | Ewma(x, halflife) | Ewma(x, 3) | 77 | | 横截面函数 - 排名 | 将指标值在横截面方向排名,返回值为名次 | Rank(x) | Rank( close/Delay(close,1)-1 ) 表示按日收益率进行排名 | 78 | | 横截面函数 - 排名 | 按分组数据g在每组内将指标值在横截面方向排名,返回值为名次 | GroupRank(x,g) | GroupRank(close/Delay(close,1)-1, g) 表示按分组g根据日收益率进行分组排名 | 79 | | 横截面函数 - 排名 | 将指标值在横截面方向排名,返回值为排名百分比 | Percentile(x) | Percentile(close, sw1) 按申万1级行业 | 80 | | 横截面函数 - 排名 | 按分组数据g在每组内将指标值在横截面方向排名,返回值为排名百分比 | GroupPercentile(x, g, n) | | 81 | | 横截面函数 - 排名 | 和Rank函数相同,但只有 cond 中值为True的标的参与排名 | ConditionRank(x, cond) | GroupRank(close/Delay(close,1)-1, cond) 表示按条件cond根据日收益率进行分组排名 | 82 | | 横截面函数 - 排名 | 根据指标值在横截面方向将标的分成n个quantile,返回值为所属quantile | Quantile(x, n) | Quantile( close/Delay(close,1)-1,5)表示按日收益率分为5档 | 83 | | 横截面函数 - 排名 | 按分组数据g在每组内根据指标值在横截面方向将标的分成n个quantile,返回值为所属quantile | GroupQuantile(x, g, n) | GroupQuantile(close/Delay(close,1)-1,g,5) 表示按日收益率和分组g进行分档,每组分为5档 | 84 | | 横截面函数 - 数据处理 | 将指标标准化,即在横截面上减去平均值后再除以标准差 | Standardize(x) | Standardize(close/Delay(close,1)-1) 表示日收益率的标准化 | 85 | | 横截面函数 - 数据处理 | 将指标横截面上去极值,用MAD (Maximum Absolute Deviation)方法, z_score为极值判断标准 | Cutoff(x, z_score) | Cutoff(close,3) 表示去掉z_score大于3的极值 | 86 | | 财报函数 | 将累计财务数据转换为单季财务数据 | CumToSingle(x) | CumToSingle(net_profit) | 87 | | 财报函数 | 从累计财务数据计算TTM的财务数据 | TTM(x) | TTM(net_profit) | 88 | | 其他 | 过去 n 天的指数衰减函数,其中 f 是平滑因子。这里 f 是平滑因子,可以赋一个小于 1 的值。Decay_exp(x, f, n) = (x[date] + x[date - 1] * f + … +x[date – n - 1] * (f (n – 1))) / (1 + f + … + f ^ (n - 1)) | Decay_exp(x,f,n) | Decay_exp(close,0.9,10) | 89 | | 其他 | 过去n天的线性衰减函数。Decay_linear(x, n) = (x[date] * n + x[date - 1] * (n - 1) + … + x[date – n - 1]) / (n + (n - 1) + … + 1) | Decay_linear(x,n) | Decay_linear(close,15) | 90 | | 其他 | 如果 x 的值介于 lower 和 upper,则将其设定为 newval | Tail(x, lower, upper, newval) | Tail(close/open, 0.99, 1.01, 1.0) | 91 | | 其他 | Step(n) 为每个标的创建一个向量,向量中 n 代表最新日期,n-1 代表前一天,以此类推。 | Step(n) | Step(30) | 92 | | 其他 | 时间序列函数,计算 x 中的值在过去 n 天中为 nan (非数字)的次数 | CountNans(x,n) | CountNans((close-open)^0.5, 10) 表示过去10天内有几天close小于open | 93 | 94 | ***注:*** 95 | 96 | - 时间序列函数计算结果由该指标过去n个值计算得来 97 | - 横截面函数由同一天所有标的的同一个指标值计算得来 98 | 99 | -------------------------------------------------------------------------------- /jaqs/dataview_function_list.md: -------------------------------------------------------------------------------- 1 | | 分类 | 函数名 | 作用 | 2 | |------------|------------------|--------------------------------------| 3 | | 准备数据 | init_from_config | 读取配置 | 4 | | 准备数据 | prepare_data | 从服务器下载数据并自动处理 | 5 | | 添加字段 | add_field | 从服务器获取一个数据库中存在的数据 | 6 | | 添加字段 | add_formula | 根据公式计算结果增加一个字段 | 7 | | 添加字段 | append_df | 提供一个DataFrame作为新的字段 | 8 | | 删除字段 | remove_field | 删除已存在的一个字段 | 9 | | 取数据 | get | 最一般的取数据方式 | 10 | | 取数据 | get_ts | 取出某个字段,所有标的所有时间的数据 | 11 | | 取数据 | get_snaphot | 取出某个时间,所有标的所有字段的数据 | 12 | | 本地化存储 | save_dataview | 将dataview的数据存储于目标文件夹内 | 13 | | 本地化存储 | load_dataview | 从目标文件夹读取dataview | 14 | -------------------------------------------------------------------------------- /jaqs/query_data_function_list.md: -------------------------------------------------------------------------------- 1 | | 类 | 函数名 | 功能描述 | 分类 | 2 | |-------------------|---------------------------|------------------------------------------|----------| 3 | | DataApi | daily | 获取历史上一段时间的日线/周线/月线数据 | 标准接口 | 4 | | DataApi | bar | 获取历史某一天的分钟线数据 | 标准接口 | 5 | | DataApi | bar_quote | 获取历史某一天的分钟线和盘口快照数据 | 标准接口 | 6 | | DataApi | quote | 获取实时报价 | 标准接口 | 7 | | DataApi | query | 获取多种多样的非标准数据,如财务数据等 | 标准接口 | 8 | | RemoteDataService | daily | 同DataApi | 标准接口 | 9 | | RemoteDataService | bar | 同DataApi | 标准接口 | 10 | | RemoteDataService | bar_quote | 同DataApi | 标准接口 | 11 | | RemoteDataService | quote | 同DataApi | 标准接口 | 12 | | RemoteDataService | query | 同DataApi | 标准接口 | 13 | | RemoteDataService | query_trade_dates | 获取给定起止日期间的交易日序列 | 常用接口 | 14 | | RemoteDataService | query_next_trade_date | 获取某日期的下一个交易日 | 常用接口 | 15 | | RemoteDataService | query_last_trade_date | 获取某日期的上一个交易日 | 常用接口 | 16 | | RemoteDataService | is_trade_date | 判断某日期是否是交易日 | 常用接口 | 17 | | RemoteDataService | query_inst_info | 获取标的基础信息 | 常用接口 | 18 | | RemoteDataService | query_dividend | 获取股票分红信息 | 常用接口 | 19 | | RemoteDataService | query_adj_factor_raw | 获取股票复权因子原始数据 | 常用接口 | 20 | | RemoteDataService | query_adj_factor_daily | 获取股票每日复权因子 | 常用接口 | 21 | | RemoteDataService | query_index_member | 获取指数在某段时间内所有成份股序列 | 常用接口 | 22 | | RemoteDataService | query_index_member_daily | 获取指数在某段时间内每日的成份股 | 常用接口 | 23 | | RemoteDataService | query_index_weights_raw | 获取指数成分权重原始数据 | 常用接口 | 24 | | RemoteDataService | query_index_weights_daily | 获取指数成分每日权重 | 常用接口 | 25 | | RemoteDataService | query_industry_raw | 获取股票的行业分类 | 常用接口 | 26 | | RemoteDataService | query_industry_daily | 获取股票的每日行业分类 | 常用接口 | 27 | | DataView | save_dataview | 将DataView存储在目标目录下 | 本地化 | 28 | | DataView | load_dataview | 从目标目录读取存储的DataView | 本地化 | 29 | | DataView | init_from_config | 从参数字典中初始化DataView配置 | 初始化 | 30 | | DataView | prepare_data | 自动利用DataService获取整理数据 | 初始化 | 31 | | DataView | get_ts | 获取某个字段的时间序列数据 | 取数据 | 32 | | DataView | get_snapshot | 获取某个交易日的快照(截面)数据 | 取数据 | 33 | | DataView | add_field | 添加一个内置字段 | 增删字段 | 34 | | DataView | add_formula | 添加一个字段,数据来自给定公式的计算结果 | 增删字段 | 35 | | DataView | append_df | 添加一个字段,数据来自给定的DataFrame | 增删字段 | 36 | | DataView | remove_field | 移除一个字段 | 增删字段 | 37 | -------------------------------------------------------------------------------- /jaqs/research_framework.md: -------------------------------------------------------------------------------- 1 | # JAQS研究框架介绍 2 | 3 | 完整的量化交易策略包含信号计算、交易指令、仓位管理、资金管理等多个方面,其中**信号研究**是一个重要组成部分。JAQS的`SignalDigger`(信号挖据)模块提供了alpha信号研究、事件驱动信号研究、CTA信号研究等功能,本文主要介绍`SignalDigger`模块。 4 | 5 | ## 什么是信号 6 | 7 | 信号是可以指导何时交易、交易多少的量化的指标,以下都可以算作信号: 8 | 9 | - 等金额购买A、B两只股票(信号是购买金额为1:1) 10 | - 购买沪深300中PE低于15的股票(若PE<15信号为1,否则为0) 11 | - 按市值权重购买A、B两只股票(信号是购买金额之比等于市值之比) 12 | - 9:37:45开仓天然橡胶期货3手(信号是购买3手) 13 | - 按等波动性贡献的标准,配置股票指数和债券指数(信号是根据风险中性标准优化得到的权重) 14 | 15 | ## 为什么需要信号 16 | 17 | 信号代表了模型对标的的预期,并给出了定量的买卖目标。好的模型能给出有效的信号,进而转化为模型在相关标的上的主动收益。 18 | 19 | ## 常用的信号评估方法 20 | 21 | 我们问“信号是否有效”,就是想问“在信号满足某些条件下的条件分布,和无条件分布是否有区别”。一般有: 22 | 23 | - 收益分析:收益的分布、均值、标准差,累计收益等; 24 | - 相关性分析:信号值与收益的相关系数、秩相关系数等 25 | 26 | ## JAQS的信号分析模块 27 | 28 | ### 股票alpha信号分析(多标的) 29 | 30 | 对于股票alpha信号,我们主要关注**横截面数据**,即每个交易日投资范围内所有股票的数据。对任意一个交易日,各个股票的信号和各个股票的收益(可以是n天的收益)构成一组数据点,可以分多组比较平均收益,也可以计算相关系数。下面为示例代码(完整版本参见[这里](https://github.com/quantOS-org/JAQS/blob/master/example/research/signal_return_ic_analysis.py)): 31 | 32 | ```python 33 | from jaqs.research import SignalDigger 34 | 35 | # 实例化SignalDigger对象,用于分析、存储结果 36 | # output_format为输出格式,也可选择直接绘图/输出base64编码等 37 | # output_folder为输出文件夹路径 38 | digger = SignalDigger(output_format='pdf', 39 | output_folder='../../output/test_signal') 40 | 41 | # 在此处传入待分析的数据: 42 | # signal是index为交易日、columns为股票、value为信号值的DataFrame 43 | # price是index为交易日,columns为股票,value为价格的DataFrame 44 | # benchmark_price是业绩基准的价格序列(单column的DataFrame) 45 | # n_quantiles是对信号分几组,period是考虑多久后的收益 46 | digger.process_signal_before_analysis(signal, price=price, 47 | mask=mask_all, 48 | n_quantiles=5, period=my_period, 49 | benchmark_price=price_bench, 50 | ) 51 | # 利用处理好的数据直接生成分析报告 52 | res = digger.create_full_report() 53 | ``` 54 | 55 | 56 | 57 | ### CTA信号分析(单标的) 58 | 59 | 对于单标的,信号组成的时间序列数据和标的价格组成的时间序列数据共同构成一组数据点,用于分析。我们同样根据信号值大小进行分组,比较每一组在信号出现后n天的收益均值、标准差;也可以计算信号与收益的相关系数。 60 | 61 | ```python 62 | from jaqs.research import SignalDigger 63 | 64 | # 实例化SignalDigger对象,用于分析、存储结果 65 | # output_format为输出格式,也可选择直接绘图/输出base64编码等 66 | # output_folder为输出文件夹路径 67 | digger = SignalDigger(output_format='pdf', 68 | output_folder='../../output') 69 | 70 | # 在此处传入待分析的数据: 71 | # signal是index为交易日、columns为股票、value为信号值的DataFrame 72 | # price是index为交易日,columns为股票,value为价格的DataFrame 73 | # n_quantiles是对信号分几组,periods是考虑多久后的收益 74 | # trade_condition用于进行简单的回测: 75 | # column列的值满足filter条件后按direction方向多/空hold天数,自动绘制累计收益 76 | digger.create_single_signal_report(signal, price, 77 | periods=[1, 5, 9, 21], n_quantiles=6, 78 | mask=None, 79 | trade_condition={'cond1': {'column': 'quantile', 80 | 'filter': lambda x: x > 3, 81 | 'hold': 5, 82 | 'direction': 1}, 83 | 'cond2': {'column': 'quantile', 84 | 'filter': lambda x: x > 5, 85 | 'hold': 5, 86 | 'direction': 1}, 87 | 'cond3': {'column': 'quantile', 88 | 'filter': lambda x: x > 5, 89 | 'hold': 9, 90 | 'direction': -1}, 91 | } 92 | ) 93 | ``` 94 | 95 | 96 | 97 | ### 事件驱动信号分析(多标的) 98 | 99 | ```python 100 | obj = SignalDigger(output_format='pdf', 101 | output_folder='../../output') 102 | 103 | obj.create_binary_event_report(signal, price, 104 | mask_all, 105 | price_bench, 106 | periods=[20, 60, 121, 242], group_by=None) 107 | 108 | 109 | ``` 110 | 111 | -------------------------------------------------------------------------------- /prerequisites.md: -------------------------------------------------------------------------------- 1 | # quantOS上手指南 2 | 3 | 作者:PKUJohnson 4 | 5 | 使用quantOS非常简单,只需要: 6 | 7 | ## 用户注册 8 | 9 | + 注册成为quantOS用户,可以使用数据、仿真交易、论坛等线上资源。 10 | + quantOS用户注册入口是:[http://www.quantos.org/cas/register.html](http://www.quantos.org/cas/register.html) 11 | + 注册成功后,请妥善保存用户名和密码。 12 | 13 | ## 下载安装软件 14 | 15 | 一般普通用户,可直接下载quantos[金融终端](https://www.quantos.org/terminal.html)。 16 | 17 | 如果您有一定的python基础,也可以手动下载并安装quantOS策略研究系统[JAQS](https://github.com/quantOS-org/JAQS/blob/master/doc/install.md) 18 | 19 | ## 开始了解和使用 20 | 21 | 了解quantOS整体功能,请参考: 22 | 23 | + [quantOS可以做什么](https://github.com/quantOS-org/quantOSUserGuide/blob/master/architect.md) 24 | 25 | 编写策略,请参考策略样例: 26 | 27 | + [量化策略样例(1):选股](https://github.com/quantOS-org/quantOSUserGuide/blob/master/strategy_tutorial_1_alpha.md) 28 | + [量化策略样例(2):择时](https://github.com/quantOS-org/quantOSUserGuide/blob/master/strategy_tutorial_2_timing.md) 29 | 30 | 直接进行交易,请参考: 31 | 32 | + [如何进行仿真交易](https://github.com/quantOS-org/quantOSUserGuide/blob/master/tradesimguide.md) 33 | 34 | ## 加入我们的社区 35 | 36 | 1. 扫描关注quantos微信公众号 37 | 38 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/quantos.jpg?raw=true) 39 | 40 | 2. 扫描加入quantos官方qq群 41 | 42 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/quantos-qq.jpg?raw=true) 43 | 44 | -------------------------------------------------------------------------------- /releasenotes.md: -------------------------------------------------------------------------------- 1 | 2 | # Release Notes 3 | 4 | ## 2017-12-26 5 | 6 | + DataCore 7 | + 发布tk2bar转换工具 8 | + DataServer支持读取本地历史bar和本地历史tick文件,接口支持历史bar查询和历史tick查询 9 | 10 | + JAQS 11 | + 升级到0.6.9版本 12 | 13 | + VNPY 14 | + VNPY 支持与 JAQS进行对接进行实盘交易。 15 | 16 | ## 2017-12-15 17 | 18 | + DataCore 19 | + 发布对接腾讯行情的mdlink,开发者是网友乔木头和李晓松 20 | + 发布本地tk文件转换成HDF5工具. [下载](https://www.quantos.org/datacore/download.html) 21 | 22 | + JAQS 23 | + 升级到0.6.7版本 24 | 25 | + TradeSim 26 | + 发布智能撮合引擎 27 | + 在线网站支持查询历史持仓、历史委托、历史成交、历史PNL 28 | + vnTrader兼容支持pyqt4和pyqt5 29 | 30 | + quantOS.org 31 | + 更新量化小学课程信息 32 | + 用户注册支持国际号码 33 | 34 | -------------------------------------------------------------------------------- /samples/calendar_spread.md: -------------------------------------------------------------------------------- 1 | 2 | ### Calendar Spread交易策略 3 | 4 | 5 | 本帖主要介绍了基于事件驱动回测框架实现calendar spread交易策略。可在[这里](https://github.com/quantOS-org/JAQS/blob/master/example/eventdriven/CalendarSpread.py)直接下载策略源代码。 6 | 7 | #### 一. 策略介绍 8 | 在商品期货市场中,同一期货品种不同到期月份合约间的价格在短期内的相关性较稳定。该策略就利用这一特性,在跨期基差稳定上升时进场做多基差,反之做空基差。 9 | 在本文中我们选择了天然橡胶作为交易品种,时间范围从2017年7月到2017年11月,选择的合约为RU1801.SHF和RU1805.SHF,将基差定义为近期合约价格减去远期合约价格。 10 | 11 | #### 二. 参数准备 12 | 我们在test_spread_commodity.py文件中的test_spread_trading()函数中设置策略所需参数,例如交易标的,策略开始日期,终止日期,换仓频率等。 13 | ```python 14 | props = { 15 | "symbol" : "ru1801.SHF,ru1805.SHF", 16 | "start_date" : 20170701, 17 | "end_date" : 20171109, 18 | "bar_type" : "DAILY", 19 | "init_balance" : 2e4, 20 | "bufferSize" : 20, 21 | "future_commission_rate": 0.00002, 22 | "stock_commission_rate" : 0.0001, 23 | "stock_tax_rate" : 0.0000 24 | } 25 | ``` 26 | 27 | #### 三. 策略实现 28 | 策略实现全部在spread_commodity.py中完成,创建名为SpreadCommodity()的class继承EventDrivenStrategy,具体分为以下几个步骤: 29 | 30 | ##### 1. 策略初始化 31 | 这里将后续步骤所需要的变量都创建好并初始化。 32 | ```python 33 | def __init__(self): 34 | EventDrivenStrategy.__init__(self) 35 | 36 | self.symbol = '' 37 | self.s1 = '' 38 | self.s2 = '' 39 | self.quote1 = None 40 | self.quote2 = None 41 | 42 | self.bufferSize = 0 43 | self.bufferCount = 0 44 | self.spreadList = '' 45 | ``` 46 | 47 | ##### 2. 从props中得到变量值 48 | 这里将props中设置的参数传入。其中,self.spreadList记录了最近$n$天的spread值,$n$是由self.bufferSize确定的。 49 | ```python 50 | def init_from_config(self, props): 51 | super(SpreadCommodity, self).init_from_config(props) 52 | self.symbol = props.get('symbol') 53 | self.init_balance = props.get('init_balance') 54 | self.bufferSize = props.get('bufferSize') 55 | self.s1, self.s2 = self.symbol.split(',') 56 | self.spreadList = np.zeros(self.bufferSize) 57 | ``` 58 | 59 | ##### 3. 策略实现 60 | 策略的主体部分在on_bar()函数中实现。因为我们选择每日调仓,所以会在每天调用on_bar()函数。 61 | 首先将两个合约的quote放入self.quote1和self.quote2中,并计算当天的spread 62 | ```python 63 | q1 = quote_dic.get(self.s1) 64 | q2 = quote_dic.get(self.s2) 65 | self.quote1 = q1 66 | self.quote2 = q2 67 | spread = q1.close - q2.close 68 | ``` 69 | 接着更新self.spreadList。因为self.spreadList为固定长度,更新方法为将第2个到最后1个元素向左平移1位,并将当前的spread放在队列末尾。 70 | ```python 71 | self.spreadList[0:self.bufferSize - 1] = self.spreadList[1:self.bufferSize] 72 | self.spreadList[-1] = spread 73 | self.bufferCount += 1 74 | ``` 75 | 接着将self.spreadList中的数据对其对应的编号(例如从1到20)做regression,观察回归系数的pvalue是否显著,比如小于0.05。如果结果不显著,则不对仓位进行操作;如果结果显著,再判断系数符号,如果系数大于0则做多spread,反之做空spread。 76 | ```python 77 | X, y = np.array(range(self.bufferSize)), np.array(self.spreadList) 78 | X = X.reshape(-1, 1) 79 | y = y.reshape(-1, 1) 80 | X = sm.add_constant(X) 81 | 82 | est = sm.OLS(y, X) 83 | est = est.fit() 84 | 85 | if est.pvalues[1] < 0.05: 86 | if est.params[1] < 0: 87 | self.short_spread(q1, q2) 88 | else: 89 | self.long_spread(q1, q2) 90 | ``` 91 | 92 | #### 四. 回测结果 93 | ![calendarspreadresult](https://raw.githubusercontent.com/quantOS-org/jaqs/master/doc/img/event_driven_calendar_spread_result.png?raw=true) 94 | -------------------------------------------------------------------------------- /samples/dual_thrust.md: -------------------------------------------------------------------------------- 1 | 2 | ### 商品期货的Dual Thrust日内交易策略 3 | 4 | 本帖主要介绍了基于事件驱动回测框架实现Dual Thrust日内交易策略。可在[这里](https://github.com/quantOS-org/JAQS/blob/master/example/eventdriven/DualThrust.py)直接下载策略源代码。 5 | 6 | #### 一. 策略介绍 7 | Dual Thrust是一个趋势跟踪策略,具有简单易用、适用度广的特点,其思路简单、参数较少,配合不同的参数、止盈止损和仓位管理,可以为投资者带来长期稳定的收益,被投资者广泛应用于股票、货币、贵金属、债券、能源及股指期货市场等。 8 | 在本文中,我们将Dual Thrust应用于商品期货市场中。 9 | 简而言之,该策略的逻辑原型是较为常见的开盘区间突破策略,以今日开盘价加减一定比例确定上下轨。日内突破上轨时平空做多,突破下轨时平多做空。 10 | 在Dual Thrust交易系统中,对于震荡区间的定义非常关键,这也是该交易系统的核心和精髓。Dual Thrust系统使用 11 | $$Range = Max(HH-LC,HC-LL)$$ 12 | 来描述震荡区间的大小。其中HH是过去N日High的最大值,LC是N日Close的最小值,HC是N日Close的最大值,LL是N日Low的最小值。 13 | 14 | #### 二. 参数准备 15 | 我们在test_spread_commodity.py文件中的test_spread_trading()函数中设置策略所需参数,例如交易标的,策略开始日期,终止日期,换仓频率等,其中$k1,k2$为确定突破区间上下限的参数。 16 | ```python 17 | props = { 18 | "symbol" : "rb1710.SHF", 19 | "start_date" : 20170510, 20 | "end_date" : 20170930, 21 | "buffersize" : 2, 22 | "k1" : 0.7, 23 | "k2" : 0.7, 24 | "bar_type" : "MIN", 25 | "init_balance" : 1e5, 26 | "future_commission_rate": 0.00002, 27 | "stock_commission_rate" : 0.0001, 28 | "stock_tax_rate" : 0.0000 29 | } 30 | ``` 31 | 32 | #### 三. 策略实现 33 | 策略实现全部在DualThrust.py中完成,创建名为DualThrustStrategy()的class继承EventDrivenStrategy,具体分为以下几个步骤: 34 | 35 | ##### 1. 策略初始化 36 | 这里将后续步骤所需要的变量都创建好并初始化。其中self.bufferSize为窗口期长度,self.pos记录了实时仓位,self.Upper和self.Lower记录了突破区间上下限。 37 | ```python 38 | def __init__(self): 39 | EventDrivenStrategy.__init__(self) 40 | self.symbol = '' 41 | self.quote = None 42 | self.bufferCount = 0 43 | self.bufferSize = '' 44 | self.high_list = '' 45 | self.close_list = '' 46 | self.low_list = '' 47 | self.open_list = '' 48 | self.k1 = '' 49 | self.k2 = '' 50 | self.pos = 0 51 | self.Upper = 0.0 52 | self.Lower = 0.0 53 | ``` 54 | 55 | ##### 2. 从props中得到变量值 56 | 这里将props中设置的参数传入。其中,self.high_list为固定长度的list,保存了最近$N$天的日最高价,其他变量类似。 57 | ```python 58 | def init_from_config(self, props): 59 | super(DualThrustStrategy, self).init_from_config(props) 60 | 61 | self.symbol = props.get('symbol') 62 | self.init_balance = props.get('init_balance') 63 | self.bufferSize = props.get('buffersize') 64 | self.k1 = props.get('k1') 65 | self.k2 = props.get('k2') 66 | self.high_list = np.zeros(self.bufferSize) 67 | self.close_list = np.zeros(self.bufferSize) 68 | self.low_list = np.zeros(self.bufferSize) 69 | self.open_list = np.zeros(self.bufferSize) 70 | ``` 71 | 72 | ##### 3. 策略实现 73 | 在每天开始时,首先调用initialize()函数,得到当天的open,close,high和low的值,并对应放入list中。 74 | ```python 75 | def initialize(self): 76 | self.bufferCount += 1 77 | 78 | # get the trading date 79 | td = self.ctx.trade_date 80 | ds = self.ctx.data_api 81 | 82 | # get the daily data 83 | df, msg = ds.daily(symbol=self.symbol, start_date=td, end_date=td) 84 | 85 | # put the daily value into the corresponding list 86 | self.open_list[0:self.bufferSize - 1] = 87 | self.open_list[1:self.bufferSize] 88 | self.open_list[-1] = df.high 89 | self.high_list[0:self.bufferSize - 1] = 90 | self.high_list[1:self.bufferSize] 91 | self.high_list[-1] = df.high 92 | self.close_list[0:self.bufferSize - 1] = 93 | self.close_list[1:self.bufferSize] 94 | self.close_list[-1] = df.close 95 | self.low_list[0:self.bufferSize - 1] = 96 | self.low_list[1:self.bufferSize] 97 | self.low_list[-1] = df.low 98 | ``` 99 | 100 | 策略的主体部分在on_bar()函数中实现。因为我们选择分钟级回测,所以会在每分钟调用on_bar()函数。 101 | 102 | 首先取到当日的quote,并计算过去$N$天的HH,HC,LC和LL,并据此计算Range和上下限Upper,Lower 103 | ```python 104 | HH = max(self.high_list[:-1]) 105 | HC = max(self.close_list[:-1]) 106 | LC = min(self.close_list[:-1]) 107 | LL = min(self.low_list[:-1]) 108 | 109 | Range = max(HH - LC, HC - LL) 110 | Upper = self.open_list[-1] + self.k1 * Range 111 | Lower = self.open_list[-1] - self.k2 * Range 112 | ``` 113 | 几个关键变量的意义如下图所示: 114 | ![illustrationdual](https://raw.githubusercontent.com/quantOS-org/jaqs/master/doc/img/event_drivent_illustration_dual.png?raw=true) 115 | 116 | 我们的交易时间段为早上9:01:00到下午14:28:00,交易的逻辑为: 117 | 1. 当分钟Bar的open向上突破上轨时,如果当时持有空单,则先平仓,再开多单;如果没有仓位,则直接开多单; 118 | 2. 当分钟Bar的open向下突破下轨时,如果当时持有多单,则先平仓,再开空单;如果没有仓位,则直接开空单; 119 | ```python 120 | if self.pos == 0: 121 | if self.quote.open > Upper: 122 | self.short(self.quote, self.quote.close, 1) 123 | elif self.quote.open < Lower: 124 | self.buy(self.quote, self.quote.close, 1) 125 | elif self.pos < 0: 126 | if self.quote.open < Lower: 127 | self.cover(self.quote, self.quote.close, 1) 128 | self.long(self.quote, self.quote.close, 1) 129 | else: 130 | if self.quote.open > Upper: 131 | self.sell(self.quote, self.quote.close, 1) 132 | self.short(self.quote, self.quote.close, 1) 133 | ``` 134 | 由于我们限制该策略为日内策略,故当交易时间超过14:28:00时,进行强行平仓。 135 | ```python 136 | elif self.quote.time > 142800: 137 | if self.pos > 0: 138 | self.sell(self.quote, self.quote.close, 1) 139 | elif self.pos < 0: 140 | self.cover(self.quote, self.quote.close, 1) 141 | ``` 142 | 我们在下单后,可能由于市场剧烈变动导致未成交,因此在on_trade_ind()函数中记录具体成交情况,当空单成交时,self.pos减一,当多单成交时,self.pos加一。 143 | ```python 144 | def on_trade_ind(self, ind): 145 | if ind.entrust_action == 'sell' or ind.entrust_action == 'short': 146 | self.pos -= 1 147 | elif ind.entrust_action == 'buy' or ind.entrust_action == 'cover': 148 | self.pos += 1 149 | print(ind) 150 | ``` 151 | 152 | #### 四. 回测结果 153 | 回测结果如下图所示: 154 | ![dualthrustresult](https://raw.githubusercontent.com/quantOS-org/jaqs/master/doc/img/event_drivent_dual_thrust_result.png?raw=true) 155 | 156 | 157 | #### 五、参考文献 158 | > [1]: https://www.ricequant.com/community/topic/392/ 159 | > [2]: https://xueqiu.com/5256769224/32429363 160 | -------------------------------------------------------------------------------- /samples/graham.md: -------------------------------------------------------------------------------- 1 | ### 格雷厄姆选股策略 2 | 3 | 主要介绍基于回测框架实现格雷厄姆模型。格雷厄姆模型分为两步,首先是条件选股,其次按照市值从小到大排序,选出排名前五的股票。 4 | 可在[这里](https://github.com/quantOS-org/JAQS/blob/master/example/alpha/Graham.py)直接下载策略源代码。 5 | #### 一. 数据准备 6 | 7 | 我们选择如下指标,对全市场的股票进行筛选,实现过程如下: 8 | a. 首先在数据准备模块save_dataview()中通过props设置数据起止日期,股票版块,以及所需变量 9 | ```python 10 | props = { 11 | 'start_date': 20150101, 12 | 'end_date': 20170930, 13 | 'universe':'000905.SH', 14 | 'fields': ('tot_cur_assets,tot_cur_liab,inventories,pre_pay,deferred_exp, eps_basic,ebit,pe,pb,float_mv,sw1'), 15 | 'freq': 1 16 | } 17 | ``` 18 | b. 接着创建0-1变量表示某只股票是否被选中,并通过add_formula将变量添加到dataview中 19 | > * 市盈率(pe ratio)低于 20 20 | > * 市净率(pb ratio)低于 2 21 | > * 同比每股收益增长率(inc_earning_per_share)大于 0 22 | > * 税前同比利润增长率(inc_profit_before_tax)大于 0 23 | > * 流动比率(current_ratio)大于 2 24 | > * 速动比率(quick_ratio)大于 1 25 | 26 | ```python 27 | factor_formula = 'pe < 20' 28 | dv.add_formula('pe_condition', factor_formula, is_quarterly=False) 29 | factor_formula = 'pb < 2' 30 | dv.add_formula('pb_condition', factor_formula, is_quarterly=False) 31 | factor_formula = 'Return(eps_basic, 4) > 0' 32 | dv.add_formula('eps_condition', factor_formula, is_quarterly=True) 33 | factor_formula = 'Return(ebit, 4) > 0' 34 | dv.add_formula('ebit_condition', factor_formula, is_quarterly=True) 35 | factor_formula = 'tot_cur_assets/tot_cur_liab > 2' 36 | dv.add_formula('current_condition', factor_formula, is_quarterly=True) 37 | factor_formula = '(tot_cur_assets - inventories - pre_pay - deferred_exp)/tot_cur_liab > 1' 38 | dv.add_formula('quick_condition', factor_formula, is_quarterly=True) 39 | ``` 40 | 需要注意的是,涉及到的财务数据若不在secDailyIndicator表中,需将is_quarterly设置为True,表示该变量为季度数据。 41 | c. 由于第二步中需要按流通市值排序,我们将这一变量也放入dataview中 42 | ```python 43 | dv.add_formula('mv_rank', 'Rank(float_mv)', is_quarterly=False) 44 | ``` 45 | 46 | #### 二. 条件选股 47 | 48 | 条件选股在my_selector函数中完成: 49 | > * 首先我们将上一步计算出的0/1变量提取出来,格式为Series 50 | > * 接着我们对所有变量取交集,选中的股票设为1,未选中的设为0,并将结果通过DataFrame形式返回 51 | ```python 52 | def my_selector(context, user_options=None): 53 | # 54 | pb_selector = context.snapshot['pb_condition'] 55 | pe_selector = context.snapshot['pe_condition'] 56 | eps_selector = context.snapshot['eps_condition'] 57 | ebit_selector = context.snapshot['ebit_condition'] 58 | current_selector = context.snapshot['current_condition'] 59 | quick_selector = context.snapshot['quick_condition'] 60 | # 61 | merge = pd.concat([pb_selector, pe_selector, eps_selector, ebit_selector, current_selector, quick_selector], axis=1) 62 | 63 | result = np.all(merge, axis=1) 64 | mask = np.all(merge.isnull().values, axis=1) 65 | result[mask] = False 66 | return pd.DataFrame(result, index=merge.index, columns=['selector']) 67 | ``` 68 | 69 | #### 三、按市值排序 70 | 71 | 按市值排序功能在signal_size函数中完成。我们根据流通市值排序变量'mv_rank'对所有股票进行排序,并选出市值最小的5只股票。 72 | ```python 73 | def signal_size(context, user_options = None): 74 | mv_rank = context.snapshot_sub['mv_rank'] 75 | s = np.sort(mv_rank.values)[::-1] 76 | if len(s) > 0: 77 | critical = s[-5] if len(s) > 5 else np.min(s) 78 | mask = mv_rank < critical 79 | mv_rank[mask] = 0.0 80 | mv_rank[~mask] = 1.0 81 | return mv_rank 82 | ``` 83 | 84 | #### 四、回测 85 | 86 | 我们在test_alpha_strategy_dataview()模块中实现回测功能 87 | 88 | ##### 1. 载入dataview,设置回测参数 89 | 该模块首先载入dataview并允许用户设置回测参数,比如基准指数,起止日期,换仓周期等。 90 | ```python 91 | dv = DataView() 92 | 93 | fullpath = fileio.join_relative_path('../output/prepared', dv_subfolder_name) 94 | dv.load_dataview(folder=fullpath) 95 | 96 | props = { 97 | "benchmark": "000905.SH", 98 | "universe": ','.join(dv.symbol), 99 | 100 | "start_date": dv.start_date, 101 | "end_date": dv.end_date, 102 | 103 | "period": "week", 104 | "days_delay": 0, 105 | 106 | "init_balance": 1e8, 107 | "position_ratio": 1.0, 108 | } 109 | ``` 110 | 111 | ##### 2. StockSelector选股模块 112 | 接着我们使用StockSelector选股模块,将之前定义的my_selector载入 113 | ```python 114 | stock_selector = model.StockSelector(context) 115 | stock_selector.add_filter(name='myselector', func=my_selector) 116 | ``` 117 | 118 | ##### 3. FactorRevenueModel模块 119 | 在进行条件选股后,使用FactorRevenueModel模块对所选股票进行排序 120 | ```python 121 | signal_model = model.FactorRevenueModel(context) 122 | signal_model.add_signal(name='signalsize', func = signal_size) 123 | ``` 124 | 125 | ##### 4. 策略回测模块 126 | 将上面定义的stockSelector和FactorRevenueModel载入AlphaStrategy函数进行回测 127 | ```python 128 | strategy = AlphaStrategy( 129 | stock_selector=stock_selector, 130 | revenue_model=signal_model, 131 | pc_method='factor_value_weight') 132 | ``` 133 | 134 | ##### 5. 启动数据准备及回测模块 135 | ```python 136 | t_start = time.time() 137 | 138 | test_save_dataview() 139 | test_alpha_strategy_dataview() 140 | test_backtest_analyze() 141 | 142 | t3 = time.time() - t_start 143 | print "\n\n\nTime lapsed in total: {:.1f}".format(t3) 144 | ``` 145 | 146 | #### 五、回测结果 147 | 148 | 回测的参数如下: 149 | 150 | | 指标 | 值 | 151 | | -------- | --: | 152 | | Beta | 0.87 | 153 | | Annual Return | 0.08 | 154 | | Annual Volatility| 0.29 | 155 | | Sharpe Ratio | 0.28 | 156 | 157 | 回测的净值曲线图如下: 158 | 159 | ![backtestgraham](https://raw.githubusercontent.com/quantOS-org/jaqs/master/doc/img/backtest_Graham_result.png?raw=true) 160 | -------------------------------------------------------------------------------- /security.md: -------------------------------------------------------------------------------- 1 | # quantOS用户安全机制 2 | 3 | + 用户访问网站www.quantOS.org使用https加密机制; 4 | + 用户通过签发令牌,访问线上资源,不传输密码; 5 | + 用户可主动定期更新令牌; 6 | + 论坛不显示用户手机信息; 7 | + 用户需要妥善保存自己的密码信息。 8 | 9 | ## 令牌(Token)签发和使用 10 | 11 | 用户注册成功后,系统会为每个用户签发一个令牌,用于`DataApi`和`TradeApi`的登录。 12 | 13 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/token.png?raw=true) 14 | 15 | ### 用户可使用令牌(Token)登录访问在线数据系统 16 | ```python 17 | from jaqs.data import DataApi 18 | dapi = DataApi(addr="tcp://data.quantos.org:8910") 19 | login_result, err_msg = api.login("手机号", "token") # 这里token即为令牌,不要使用用户密码 20 | ``` 21 | 更多关于`DataApi`的教程,参见DataApi使用说明。 22 | 23 | ### 用户可使用令牌登录访问仿真交易系统 24 | ```python 25 | from jaqs.trade import TradeApi 26 | tapi = TradeApi(addr="tcp://gw.quantos.org:8901") 27 | user_info, msg = tapi.login("手机号", "token") # 这里token即为令牌,不要使用用户密码 28 | ``` 29 | 更多关于`TradeApi`的教程,参见[TradeApi使用说明](https://github.com/quantOS-org/TradeApi)。 30 | 31 | ### 用户可登录网站后,主动更新令牌 32 | 在网站首页,点击自己的用户名-查看API令牌,在弹出的窗口中点击”刷新令牌”,令牌值会即时刷新,立即生效。 33 | -------------------------------------------------------------------------------- /strategy_tutorial_1_alpha.md: -------------------------------------------------------------------------------- 1 | # quantOS量化策略样例(1):选股 2 | 3 | 本文主要内容: 4 | 5 | - 用**JAQS的股票Alpha框架**做股票策略回测; 6 | - 用**TradeSim**在线仿真交易。 7 | 8 | 代码量:<100行;预计阅读时间:5分钟。 9 | 10 | 完整代码及样例见[这里](https://github.com/quantOS-org/JAQS/blob/master/example/alpha/first_example.py),安装JAQS后即可直接运行(安装教程,参见 [JAQS安装指南](https://github.com/quantOS-org/JAQS/blob/master/doc/install.md))。 11 | 12 | ## 策略描述 13 | 14 | - 每月调仓一次; 15 | - 每次调仓时,将食品饮料行业(中证申万食品饮料指数)的所有成份股按照市值权重构建目标投资组合,依照此目标进行买卖; 16 | - 初始资金1亿,回测期间收益均再投资; 17 | - 策略目标是获得比沪深300更好的收益。 18 | 19 | ## 策略回测和结果分析 20 | 21 | 我们使用[JAQS](https://www.quantos.org/jaqs/index.html)来完成数据获取和回测。关于JAQS的介绍,见本文最后部分。 22 | 23 | ### 策略实现 24 | 25 | 实现并回测该策略的代码可分为两部分:**准备数据**和**利用准备好的数据进行回测**,这是因为同样的策略可以在不同数据上测试,同样的数据也可以用于不同数据的回测。JAQS也依照这一理念进行了模块化设计,具体请看下方例子。 26 | 27 | #### 准备数据 28 | 29 | 根据策略描述,我们需要以下数据: 30 | 31 | - 投资范围(universe):中证申万食品饮料指数 `000807.SH`的所有成份股; 32 | - 业绩比较基准(benchmark):沪深300指数 `000300.SH`; 33 | - 市值:投资范围内所有股票的市值; 34 | - 起止时间:回测运行的时间段; 35 | - 日行情:包括高开低收、成交量等,这是回测必然会用到的数据。 36 | 37 | 使用JAQS提供的`DataView`工具,可方便地获取以上数据: 38 | 39 | ```python 40 | dataview_props = {# Start and end date of back-test 41 | 'start_date': 20170101, 'end_date': 20171030, 42 | # Investment universe and performance benchmark 43 | 'universe': UNIVERSE, 'benchmark': '000300.SH', 44 | # Data fields that we need 45 | 'fields': 'total_mv,turnover', 46 | # freq = 1 means we use daily data. Please do not change this. 47 | 'freq': 1} 48 | 49 | # RemoteDataService communicates with a remote server to fetch data 50 | ds = RemoteDataService() 51 | # Use username and password in data_config to login 52 | ds.init_from_config(data_config) 53 | 54 | # DataView utilizes RemoteDataService to get various data and store them 55 | dv = DataView() 56 | dv.init_from_config(dataview_props, ds) 57 | dv.prepare_data() 58 | dv.save_dataview(folder_path=dataview_store_folder) 59 | ``` 60 | 61 | 运行后,在输出中看到: 62 | 63 | ```shell 64 | Dataview has been successfully saved to: 65 | 'dataview_store_folder' 66 | 67 | You can load it with load_dataview('dataview_store_folder') 68 | ``` 69 | 70 | 则说明`DataView`已经自动获取数据并存储在我们设置的存储路径`dataview_store_folder`里。 71 | 72 | 数据存储好后,可多次读取使用,无需再连接数据服务器。 73 | 74 | #### 策略回测 75 | 76 | 首先需要读取保存好的数据文件: 77 | 78 | ```python 79 | # Load local data file that we just stored. 80 | dv = DataView() 81 | dv.load_dataview(folder_path=dataview_store_folder) 82 | ``` 83 | 84 | 读取后会看到如下输出: 85 | 86 | ```shell 87 | Dataview loaded successfully. 88 | ``` 89 | 90 | 接下来是策略部分。我们使用JAQS的股票Alpha策略框架`AlphaStrategy`、回测框架`AlphaBacktestInstance`实现。 91 | 92 | 框架允许用户任意指定投资范围内每只股票的权重,同时对于等权重、市值权重等常用情况,JAQS已经内置了相应函数,用户无需自己实现。 93 | 94 | 我们需要设置起止时间、初始资金等回测配置`backtest_props`,建立策略对象`AlphaStrategy`,回测实例对象`AlphaBacktestInstance`等。此外还需要建立运行上下文`context`,用于放置一些全局变量。 95 | 96 | ```python 97 | backtest_props = {# start and end date of back-test 98 | "start_date": dv.start_date, 99 | "end_date": dv.end_date, 100 | # re-balance period length 101 | "period": "month", 102 | # benchmark and universe 103 | "benchmark": dv.benchmark, 104 | "universe": dv.universe, 105 | # Amount of money at the start of back-test 106 | "init_balance": 1e8} 107 | 108 | # This is our strategy 109 | strategy = AlphaStrategy(pc_method='market_value_weight') 110 | 111 | # BacktestInstance is in charge of running the back-test 112 | bt = AlphaBacktestInstance() 113 | 114 | # Public variables are stored in context. We can also store anything in it 115 | context = model.Context(dataview=dv, instance=bt, strategy=strategy, trade_api=trade_api, pm=pm) 116 | ``` 117 | 118 | 准备好这些对象后,即可运行回测并储存结果: 119 | 120 | ```python 121 | bt.init_from_config(backtest_props) 122 | bt.run_alpha() 123 | 124 | # After finishing back-test, we save trade results into a folder 125 | bt.save_results(folder_path=backtest_result_folder) 126 | ``` 127 | 128 | 回测过程中会实时输出回测进度及资金情况,如: 129 | 130 | ```shell 131 | AlphaStrategy Initialized. 132 | 133 | =======new day 20170103 134 | Before 20170103 re-balance: available cash all = 1.0000e+08 135 | 136 | =======new day 20170203 137 | Before 20170203 re-balance: available cash all = 1.0054e+08 138 | ``` 139 | 140 | 回测完成后,会有如下提示: 141 | 142 | ```shell 143 | Backtest done. 240 days, 5.27e+02 trades in total. 144 | Backtest results has been successfully saved to: 145 | 'backtest_result_folder' 146 | ``` 147 | 148 | 即回测的结果(交易记录)和回测相关配置已成功存储在`backtest_result_folder`内。用户可自行查看,也可使用我们提供的分析工具进行分析,见下一节。 149 | 150 | ### 结果分析 151 | 152 | 我们使用JAQS的`Analyzer`工具。分析时同样基于保存好的`DataView`和回测结果进行: 153 | 154 | ```python 155 | # Analyzer help us calculate various trade statistics according to trade results. 156 | # All the calculation results will be stored as its members. 157 | ta = ana.AlphaAnalyzer() 158 | ta.initialize(dataview=dv, file_folder=backtest_result_folder) 159 | 160 | ta.do_analyze(result_dir=backtest_result_folder, 161 | selected_sec=list(ta.universe)[:3]) 162 | ``` 163 | 164 | 其中`selected_sec`参数是一个`list`,存放标的代码,其中存放的标的的买卖详情会绘制在回测报告中。 165 | 166 | 分析完成后,会生成HTML格式的回测报告,并输出报告所在路径。报告样例截图如下: 167 | 168 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/alpha_backtest_report.PNG?raw=true) 169 | 170 | ## 仿真交易 171 | 172 | 若想将以上策略接入仿真交易,仍使用JAQS运行策略,最后用[TradeSim](https://www.quantos.org/tradesim/index.html)进行仿真交易与撮合。无需修改策略代码,只需修改主程序 173 | 174 | ,只需更换`AlphaTradeApi`和`AlphaBacktestInstance`: 175 | 176 | ```python 177 | livetrade_props = {"period": "day", 178 | "strategy_no": 1044, 179 | "init_balance" 1e6} 180 | 181 | strategy = AlphaStrategy(pc_method='market_value_weight') 182 | 183 | bt = AlphaLiveTradeInstance() 184 | trade_api = RealTimeTradeApi(props) 185 | ds = RemoteDataService() 186 | 187 | context = model.Context(dataview=dv, instance=bt, strategy=strategy, trade_api=trade_api, pm=pm, data_api=ds) 188 | 189 | bt.init_from_config(props) 190 | bt.run_alpha() 191 | ``` 192 | 193 | 以上代码中,我们将`AlphaBacktestInstance`更换为`AlphaLiveTradeInstance`,将`AlphaTradeApi`更换为`RealTimeTradeApi`,并使用`RemoteDataService`以获取最新数据。注意`livetrade_props`中需要填写`strategy_no`项,这是我们的策略号,不同用户不同。 194 | 195 | 运行`run_alpha`后,策略会根据最新数据产生目标投资组合,可从`strategy.goal_positions`中取出并发单: 196 | ```python 197 | goal_positions = strategy.goal_positions 198 | task_id, msg = trade_api.basket_order(goal_positions) 199 | ``` 200 | 发单成功后,`trade_api`为该任务的编号,msg为返回信息。 201 | 202 | 具体订单、持仓、盈亏等可在[仿真交易网站](https://www.quantos.org/tradesim/trade.html)查看,也可使用[vnTrade](https://github.com/quantOS-org/TradeSim/tree/master/vnTrader)客户端查看,如下图: 203 | 204 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/tradesim_web.PNG?raw=true) 205 | 206 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/vnTrader.PNG?raw=true) 207 | 208 | 209 | 210 | *__注__:以上只展示了部分核心代码段,__无法直接运行__。完整、可运行代码可在[这里](https://github.com/quantOS-org/JAQS/blob/master/example/alpha/first_example.py)下载。* 211 | 212 | 213 | ## 附:JAQS简介 214 | 215 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/procedure.png?raw=true) 216 | 217 | 策略开发的完整流程一般是以下四步的循环往复,JAQS在这四步都提供了支持: 218 | 219 | 1. **数据**收集处理:我们提供了标准接口`DataApi`, 便利接口`DataService`, 高效工具`DataView` 220 | 2. 对数据进行**研究**:我们提供进行信号/事件研究的`SignalDigger` 221 | 3. 根据研究结果开发策略并**回测**:我们提供两种策略回测框架,Alpha选股和事件驱动择时(如CTA、套利) 222 | 4. 对回测结果进行**分析**:我们提供直观简洁的报告`Report`,以及分析内容丰富、可进一步开发的分析器`Analyzer` 223 | 224 | 本文作为入门系列,主要围绕具体样例,介绍了回测部分,更多资料,参见[官方网站。](https://www.quantos.org/jaqs/index.html) 225 | -------------------------------------------------------------------------------- /strategy_tutorial_2_timing.md: -------------------------------------------------------------------------------- 1 | # quantOS量化策略样例(2):择时 2 | 3 | 本文将向大家展示如何利用JAQS系统的事件驱动框架开发择时策略,并通过TradeSim进行仿真交易。这里我将以贵州茅台(600519.SH)的双均线穿越策略为例。 4 | 5 | JAQS安装教程,参见 [JAQS安装指南](https://github.com/quantOS-org/JAQS/blob/master/doc/install.md) 6 | 7 | **完整代码**请点击[这里](https://github.com/quantOS-org/JAQS/tree/master/example/eventdriven),安装JAQS后即可直接运行(安装教程,参见[JAQS安装指南](https://github.com/quantOS-org/JAQS/blob/master/doc/install.md))。 8 | 9 | ## 一、策略描述 10 | 双均线穿越策略分为两步: 11 | 1. 首先,确定交易标的,根据历史价格数据计算快速均线和慢速均线。在本文的回测模式中,数据周期为1天。 12 | 2. 当快线均值上穿慢线均值时,若此时没有持仓,则买入股票;反之当快线均值下穿慢线均值时,若此时有股票持仓,则卖出所有股票。 13 | 14 | ## 二、策略实现 15 | 首先向大家介绍一下事件驱动策略框架的组成部分。该框架由类`DoubleMaStrategy()`实现,完成了“数据采集-信号生成-发单”的整个交易逻辑。 16 | ```python 17 | class DoubleMaStrategy(EventDrivenStrategy): 18 | """""" 19 | def __init__(self): 20 | super(DoubleMaStrategy, self).__init__() 21 | pass 22 | 23 | def init_from_config(self, props): 24 | super(DoubleMaStrategy, self).init_from_config(props) 25 | pass 26 | 27 | def buy(self, quote, size=1): 28 | pass 29 | 30 | def sell(self, quote, size=1): 31 | pass 32 | 33 | def on_tick(self, quote): 34 | pass 35 | 36 | def on_bar(self, quote_dic): 37 | pass 38 | 39 | def on_trade(self, ind): 40 | pass 41 | ``` 42 | 其中, 43 | 44 | - `init_from_config()`负责通过props接收策略所需参数,进行策略初始化; 45 | - `buy()`/`sell()`负责发单; 46 | - `on_tick()`和`on_bar()`是框架核心,策略的逻辑都在其中实现,区别在于`on_tick()`接收单个quote变量,而`on_bar()`接收多个quote组成的dictionary。此外`on_tick()`是在tick级回测和实盘/仿真交易中使用,而`on_bar()`是在bar回测中使用; 47 | - `on_trade()`负责监督发单成交情况。 48 | 49 | ### 1. 参数初始化 50 | 首先在函数`__init__()`中初始化策略所需变量 51 | ```python 52 | def __init__(self): 53 | super(DoubleMaStrategy, self).__init__() 54 | 55 | # 标的 56 | self.symbol = '' 57 | 58 | # 快线和慢线周期 59 | self.fast_ma_len = 0 60 | self.slow_ma_len = 0 61 | 62 | # 记录当前已经过的天数 63 | self.window_count = 0 64 | self.window = 0 65 | 66 | # 固定长度的价格序列 67 | self.price_arr = None 68 | 69 | # 快线和慢线均值 70 | self.fast_ma = 0 71 | self.slow_ma = 0 72 | 73 | # 当前仓位 74 | self.pos = 0 75 | 76 | # 下单量乘数 77 | self.buy_size_unit = 1 78 | self.output = True 79 | ``` 80 | 该策略的关键参数有三个,交易标的(symbol),快线周期(fast_ma_len)和慢线周期(slow_ma_len),通过props字典传入。 81 | ```python 82 | def init_from_config(self, props): 83 | """ 84 | 将props中的用户设置读入 85 | """ 86 | super(DoubleMaStrategy, self).init_from_config(props) 87 | # 标的 88 | self.symbol = props.get('symbol') 89 | 90 | # 初始资金 91 | self.init_balance = props.get('init_balance') 92 | 93 | # 快线和慢线均值 94 | self.fast_ma_len = props.get('fast_ma_length') 95 | self.slow_ma_len = props.get('slow_ma_length') 96 | self.window = self.slow_ma_len + 1 97 | 98 | # 固定长度的价格序列 99 | self.price_arr = np.zeros(self.window) 100 | 101 | ``` 102 | ### 2. 逻辑实现 103 | 策略的日级回测在`on_bar()`函数中完成。在回测中,每天会有一个quote传入,主要包括open, close, high和low。下面我们以回测为例。 104 | 第一步:根据历史价格数据计算快速均线和慢速均线。 105 | 每当一个quote传入,我们计算当前的midprice并更新价格序列。 106 | ```python 107 | if isinstance(quote, Quote): 108 | # 如果是Quote类型,mid为bidprice和askprice的均值 109 | bid, ask = quote.bidprice1, quote.askprice1 110 | if bid > 0 and ask > 0: 111 | mid = (quote.bidprice1 + quote.askprice1) / 2.0 112 | else: 113 | # 如果当前价格达到涨停板或跌停板,系统不交易 114 | return 115 | else: 116 | # 如果是Bar类型,mid为Bar的close 117 | mid = quote.close 118 | 119 | # 将price_arr序列中的第一个值删除,并将当前mid放入序列末尾 120 | self.price_arr[0: self.window - 1] = self.price_arr[1: self.window] 121 | self.price_arr[-1] = mid 122 | ``` 123 | 接着计算快速均线和慢速均线, 124 | ```python 125 | self.fast_ma = np.mean(self.price_arr[-self.fast_ma_len:]) 126 | self.slow_ma = np.mean(self.price_arr[-self.slow_ma_len:]) 127 | ``` 128 | 第二步:当快线向上穿越慢线且当前没有持仓,则买入100股;当快线向下穿越慢线且当前有持仓,则平仓。 129 | ```python 130 | if self.fast_ma > self.slow_ma: 131 | if self.pos == 0: 132 | self.buy(quote, 100) 133 | 134 | elif self.fast_ma < self.slow_ma: 135 | if self.pos > 0: 136 | self.sell(quote, self.pos) 137 | ``` 138 | 第三步:交易完成后,会触发`on_trade()`函数,通过`self.ctx.pm.get_pos()`函数的到最新仓位并更新self.pos 139 | ```python 140 | def on_trade(self, ind): 141 | print("\nStrategy on trade: ") 142 | print(ind) 143 | self.pos = self.ctx.pm.get_pos(self.symbol) 144 | ``` 145 | ## 三、回测启动 146 | 策略启动在`run_strategy()`函数中完成。 147 | ```python 148 | def run_strategy(): 149 | if is_backtest: 150 | """ 151 | 回测模式 152 | """ 153 | props = {"symbol": '600519.SH', 154 | "start_date": 20170101, 155 | "end_date": 20171104, 156 | "fast_ma_length": 5, 157 | "slow_ma_length": 15, 158 | "bar_type": "1d", # '1d' 159 | "init_balance": 50000} 160 | 161 | tapi = BacktestTradeApi() 162 | ins = EventBacktestInstance() 163 | 164 | else: 165 | """ 166 | 实盘/仿真模式 167 | """ 168 | props = {'symbol': '600519.SH', 169 | "fast_ma_length": 5, 170 | "slow_ma_length": 15, 171 | 'strategy.no': 1062} 172 | tapi = RealTimeTradeApi(trade_config) 173 | ins = EventLiveTradeInstance() 174 | ``` 175 | ## 四、回测结果及分析 176 | 回测结果如下图所示: 177 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/doubleMA.png?raw=true) 178 | 179 | 回测结果的分析在`analyze()`中完成 180 | ```python 181 | def analyze(): 182 | ta = ana.EventAnalyzer() 183 | 184 | ds = RemoteDataService() 185 | ds.init_from_config(data_config) 186 | 187 | ta.initialize(data_server_=ds, file_folder=result_dir_path) 188 | 189 | ta.do_analyze(result_dir=result_dir_path, selected_sec=[]) 190 | ``` 191 | *__注__:本文只介绍了策略核心函数和逻辑,完整代码请点击[这里](https://github.com/quantOS-org/JAQS/blob/master/example/eventdriven/DoubleMA.py)。* 192 | 193 | ## 五、仿真交易及结果展示 194 | 本例展示的是日线交易策略,可以通过TradeApi进行手动下单。需要输入的信息包括股票代码,交易方向,价格和交易量。 195 | ```python 196 | from jaqs.trade.tradeapi import TradeApi 197 | tapi = TradeApi(trade_config['remote.trade.address']) 198 | user_info, msg = tapi.login(trade_config['remote.trade.username'], trade_config['remote.trade.password']) 199 | task_id, msg = tapi.place_order(security = '600519.SH', action = 'Buy', price = 667, size = 100) 200 | ``` 201 | 发单成功后,trade_api为任务编号。具体订单持仓盈亏可在[仿真交易网站](https://www.quantos.org/tradesim/trade.html)查看,如下图所示: 202 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/doubleMA_tradeapi.PNG?raw=true) 203 | -------------------------------------------------------------------------------- /tradesimguide.md: -------------------------------------------------------------------------------- 1 | # 如何进行仿真交易 2 | 3 | 作者:vanvency, PKUJohnson 4 | 5 | 我们提供仿真交易系统TradeSim。 6 | 7 | + TradeSim是一个在线仿真交易平台(未开源),提供账户管理、在线交易、模拟成交等服务,支持股票、期货等品种的交易。 8 | + TradeSim中的交易系统模块支持多账户管理、多通道交易、实时风控,提供包括VWAP、TWAP等算法交易,是一款企业级应用。 9 | 10 | 使用TradeSim非常简单,只需要如下几个步骤: 11 | 12 | ## 注册 13 | 14 | + 注册成为quantOS的用户,即成为TradeSim系统的用户。注册地址是:[http://www.quantos.org/cas/register.html](http://www.quantos.org/cas/register.html) 15 | + 每个用户初始提供三个交易策略,分别交易沪深300,中证500和股指期货。 16 | + 安装JAQS,请参考[https://github.com/quantOS-org/JAQS/blob/master/doc/install.md](https://github.com/quantOS-org/JAQS/blob/master/doc/install.md) 17 | 18 | ## API程序化交易 19 | 20 | + 使用TradeApi进行程序化交易。样例代码如下: 21 | 22 | ```py 23 | from jaqs.trade.tradeapi import TradeApi 24 | 25 | # 登录仿真系统 26 | tapi = TradeApi(addr="tcp://gw.quantos.org:8901") 27 | user_info, msg = tapi.login("phone", "token") 28 | 29 | # 选择策略号 30 | tapi.use_strategy(123) # 123为给你分配的策略号,可以从user_info中获得 31 | 32 | # 下单接口 33 | task_id, msg = tapi.place_order("000025.SZ", "Buy", 57, 100) 34 | print "msg:", msg 35 | print "task_id:", task_id 36 | ``` 37 | 38 | + TradeApi的详细使用方法,请参看[这里](https://github.com/quantOS-org/JAQS/blob/master/doc/trade_api.md). 39 | 40 | ## Web综合客户端 41 | 42 | + 登录TradeSim网页,查看交易情况。访问地址是:[http://www.quantos.org/tradesim/trade.html](http://www.quantos.org/tradesim/trade.html) 43 | + 查看到自己的策略,当期的交易,持仓,绩效等情况 44 | 45 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/tradesim_entrust.PNG?raw=true) 46 | 47 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/tradesim_trade.PNG?raw=true) 48 | 49 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/tradesim_pnl.PNG?raw=true) 50 | 51 | + 目前只有查询功能,未来会有更多丰富的分析功能、交易功能等 52 | 53 | ## 专业交易客户端 54 | 55 | + 使用vnTrader进行交易。详细使用方法请参见[https://github.com/quantOS-org/TradeSim/blob/master/doc/vnTrader.md](https://github.com/quantOS-org/TradeSim/blob/master/doc/vnTrader.md) 56 | 57 | + 交易界面展示 58 | 59 | ![](https://github.com/quantOS-org/TradeSim/blob/master/doc/img/vnTrader_main.png?raw=true) 60 | -------------------------------------------------------------------------------- /tradesolution.md: -------------------------------------------------------------------------------- 1 | # 交易系统解决方案 2 | 3 | 作者:PKUJohnson, symbol, vanvency, 用python的交易员 4 | 5 | 交易是将量化投资付诸实施的手段,也是实现量化投资理念的重要步骤。 6 | 7 | ## 仿真交易TradeSim 8 | 9 | 严谨的量化投资,应该进行一定时间的仿真交易,作为策略实盘前的验证。因此,quantOS提供了一套完备的仿真交易系统TradeSim,供用户使用。 10 | 11 | 使用TradeSim非常简单,只需要如下几个步骤: 12 | 13 | 1、注册成为quantOS的用户,即成为TradeSim系统的合法用户。每个用户初始提供三个交易策略,分别交易沪深300,中证500和股指期货。注册地址是:[http://www.quantos.org/cas/register.html](http://www.quantos.org/cas/register.html) 14 | 15 | 2、下载TradeApi。下载地址是:[https://github.com/quantOS-org/TradeApi](https://github.com/quantOS-org/TradeApi) 16 | 17 | 3、使用TradeApi进行程序化交易。样例代码如下: 18 | 19 | ```py 20 | from tradeapi import TradeApi 21 | 22 | # 登录仿真系统 23 | tapi = TradeApi(addr="tcp://gw.quantos.org:8901") 24 | user_info, msg = tapi.login("demo", "token") 25 | 26 | # 选择策略号 27 | tapi.use_strategy(123) # 123为给你分配的策略号,可以从user_info中获得 28 | 29 | # 下单接口 30 | task_id, msg = tapi.place_order("000025.SZ", "Buy", 57, 100) 31 | print "msg:", msg 32 | print "task_id:", task_id 33 | ``` 34 | 35 | TradeApi的详细使用方法,请参看[这里](http://www.quantos.org/tradesim/doc.html). 36 | 37 | 4、登录TradeSim网页,查看交易情况。访问地址是:[http://www.quantos.org/tradesim/trade.html](http://www.quantos.org/tradesim/trade.html) 38 | 39 | 在TradeSim网页上,我们能看到自己的策略,当期的交易,持仓,绩效等情况。未来会有更多丰富的分析功能。 40 | 41 | ## 实盘交易 42 | 43 | 实盘交易是用户最重要的交易环节,对用户至关重要。我们推荐两类解决方案: 44 | 45 | ### 实盘方案1:使用vn.py交易 46 | 47 | vn.py是一个用户众多的开源交易软件,已经实现了与众多交易柜台的对接。quantOS将JAQS策略系统与VN.PY进行了集成,实现了统一的交易规范,如下图所示: 48 | 49 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/trade_api.png?raw=true) 50 | 51 | JAQS用户可以通过统一的TradeApi,访问TradeSim系统进行仿真交易,访问vn.py进行实盘交易。 52 | 53 | vn.py通过提供jaqsService,实现了TradeApi的支持。详细信息请参看[vn.py官方网站](https://github.com/vnpy/vnpy)。 54 | 55 | ### 实盘方案2:使用专业版的交易系统TKPro 56 | 57 | TKPro是quantOS的专业交易系统,目前尚未开源。其技术架构如下: 58 | 59 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/tkpro.png?raw=true) 60 | 61 | JAQS用户可以通过统一的TradeApi,像访问TradeSim一样,访问TKPro。 62 | 63 | TKPro支持的交易功能非常丰富,包括: 64 | 65 | * 用户登录,选择策略号 66 | * 查询策略持仓 67 | * 查询账户资金 68 | * 查询委托、成交 69 | * 成交推送,委托状态推送 70 | * 普通下单、篮子下单 71 | * 算法下单(TWAP、VWAP,配对交易,最优价格算法等) 72 | * 撤单 73 | * 相对数量下单 74 | * 组合目标下单 75 | 76 | 除了下单外,TKPro还提供的功能包括: 77 | 78 | * 多策略管理 79 | * 多交易通道支持 80 | * 智能交易路由 81 | * 极速交易风控 82 | 83 | TKPro是一款适合企业级交易系统,可以本地化部署,有兴趣的同学可以联系[tkpro@quantos.org](mailto:tkpro@quantos.org)。 84 | 85 | TradeSim相当于TKPro的在线版本,提供了模拟撮合功能。 86 | 87 | -------------------------------------------------------------------------------- /tusharepro.md: -------------------------------------------------------------------------------- 1 | # 我只想使用数据,该怎么做 2 | 3 | 作者:米哥, symbol, PKUJohnson 4 | 5 | 如果只想获取一些数据,请使用我们的在线数据服务TusharePro,目前已支持股票、基金、指数、期货等品种的市场数据、参考数据等。 6 | 7 | 使用非常简单,步骤如下: 8 | 9 | 1. 注册成为www.quantos.org的注册用户,注册地址是:[https://www.quantos.org/cas/register.html](https://www.quantos.org/cas/register.html) 10 | 11 | 2. 安装JAQS,请参考[https://github.com/quantOS-org/JAQS/blob/master/doc/install.md](https://github.com/quantOS-org/JAQS/blob/master/doc/install.md) 12 | 13 | 3. 使用DataApi,从TusharePro获取您需要的研究数据。 14 | 15 | 以下是简单的使用示例 16 | 17 | ```python 18 | 19 | from jaqs.data import DataApi 20 | 21 | api = DataApi(addr="tcp://data.quantos.org:8910") 22 | 23 | api.login("手机号", "token") 24 | 25 | df, msg = api.daily( 26 | symbol="600832.SH, 600030.SH", 27 | start_date=20121026, 28 | end_date=20121130, 29 | fields="", 30 | adjust_mode="post") 31 | ``` 32 | 结果示例(前5条记录): 33 | 34 | 35 | |close | code | high | low | oi | open | settle | symbol |trade_date |trade_status |turnover |volume |vwap| 36 | | --- | --- | --- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- | 37 | |5.09| 600832| 5.24| 5.08| NaN |5.23 |NaN |600832.SH| 20121026 |交易 |2.779057e+07| 5381800 | 5.16| 38 | |5.10| 600832| 5.15| 5.08| NaN |5.11 |NaN |600832.SH| 20121029 |交易 |1.320333e+07| 2582557 | 5.11| 39 | |5.11| 600832| 5.18| 5.08| NaN |5.12 |NaN |600832.SH| 20121030 |交易 |1.622705e+07| 3170615 | 5.12| 40 | |5.11| 600832| 5.14| 5.09| NaN |5.12 |NaN |600832.SH| 20121031 |交易 |1.072007e+07| 2097770 | 5.11| 41 | |5.18| 600832| 5.20| 5.12| NaN |5.12 |NaN |600832.SH| 20121101 |交易 |1.972100e+07| 3814712 | 5.17| 42 | 43 | -------------------------------------------------------------------------------- /usercase.md: -------------------------------------------------------------------------------- 1 | # quantOS典型应用场景分析 2 | 3 | 作者:quantOS.org 4 | 5 | 不同的用户需求,决定了不同的系统架构,quantOS提供几种典型的组合场景,供用户自行选择。主要包括: 6 | 7 | + 个人投资者 8 | + 小型投资机构 9 | + 中大型投资机构 10 | + 独立数据用户 11 | + 独立交易用户 12 | 13 | ## 场景1:适合个人投资者 14 | 15 | 个人投资者进行量化投资,一般会面临几个具体的困难: 16 | 17 | * 获取数据的成本比较高,没有自己的数据源 18 | * 没有完整的策略研究框架,用于开发策略和验证策略的有效性 19 | * 实盘交易需要开发对接各种交易接口。 20 | 21 | 以上各种问题,在quantOS上都能得到完美的解决。我们建议的解决方案如下: 22 | 23 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/solution_case1.png?raw=true) 24 | 25 | 1. 使用在线数据源\(data.quantos.org\),作为自己的数据源,数据质量及时可靠,使用DataApi进行访问,简单易用。 26 | 2. 使用JAQS平台进行策略研究。JAQS集成了信号研究、策略回测、回测分析等功能模块,同时支持Alpha、CTA、套利等,可以快速开发策略,进行回测。 27 | 3. 使用TradeSim进行仿真交易,TradeSim支持股票、期货等品种的交易,根据实时行情进行模拟撮合,最大程度接近实盘效果,提供绩效分析功能,方便用户跟踪策略在模拟盘中的绩效,做到心中有数。 28 | 4. 使用vn.py进行实盘交易,vn.py已经实现了与国内各大主流交易系统的对接,可满足个人用户的单帐户交易要求。JAQS和vn.py之间通过TradeApi进行标准化对接,可做到仿真与实盘交易无缝对接。 29 | 30 | **注意**:这个方案只需要安装JAQS即可使用。 31 | 32 | JAQS安装文档参见:[https://github.com/quantOS-org/JAQS/blob/master/doc/install.md](https://github.com/quantOS-org/JAQS/blob/master/doc/install.md) 33 | 34 | ## 场景2:适合小型投资机构 35 | 36 | 与个人投资者不同,小型投资机构进行量化投资,遇到的困难包括: 37 | 38 | * 有自己的研究数据,业务上要求数据系统部署在本地,但没有一套高效的数据系统,将各类数据整合在一起。 39 | * 机构内部有多个用户需要使用数据,对数据标准化有要求。 40 | * 有交易需求,但没有能力维护一套大的交易系统。 41 | * 没有完整的策略研究框架,用于开发策略和验证策略的有效性 42 | 43 | quantOS专门为小型投资机构量身定做的解决方案如下: 44 | 45 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/solution_case2.png?raw=true) 46 | 47 | * 使用DataCore项目,搭建自己的数据系统。DataCore是一款企业级开源量化数据系统,通过标准化接口提供高速实时行情、历史行情和参考数据等核心服务,覆盖股票、商品期货、股指期货、国债期货等品种,适配CTP、万得、聚源、Tushare等各类数据。 48 | * 使用JAQS进行策略研究。JAQS集成了信号研究、策略回测、回测分析等功能模块,同时支持Alpha、CTA、套利等,可以快速开发策略,进行回测。 49 | * 使用TradeSim进行仿真交易,TradeSim支持股票、期货等品种的交易,根据实时行情进行模拟撮合,最大程度接近实盘效果,提供绩效分析功能,方便用户跟踪策略在模拟盘中的绩效,做到心中有数。 50 | * 使用vn.py进行实盘交易,vn.py已经实现了与国内各大主流交易系统的对接,可满足小型投资机构少量帐户的交易要求。JAQS和vn.py之间通过TradeApi进行标准化对接,可做到仿真与实盘交易无缝对接。 51 | 52 | **注意**:这个方案需要安装DataCore和JAQS。 53 | 54 | DataCore安装文档参见:[https://github.com/quantOS-org/DataCore/blob/master/doc/install.md](https://github.com/quantOS-org/DataCore/blob/master/doc/install.md) 55 | 56 | JAQS安装文档参见:[https://github.com/quantOS-org/JAQS/blob/master/doc/install.md](https://github.com/quantOS-org/JAQS/blob/master/doc/install.md) 57 | 58 | ## 场景3:适合中大型投资机构 59 | 60 | 中大型机构的业务要求较高,主要包括: 61 | 62 | * 用户数量较多,需要多人共享研究数据和交易通道。 63 | * 有自己的独特的研究数据。数据的标准化、权限管理很重要。 64 | * 交易呈现多个用户、多个产品、多个账户的特点。 65 | * 对实时交易风控有要求。 66 | * 需要有通用的策略研究平台,严谨的研究方法。 67 | 68 | quantOS量化交易平台诞生于对冲基金,从一开始就是为中大型机构设计的。我们建议的解决方案如下: 69 | 70 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/solution_case3.png?raw=true) 71 | 72 | 这个解决方案的特点是: 73 | 74 | * 使用DataCore项目,搭建自己的数据系统。DataCore是一款企业级开源量化数据系统,通过标准化接口提供高速实时行情、历史行情和参考数据等核心服务,覆盖股票、商品期货、股指期货、国债期货等品种,适配CTP、万得、聚源、Tushare等各类数据。 75 | 76 | * 使用JAQS进行策略研究。JAQS集成了信号研究、策略回测、回测分析等功能模块,同时支持Alpha、CTA、套利等,可以快速开发策略,进行回测。 77 | * 使用TradeSim进行仿真交易,TradeSim支持股票、期货等品种的交易,根据实时行情进行模拟撮合,最大程度接近实盘效果,提供绩效分析功能,方便用户跟踪策略在模拟盘中的绩效,做到心中有数。 78 | * 实盘交易建议使用我们的专业版交易软件TKPro。 79 | 80 | **注意**:这个方案需要安装DataCore和JAQS. 81 | 82 | DataCore安装文档参见:[https://github.com/quantOS-org/DataCore/blob/master/doc/install.md](https://github.com/quantOS-org/DataCore/blob/master/doc/install.md) 83 | 84 | JAQS安装文档参见:[https://github.com/quantOS-org/JAQS/blob/master/doc/install.md](https://github.com/quantOS-org/JAQS/blob/master/doc/install.md) 85 | 86 | **TKPro目前尚未开源** 87 | 88 | TKPro支持的交易功能非常丰富,包括: 89 | 90 | * 用户登录,选择策略号 91 | * 查询策略持仓 92 | * 查询账户资金 93 | * 查询委托、成交 94 | * 成交推送,委托状态推送 95 | * 普通下单、篮子下单 96 | * 算法下单(TWAP、VWAP,配对交易,最优价格算法等) 97 | * 撤单 98 | * 相对数量下单 99 | * 组合目标下单 100 | 101 | 除了下单外,TKPro还提供的功能包括: 102 | 103 | * 多策略管理 104 | * 多交易通道支持 105 | * 智能交易路由 106 | * 极速交易风控 107 | 108 | TKPro是一款适合中大型交易机构的企业级交易系统,可以本地化部署,有兴趣的同学可以联系[tkpro@quantos.org](mailto:tkpro@quantos.org)。 109 | 110 | ## 场景4:独立数据用户 111 | 112 | 独立数据客户希望通过获取数据后,进行数据分析。我们建议的方案如下: 113 | 114 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/solution_case4.png?raw=true) 115 | 116 | 1. 使用在线数据源\(data.quantos.org\),作为自己的数据源,数据质量及时可靠,使用DataApi进行访问,简单易用。 117 | 2. 使用JAQS平台进行数据分析系统。JAQS提供的DataView组件,可方便快捷的取到用户需要的数据,支持通过公式定义衍生数据,支持本地化存储。 118 | 3. 用户获得数据后,根据自己的业务生成报表和分析结果。 119 | 120 | **注意**:这个方案只需要安装JAQS即可使用。 121 | 122 | JAQS安装文档参见:[https://github.com/quantOS-org/JAQS/blob/master/doc/install.md](https://github.com/quantOS-org/JAQS/blob/master/doc/install.md) 123 | 124 | ## 场景5:独立交易用户 125 | 126 | 独立交易客户希望能直接进行交易,我们建议的方案如下: 127 | 128 | ![](https://github.com/quantOS-org/quantOSUserGuide/blob/master/assets/solution_case5.png?raw=true) 129 | 130 | * 安装TradeApi,通过统一的TradeApi可以对接仿真交易和实盘交易 131 | * 使用TradeSim进行仿真交易,TradeSim支持股票、期货等品种的交易,根据实时行情进行模拟撮合,最大程度接近实盘效果,提供绩效分析功能,方便用户跟踪策略在模拟盘中的绩效,做到心中有数。 132 | * 使用vn.py进行实盘交易,vn.py已经实现了与国内各大主流交易系统的对接,可满足小型投资机构少量帐户的交易要求。TradeApi可以无缝对接vnpy。 133 | * 使用我们的专业版交易软件TKPro,这个一般适合中大型投资机构。 134 | 135 | --------------------------------------------------------------------------------