├── LICENSE ├── README.md ├── YML ├── app ├── CA │ ├── client.cer │ └── client.key ├── conf │ ├── appinfo.ini │ └── log.ini ├── db.py ├── futu_server_api.py ├── log │ └── db.log ├── mainapp.py ├── myutility.py └── script.sh ├── demo.py ├── futu-openapi-api.md ├── futu-openapi-instructions.md └── mydata ├── ib_logfile0 ├── ib_logfile1 ├── ibdata1 ├── mysql ├── columns_priv.MYD ├── columns_priv.MYI ├── columns_priv.frm ├── db.MYD ├── db.MYI ├── db.frm ├── event.MYD ├── event.MYI ├── event.frm ├── func.MYD ├── func.MYI ├── func.frm ├── general_log.CSM ├── general_log.CSV ├── general_log.frm ├── help_category.MYD ├── help_category.MYI ├── help_category.frm ├── help_keyword.MYD ├── help_keyword.MYI ├── help_keyword.frm ├── help_relation.MYD ├── help_relation.MYI ├── help_relation.frm ├── help_topic.MYD ├── help_topic.MYI ├── help_topic.frm ├── host.MYD ├── host.MYI ├── host.frm ├── ndb_binlog_index.MYD ├── ndb_binlog_index.MYI ├── ndb_binlog_index.frm ├── plugin.MYD ├── plugin.MYI ├── plugin.frm ├── proc.MYD ├── proc.MYI ├── proc.frm ├── procs_priv.MYD ├── procs_priv.MYI ├── procs_priv.frm ├── proxies_priv.MYD ├── proxies_priv.MYI ├── proxies_priv.frm ├── servers.MYD ├── servers.MYI ├── servers.frm ├── slow_log.CSM ├── slow_log.CSV ├── slow_log.frm ├── tables_priv.MYD ├── tables_priv.MYI ├── tables_priv.frm ├── time_zone.MYD ├── time_zone.MYI ├── time_zone.frm ├── time_zone_leap_second.MYD ├── time_zone_leap_second.MYI ├── time_zone_leap_second.frm ├── time_zone_name.MYD ├── time_zone_name.MYI ├── time_zone_name.frm ├── time_zone_transition.MYD ├── time_zone_transition.MYI ├── time_zone_transition.frm ├── time_zone_transition_type.MYD ├── time_zone_transition_type.MYI ├── time_zone_transition_type.frm ├── user.MYD ├── user.MYI └── user.frm ├── performance_schema ├── cond_instances.frm ├── db.opt ├── events_waits_current.frm ├── events_waits_history.frm ├── events_waits_history_long.frm ├── events_waits_summary_by_instance.frm ├── events_waits_summary_by_thread_by_event_name.frm ├── events_waits_summary_global_by_event_name.frm ├── file_instances.frm ├── file_summary_by_event_name.frm ├── file_summary_by_instance.frm ├── mutex_instances.frm ├── performance_timers.frm ├── rwlock_instances.frm ├── setup_consumers.frm ├── setup_instruments.frm ├── setup_timers.frm └── threads.frm └── test ├── account_token.frm └── db.opt /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 | - 富途开放平台第三方使用文档,见 [futu-openapi-instructions.md](./futu-openapi-instructions.md) 2 | - 富途开放平台第三方接口(API)说明文档,见[futu-openapi-api.md](./futu-openapi-api.md) 3 | -------------------------------------------------------------------------------- /YML: -------------------------------------------------------------------------------- 1 | mysql: 2 | image: daocloud.io/zznn/mysql:latest 3 | volumes: 4 | - /home/zhulei/mydata:/var/lib/mysql 5 | environment: 6 | - MYSQL_ROOT_PASSWORD=123456 7 | myapp: 8 | image: daocloud.io/zznn/flask:latest 9 | command: ./script.sh 10 | links: 11 | - mysql:futudb 12 | ports: 13 | - 8888:8080 14 | volumes: 15 | - /home/zhulei/app:/app 16 | - /etc/localtime:/etc/localtime 17 | -------------------------------------------------------------------------------- /app/CA/client.cer: -------------------------------------------------------------------------------- 1 | Certificate: 2 | Data: 3 | Version: 1 (0x0) 4 | Serial Number: 4100 (0x1004) 5 | Signature Algorithm: sha1WithRSAEncryption 6 | Issuer: C=CN, ST=Guangdong, L=Shenzhen, O=FUTU, OU=OpenAPI, CN=futu5.com/emailAddress=openapi@futunn.com 7 | Validity 8 | Not Before: May 3 09:48:03 2016 GMT 9 | Not After : Apr 28 09:48:03 2017 GMT 10 | Subject: C=CN, ST=Guangdong, O=Tencent, OU=\, L=Shenzhen, CN=qq.com 11 | Subject Public Key Info: 12 | Public Key Algorithm: rsaEncryption 13 | Public-Key: (1024 bit) 14 | Modulus: 15 | 00:b3:88:8a:69:62:30:88:09:a4:0d:e8:37:fc:24: 16 | fc:d7:d7:f0:6c:b2:19:38:be:89:6f:f0:75:fb:8b: 17 | 3f:1c:d3:28:83:f7:f6:5c:8c:f5:7a:c4:61:d3:0e: 18 | 51:cf:ea:e7:36:e0:08:7d:86:7f:76:25:9c:b9:c2: 19 | 38:d9:71:a8:c5:7d:96:f6:9b:e6:5e:33:95:f6:bd: 20 | d0:46:88:45:57:43:f0:e0:8f:22:a8:61:8e:55:e7: 21 | ee:fd:89:ab:9f:23:4d:ee:ee:6e:1a:56:93:58:93: 22 | 4f:72:ca:eb:54:24:94:ca:38:b5:cb:f0:45:f8:03: 23 | af:6d:a8:e6:f6:43:78:23:01 24 | Exponent: 65537 (0x10001) 25 | Signature Algorithm: sha1WithRSAEncryption 26 | 3a:aa:9d:b4:85:92:6f:54:b7:0a:37:0c:d0:5f:92:b6:8c:bf: 27 | 66:a8:14:74:59:97:17:03:65:48:28:4a:ca:53:7f:23:61:0d: 28 | 5f:b3:12:6a:40:10:04:0c:d1:ce:13:d3:07:50:62:a7:c3:07: 29 | 0f:5f:9d:34:a9:ad:fc:55:56:ba:ea:b0:dd:22:11:68:26:b2: 30 | 3b:06:47:06:a8:67:58:83:b3:48:c4:d3:18:d2:05:d6:9c:9e: 31 | c8:f3:d9:b8:07:62:75:39:be:ad:65:f6:1a:d6:cb:40:45:92: 32 | ae:ee:53:e2:b9:49:c1:9b:eb:93:03:21:40:d4:86:f0:c3:d0: 33 | d1:fb 34 | -----BEGIN CERTIFICATE----- 35 | MIICYDCCAckCAhAEMA0GCSqGSIb3DQEBBQUAMIGMMQswCQYDVQQGEwJDTjESMBAG 36 | A1UECAwJR3Vhbmdkb25nMREwDwYDVQQHDAhTaGVuemhlbjENMAsGA1UECgwERlVU 37 | VTEQMA4GA1UECwwHT3BlbkFQSTESMBAGA1UEAwwJZnV0dTUuY29tMSEwHwYJKoZI 38 | hvcNAQkBFhJvcGVuYXBpQGZ1dHVubi5jb20wHhcNMTYwNTAzMDk0ODAzWhcNMTcw 39 | NDI4MDk0ODAzWjBjMQswCQYDVQQGEwJDTjESMBAGA1UECBMJR3Vhbmdkb25nMRAw 40 | DgYDVQQKEwdUZW5jZW50MQowCAYDVQQLFAFcMREwDwYDVQQHEwhTaGVuemhlbjEP 41 | MA0GA1UEAxMGcXEuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCziIpp 42 | YjCICaQN6Df8JPzX1/Bsshk4volv8HX7iz8c0yiD9/ZcjPV6xGHTDlHP6uc24Ah9 43 | hn92JZy5wjjZcajFfZb2m+ZeM5X2vdBGiEVXQ/DgjyKoYY5V5+79iaufI03u7m4a 44 | VpNYk09yyutUJJTKOLXL8EX4A69tqOb2Q3gjAQIDAQABMA0GCSqGSIb3DQEBBQUA 45 | A4GBADqqnbSFkm9Utwo3DNBfkraMv2aoFHRZlxcDZUgoSspTfyNhDV+zEmpAEAQM 46 | 0c4T0wdQYqfDBw9fnTSprfxVVrrqsN0iEWgmsjsGRwaoZ1iDs0jE0xjSBdacnsjz 47 | 2bgHYnU5vq1l9hrWy0BFkq7uU+K5ScGb65MDIUDUhvDD0NH7 48 | -----END CERTIFICATE----- 49 | -------------------------------------------------------------------------------- /app/CA/client.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIICXAIBAAKBgQCziIppYjCICaQN6Df8JPzX1/Bsshk4volv8HX7iz8c0yiD9/Zc 3 | jPV6xGHTDlHP6uc24Ah9hn92JZy5wjjZcajFfZb2m+ZeM5X2vdBGiEVXQ/DgjyKo 4 | YY5V5+79iaufI03u7m4aVpNYk09yyutUJJTKOLXL8EX4A69tqOb2Q3gjAQIDAQAB 5 | AoGASHrFNkpXwXPy8VJg18Cu+wzImXlFSW1S2wg++XB76E0vPCftI+wcZpXF0Ikl 6 | akUxVywXAWY9KxuALFZG0TJbqcIqwmaD47akpCW+CBLasi2QZ39B6sZlaWxAz7U3 7 | grfZ1/In5PPnb/j4MgypWTg5EHuReZcqUFA/f+rb8/0lWAECQQDaXiw3+SZgB4OY 8 | 5JPm2Hn/FyV02FUDyP4915i1Snrq/g+ccBsHA9GtxNpCxBakT6GcUaGXGQ6mXl9n 9 | kP0KZ2YhAkEA0nkXAnhVUBRVqxUXnfkm9Od1yga7Fj8GpKu0HLQLKoJN2wpfGi+G 10 | lUUiOnGb4dFkPvGTDX4xTsQjEum7mOtg4QJBAMrHDJTlvqcKE0AVcuq5N4CUQ+of 11 | QcMEEGPpIxumkEJLrr98svxupXWSCYRahxQKBm8ctsuTLzF7DWklEHVq00ECQA/x 12 | JBEH1E5we9ytiFBq4syCC6X1xI320CYA62+RI5dgr0z8CCAPoX4E8obCvC/qkFFE 13 | MwM+n7V7nbx8/7yhd4ECQD2v3urfatJa7NYi3Zn0zxJQFdF+Gma58qvLa2K3wM62 14 | yKSsbpfPqSWLYv7zQ3OlPC6d8m9pUiSW9US1XDZguP8= 15 | -----END RSA PRIVATE KEY----- 16 | -------------------------------------------------------------------------------- /app/conf/appinfo.ini: -------------------------------------------------------------------------------- 1 | [10000001] 2 | app_secret = !UMC+RztTD5De9ZV4sg6H6eUURJdyzlL 3 | client_cer = ./CA/client.cer 4 | client_key = ./CA/client.key 5 | 6 | -------------------------------------------------------------------------------- /app/conf/log.ini: -------------------------------------------------------------------------------- 1 | [loggers] 2 | keys = root 3 | 4 | [handlers] 5 | keys = consoleHandler, fileHandler 6 | 7 | [formatters] 8 | keys = fmt 9 | 10 | [logger_root] 11 | level = DEBUG 12 | handlers = fileHandler 13 | 14 | [handler_consoleHandler] 15 | class = StreamHandler 16 | level = DEBUG 17 | formatter = fmt 18 | args = (sys.stdout,) 19 | 20 | [handler_fileHandler] 21 | class = logging.handlers.RotatingFileHandler 22 | level = DEBUG 23 | formatter = fmt 24 | args = ('/app/log/db.log', 'a', 1024*1024, 5,) 25 | 26 | [formatter_fmt] 27 | format = %(asctime)s - %(filename)s:%(lineno)s - %(funcName)s - %(levelname)s - %(message)s 28 | -------------------------------------------------------------------------------- /app/db.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import pymysql.cursors 3 | import logging 4 | import logging.config 5 | 6 | logging.config.fileConfig('./conf/log.ini') 7 | db_logger = logging.getLogger() 8 | 9 | 10 | config = { 11 | 'host':'172.17.0.2', 12 | 'port':3306, 13 | 'user':'root', 14 | 'password':'123456', 15 | 'db':'test', 16 | 'charset':'utf8', 17 | } 18 | 19 | connection = pymysql.connect(**config) 20 | 21 | def get_token(appid, card, isTrade): 22 | try: 23 | connection.ping() 24 | except Exception as e: 25 | connection = pymysql.connect(**config) 26 | finally: 27 | pass 28 | 29 | if isTrade is True: 30 | token_type = 'tradetoken' 31 | else: 32 | token_type = 'accesstoken' 33 | try: 34 | with connection.cursor() as cursor: 35 | sql = 'select %s from account_token ' % token_type 36 | sql += 'where card = %s and appid = %s' 37 | cursor.execute(sql, (card, appid)) 38 | result = cursor.fetchone() 39 | connection.commit() 40 | if result is not None and result[0] is not None: 41 | db_logger.info('%s SUCCESS' % token_type) 42 | return result[0] 43 | else: 44 | db_logger.info('%s FAIL' % token_type) 45 | return None 46 | except Exception as e: 47 | connection.rollback() 48 | db_logger.error('get FAIL ,following as:%s' % str(e), exc_info = True) 49 | finally: 50 | connection.close() 51 | 52 | 53 | def save_update_token(account, appid, market, token, card, isTrade, card_desc = None): 54 | try: 55 | connection.ping() 56 | except Exception as e: 57 | connection = pymysql.connect(**config) 58 | finally: 59 | pass 60 | 61 | if isTrade is True: 62 | token_type = 'tradetoken' 63 | else: 64 | token_type = 'accesstoken' 65 | try: 66 | with connection.cursor() as cursor: 67 | operate = '' 68 | sql = 'select id from account_token where card = %s and appid = %s' 69 | cursor.execute(sql, (card, appid)) 70 | result = cursor.fetchone() 71 | if result is None: 72 | operate = 'insert' 73 | sql1 = 'insert into account_token(account, %s, card, appid, market, card_infor)' % token_type 74 | sql1 += ' values(%s, %s, %s, %s, %s, %s)' 75 | cursor.execute(sql1, (account, token, card, appid, market, card_desc)) 76 | else: 77 | operate = 'update' 78 | sql = 'update account_token set %s =' % token_type 79 | sql += '%s where card = %s and appid = %s' 80 | cursor.execute(sql, (token, card, appid)) 81 | db_logger.info('%s SUCCESS' % operate) 82 | connection.commit() 83 | return 'success' 84 | except Exception as e: 85 | connection.rollback() 86 | db_logger.error('%s FAIL,following as:%s' % (operate, str(e)), exc_info = True) 87 | return 'failure' 88 | finally: 89 | connection.close() 90 | 91 | def delete_tokens(account, appid): 92 | global operate 93 | try: 94 | connection.ping() 95 | except Exception as e: 96 | connection = pymysql.connect(**config) 97 | finally: 98 | pass 99 | 100 | try: 101 | with connection.cursor() as cursor: 102 | operate = 'delete' 103 | sql = 'delete from account_token where account = %s and appid = %s' 104 | cursor.execute(sql, (account, appid)) 105 | db_logger.info('%s SUCCESS' % operate) 106 | connection.commit() 107 | return 'success' 108 | except Exception as e: 109 | connection.rollback() 110 | db_logger.error('%s FAIL,following as:%s' % (operate, str(e)), exc_info = True) 111 | return 'failure' 112 | finally: 113 | connection.close() 114 | 115 | def list_cards(account, appid): 116 | cards = [] 117 | try: 118 | connection.ping() 119 | except Exception as e: 120 | connection = pymysql.connect(**config) 121 | finally: 122 | pass 123 | 124 | try: 125 | with connection.cursor() as cursor: 126 | sql = 'select card, card_infor, market from account_token where account = %s and appid = %s' 127 | cursor.execute(sql, (account, appid)) 128 | result = cursor.fetchall() 129 | if len(result) != 0: 130 | for i in range(len(result)): 131 | data = {'card':result[i][0],'card_infor':result[i][1],'market':result[i][2]} 132 | cards.insert(i,data) 133 | db_logger.info('list cards SUCCESS') 134 | connection.commit() 135 | return cards 136 | except Exception as e: 137 | connection.rollback() 138 | db_logger.error('list cards FAIL,following as:%s' % str(e), exc_info = True) 139 | return 'failure' 140 | finally: 141 | connection.close() 142 | 143 | 144 | -------------------------------------------------------------------------------- /app/futu_server_api.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | try: 3 | from urllib import urlencode 4 | except ImportError: 5 | from urllib.parse import urlencode 6 | from datetime import datetime, timedelta 7 | from myutility import gen_signature 8 | from urllib.parse import quote,quote_plus 9 | from db import get_token 10 | import urllib 11 | import json 12 | import random 13 | import time 14 | import requests 15 | import configparser 16 | 17 | config = configparser.ConfigParser() 18 | config.read('./conf/appinfo.ini') 19 | 20 | def check_type(request): 21 | if isinstance(request, dict): 22 | return request 23 | elif isinstance(request.json(), dict): 24 | return request.json() 25 | else: 26 | return request.text 27 | 28 | class client(object): 29 | """docstring for client""" 30 | def __init__(self, app_account, card, appid): 31 | super(client, self).__init__() 32 | for item in config.sections(): 33 | if item == appid: 34 | self.appid = item 35 | self.appsecret = config[item]['app_secret'] 36 | self._cert = (config[item]['client_cer'], config[item]['client_key']) 37 | else: 38 | pass 39 | self.app_account = app_account 40 | self.card = card 41 | self._token = get_token(appid, card, False) 42 | self._tradetoken = get_token(appid, card, True) 43 | 44 | def gen_headers(self, isTrade, data, url, method, lang = 'sc'): 45 | ''' 46 | isTrade字段用于判断是否携带交易授权令牌 47 | ''' 48 | if not self._token: 49 | return {'result_code':2, 'error_msg':'didn\'t get accesstoken'} 50 | 51 | myheaders = { 52 | 'Accept':'application/vnd.futu5.openapi-v1+json', 53 | 'Content-Type':'application/vnd.futu5.openapi-v1+json', 54 | 'X-Futu-Oauth-Appid':self.appid, 55 | 'X-Futu-Oauth-App-Account':self.app_account, 56 | 'X-Futu-Oauth-Nonce':random.randint(1, 100000), 57 | 'X-Futu-Oauth-Accesstoken':self._token, 58 | 'X-Futu-Oauth-Signature-Method':'HMAC-SHA1', 59 | 'X-Futu-Oauth-Timestamp':int(time.time()), 60 | 'X-Futu-Oauth-Version':'1.0', 61 | 'X-Futu-Oauth-Lang':lang #可预留接口扩展 62 | } 63 | 64 | if isTrade: 65 | if self._tradetoken: 66 | myheaders['X-Futu-Oauth-Tradetoken'] = self._tradetoken 67 | else: 68 | return {'result_code':2, 'error_msg':'didn\'t get tradetoken'} 69 | 70 | sigheaders = { 71 | 'X-Futu-Oauth-Appid':myheaders['X-Futu-Oauth-Appid'], 72 | 'X-Futu-Oauth-App-Account':myheaders['X-Futu-Oauth-App-Account'], 73 | 'X-Futu-Oauth-Nonce':myheaders['X-Futu-Oauth-Nonce'], 74 | 'X-Futu-Oauth-Accesstoken':myheaders['X-Futu-Oauth-Accesstoken'], 75 | 'X-Futu-Oauth-Signature-Method':myheaders['X-Futu-Oauth-Signature-Method'], 76 | 'X-Futu-Oauth-Timestamp':myheaders['X-Futu-Oauth-Timestamp'], 77 | 'X-Futu-Oauth-Version':'1.0', 78 | 'X-Futu-Oauth-Lang':myheaders['X-Futu-Oauth-Lang'] 79 | } 80 | 81 | if isTrade: 82 | sigheaders['X-Futu-Oauth-Tradetoken'] = self._tradetoken 83 | 84 | sig = gen_signature(sigheaders, data, url, method, self.appsecret, self._token) 85 | myheaders['X-Futu-Oauth-Signature'] = sig 86 | return myheaders 87 | 88 | def get(self, url, data = None, lang = 'sc'): 89 | ''' 90 | GET请求,获取数据 91 | ''' 92 | headers = self.gen_headers(False, data, url, 'GET', lang) 93 | if 'error_msg' in headers: 94 | return headers 95 | else: 96 | return requests.get(url, params = data, headers = headers, cert = self._cert) 97 | 98 | def post(self, url, data = None): 99 | ''' 100 | POST请求,修改数据 101 | ''' 102 | headers = self.gen_headers(True, data, url, 'POST') 103 | if 'error_msg' in headers: 104 | return headers 105 | else: 106 | return requests.post(url, data = json.dumps(data), headers = headers, cert = self._cert) 107 | 108 | 109 | def put(self, url, data = None): 110 | ''' 111 | PUT请求是幂等的,重复执行多次,效果一样 112 | ''' 113 | headers = self.gen_headers(True, data, url, 'PUT') 114 | if 'error_msg' in headers: 115 | return headers 116 | else: 117 | return requests.put(url, data = json.dumps(data), headers = headers, cert = self._cert) 118 | 119 | 120 | def get_trade_token(self, trade_pswd): 121 | ''' 122 | 验证交易密码,获取tradetoken 123 | ''' 124 | data = { 125 | 'trade_pswd':trade_pswd 126 | } 127 | url = 'https://openapi.futu5.com/auth_trade_pswd' 128 | headers = self.gen_headers(False, data, url, 'POST') 129 | if 'error_msg' in headers: 130 | return headers 131 | req = requests.post(url, 132 | data = json.dumps(data), 133 | headers = headers, 134 | cert = self._cert) 135 | return check_type(req) 136 | 137 | 138 | def get_account_detail(self): 139 | ''' 140 | 获取账户详情 141 | ''' 142 | req = self.get('https://tradeopen.futu5.com/account') 143 | return check_type(req) 144 | 145 | 146 | def get_account_cash(self): 147 | ''' 148 | 获取现金数据 149 | ''' 150 | req = self.get('https://tradeopen.futu5.com/account/cash') 151 | return check_type(req) 152 | 153 | 154 | def get_account_portfolio(self): 155 | ''' 156 | 获取当前账户股票持仓数据 157 | ''' 158 | req = self.get('https://tradeopen.futu5.com/account/portfolio') 159 | return check_type(req) 160 | 161 | 162 | def get_list_orders(self, date_begin = '', date_end = ''): 163 | ''' 164 | 获取订单数据 165 | datetime.now().date().strftime('%Y%m%d') 166 | ''' 167 | url = 'https://tradeopen.futu5.com/orders?date_begin={0}&date_end={1}'.format(date_begin, date_end) 168 | 169 | req = self.get( 170 | url, 171 | lang = 'tc' 172 | ) 173 | return check_type(req) 174 | 175 | 176 | def get_list_trades(self): 177 | ''' 178 | 获取账户今日成交列表 179 | ''' 180 | req = self.get('https://tradeopen.futu5.com/trades') 181 | return check_type(req) 182 | 183 | 184 | def place_order(self, code, quantity, price, side, ltype): 185 | ''' 186 | 下订单 187 | ''' 188 | req = self.post( 189 | 'https://tradeopen.futu5.com/orders', 190 | { 191 | 'code':code, 192 | 'quantity':quantity, 193 | 'price':price, 194 | 'side':side, 195 | 'type':ltype 196 | } 197 | ) 198 | return check_type(req) 199 | 200 | 201 | def change_order(self, order_id, quantity, price): 202 | ''' 203 | 修改订单 204 | ''' 205 | url = 'https://tradeopen.futu5.com/orders/' + str(order_id) 206 | req = self.put( 207 | url, 208 | { 209 | 'action':1, 210 | 'quantity':quantity, 211 | 'price':price 212 | }) 213 | return check_type(req) 214 | 215 | 216 | def cancel_order(self, order_id): 217 | ''' 218 | 取消订单,对还没有成交的订单撤单 219 | ''' 220 | url = 'https://tradeopen.futu5.com/orders/' + str(order_id) 221 | req = self.put( 222 | url, 223 | { 224 | 'action':0 225 | } 226 | ) 227 | return check_type(req) 228 | 229 | -------------------------------------------------------------------------------- /app/log/db.log: -------------------------------------------------------------------------------- 1 | 2016-05-11 07:32:49,968 - db.py:43 - get_token - INFO - accesstoken SUCCESS 2 | 2016-05-11 07:32:49,970 - db.py:43 - get_token - INFO - tradetoken SUCCESS 3 | 2016-05-11 07:32:50,292 - mainapp.py:80 - get_account_cash - INFO - SUCCESS 4 | 2016-05-11 07:32:59,394 - db.py:43 - get_token - INFO - accesstoken SUCCESS 5 | 2016-05-11 07:32:59,395 - db.py:43 - get_token - INFO - tradetoken SUCCESS 6 | 2016-05-11 07:32:59,578 - mainapp.py:80 - get_account_cash - INFO - SUCCESS 7 | 2016-05-11 15:56:32,961 - db.py:43 - get_token - INFO - accesstoken SUCCESS 8 | 2016-05-11 15:56:32,963 - db.py:43 - get_token - INFO - tradetoken SUCCESS 9 | 2016-05-11 15:56:33,185 - mainapp.py:68 - get_account_detail - INFO - SUCCESS 10 | 2016-05-11 15:56:51,710 - db.py:43 - get_token - INFO - accesstoken SUCCESS 11 | 2016-05-11 15:56:51,712 - db.py:43 - get_token - INFO - tradetoken SUCCESS 12 | 2016-05-11 15:56:52,071 - mainapp.py:68 - get_account_detail - INFO - SUCCESS 13 | 2016-05-11 16:17:46,475 - db.py:43 - get_token - INFO - accesstoken SUCCESS 14 | 2016-05-11 16:17:46,477 - db.py:43 - get_token - INFO - tradetoken SUCCESS 15 | 2016-05-11 16:17:47,725 - mainapp.py:68 - get_account_detail - INFO - SUCCESS 16 | 2016-05-11 16:17:49,493 - db.py:43 - get_token - INFO - accesstoken SUCCESS 17 | 2016-05-11 16:17:49,494 - db.py:43 - get_token - INFO - tradetoken SUCCESS 18 | 2016-05-11 16:17:49,690 - mainapp.py:68 - get_account_detail - INFO - SUCCESS 19 | 2016-05-11 16:18:29,560 - db.py:43 - get_token - INFO - accesstoken SUCCESS 20 | 2016-05-11 16:18:29,561 - db.py:43 - get_token - INFO - tradetoken SUCCESS 21 | 2016-05-11 16:18:29,885 - mainapp.py:80 - get_account_cash - INFO - SUCCESS 22 | 2016-05-11 16:18:33,576 - db.py:43 - get_token - INFO - accesstoken SUCCESS 23 | 2016-05-11 16:18:33,577 - db.py:43 - get_token - INFO - tradetoken SUCCESS 24 | 2016-05-11 16:18:33,751 - mainapp.py:80 - get_account_cash - INFO - SUCCESS 25 | 2016-05-11 16:54:57,543 - db.py:43 - get_token - INFO - accesstoken SUCCESS 26 | 2016-05-11 16:54:57,545 - db.py:43 - get_token - INFO - tradetoken SUCCESS 27 | 2016-05-11 16:54:57,819 - mainapp.py:80 - get_account_cash - INFO - SUCCESS 28 | 2016-05-11 16:55:10,248 - db.py:43 - get_token - INFO - accesstoken SUCCESS 29 | 2016-05-11 16:55:10,249 - db.py:43 - get_token - INFO - tradetoken SUCCESS 30 | 2016-05-11 16:55:10,569 - mainapp.py:92 - get_account_portfolio - INFO - SUCCESS 31 | 2016-05-11 16:55:14,422 - db.py:43 - get_token - INFO - accesstoken SUCCESS 32 | 2016-05-11 16:55:14,423 - db.py:43 - get_token - INFO - tradetoken SUCCESS 33 | 2016-05-11 16:55:14,603 - mainapp.py:92 - get_account_portfolio - INFO - SUCCESS 34 | 2016-05-11 16:55:19,911 - db.py:43 - get_token - INFO - accesstoken SUCCESS 35 | 2016-05-11 16:55:19,913 - db.py:43 - get_token - INFO - tradetoken SUCCESS 36 | 2016-05-11 16:55:20,296 - mainapp.py:92 - get_account_portfolio - INFO - SUCCESS 37 | 2016-05-11 16:58:15,894 - db.py:43 - get_token - INFO - accesstoken SUCCESS 38 | 2016-05-11 16:58:15,896 - db.py:43 - get_token - INFO - tradetoken SUCCESS 39 | 2016-05-11 16:58:16,104 - mainapp.py:92 - get_account_portfolio - INFO - SUCCESS 40 | 2016-05-11 16:58:31,651 - db.py:43 - get_token - INFO - accesstoken SUCCESS 41 | 2016-05-11 16:58:31,653 - db.py:43 - get_token - INFO - tradetoken SUCCESS 42 | 2016-05-11 16:58:31,933 - mainapp.py:105 - get_list_orders - INFO - SUCCESS 43 | 2016-05-11 17:20:31,935 - db.py:43 - get_token - INFO - accesstoken SUCCESS 44 | 2016-05-11 17:20:31,937 - db.py:43 - get_token - INFO - tradetoken SUCCESS 45 | 2016-05-11 17:20:32,186 - mainapp.py:68 - get_account_detail - INFO - SUCCESS 46 | 2016-05-11 17:20:34,544 - db.py:43 - get_token - INFO - accesstoken SUCCESS 47 | 2016-05-11 17:20:34,545 - db.py:43 - get_token - INFO - tradetoken SUCCESS 48 | 2016-05-11 17:20:34,724 - mainapp.py:68 - get_account_detail - INFO - SUCCESS 49 | 2016-05-11 09:42:20,555 - db.py:43 - get_token - INFO - accesstoken SUCCESS 50 | 2016-05-11 09:42:20,557 - db.py:43 - get_token - INFO - tradetoken SUCCESS 51 | 2016-05-11 09:42:20,899 - mainapp.py:68 - get_account_detail - INFO - SUCCESS 52 | 2016-05-11 09:42:26,243 - db.py:43 - get_token - INFO - accesstoken SUCCESS 53 | 2016-05-11 09:42:26,244 - db.py:43 - get_token - INFO - tradetoken SUCCESS 54 | 2016-05-11 09:42:26,525 - mainapp.py:68 - get_account_detail - INFO - SUCCESS 55 | 2016-05-11 17:43:47,848 - db.py:43 - get_token - INFO - accesstoken SUCCESS 56 | 2016-05-11 17:43:47,850 - db.py:43 - get_token - INFO - tradetoken SUCCESS 57 | 2016-05-11 17:43:48,073 - mainapp.py:68 - get_account_detail - INFO - SUCCESS 58 | 2016-05-11 17:43:48,993 - db.py:43 - get_token - INFO - accesstoken SUCCESS 59 | 2016-05-11 17:43:48,995 - db.py:43 - get_token - INFO - tradetoken SUCCESS 60 | 2016-05-11 17:43:49,218 - mainapp.py:68 - get_account_detail - INFO - SUCCESS 61 | -------------------------------------------------------------------------------- /app/mainapp.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from flask import Flask, jsonify, request, abort, make_response 3 | from futu_server_api import * 4 | from db import save_update_token 5 | from db import delete_tokens 6 | from db import list_cards 7 | import logging 8 | import logging.config 9 | import json 10 | 11 | app = Flask(__name__) 12 | 13 | logging.config.fileConfig('./conf/log.ini') 14 | no_db_logger = logging.getLogger() 15 | 16 | def check_parameters(pjson): 17 | if not pjson or not 'app_account' in pjson or not 'card' in pjson or not 'appid' in pjson: 18 | no_db_logger.info('No Parameter') 19 | abort(400) 20 | cli = {'account':pjson['app_account'], 'card':pjson['card'], 'appid':pjson['appid']} 21 | return client(cli['account'], cli['card'], cli['appid']) 22 | 23 | def log_handler(myjson, mytitle): 24 | if 'ClientWarning' in myjson: 25 | return '%s' % myjson['ClientWarning'] 26 | elif myjson['result_code'] == 0: 27 | return 'SUCCESS' 28 | else: 29 | return 'FAIL ,REASON OF FAILURE:%s ,PARAMETER:%s' % (myjson['error_msg'], request.json) 30 | 31 | 32 | @app.route('/') 33 | def hello_world(): 34 | no_db_logger.info('server start#####') 35 | return 'hello 22222222 world!' 36 | 37 | 38 | @app.route('/api/v1/tradetoken', methods=['POST']) 39 | def trade_token(): 40 | trade_pswd = request.json['trade_pswd'] 41 | account = request.json['app_account'] 42 | card = request.json['card'] 43 | appid = request.json['appid'] 44 | cc = check_parameters(request.json) 45 | message = cc.get_trade_token(trade_pswd) 46 | if message['result_code'] != 0 and message['error_msg'] == 'didn\'t get accesstoken': 47 | no_db_logger.info('didn\'t get accesstoken') 48 | return json.dumps({'result_code':2,'error_msg':'didn\'t get accesstoken'}, ensure_ascii=False) 49 | if message['result_code'] == 0: 50 | token = message['data']['trade_token'] 51 | save_update_token(account, appid, None, token, card, True) 52 | return jsonify(**message) 53 | 54 | 55 | 56 | @app.route('/api/v1/account', methods=['POST']) 57 | def get_account_detail(): 58 | cc = check_parameters(request.json) 59 | message = cc.get_account_detail() 60 | logtext = log_handler(message, '获取账户信息') 61 | no_db_logger.info(logtext) 62 | return json.dumps(message, ensure_ascii=False) 63 | 64 | 65 | 66 | @app.route('/api/v1/account/cash', methods=['POST']) 67 | def get_account_cash(): 68 | cc = check_parameters(request.json) 69 | message = cc.get_account_cash() 70 | logtext = log_handler(message, '获取账户现金') 71 | no_db_logger.info(logtext) 72 | return json.dumps(message, ensure_ascii=False) 73 | 74 | 75 | @app.route('/api/v1/account/portfolio', methods=['POST']) 76 | def get_account_portfolio(): 77 | cc = check_parameters(request.json) 78 | message = cc.get_account_portfolio() 79 | logtext = log_handler(message, '获取账户持仓') 80 | no_db_logger.info(logtext) 81 | return json.dumps(message, ensure_ascii=False) 82 | 83 | 84 | @app.route('/api/v1/get_list_orders', methods=['POST']) 85 | def get_list_orders(): 86 | date_begin = request.json['date_begin'] 87 | date_end = request.json['date_end'] 88 | cc = check_parameters(request.json) 89 | message = cc.get_list_orders() 90 | logtext = log_handler(message, '获取订单列表') 91 | no_db_logger.info(logtext) 92 | return json.dumps(message, ensure_ascii=False) 93 | 94 | 95 | @app.route('/api/v1/get_list_trades', methods=['POST']) 96 | def get_list_trades(): 97 | cc = check_parameters(request.json) 98 | message = cc.get_list_trades() 99 | logtext = log_handler(message, '获取交易列表') 100 | no_db_logger.info(logtext) 101 | return json.dumps(message, ensure_ascii=False) 102 | 103 | 104 | @app.route('/api/v1/place_order', methods=['POST']) 105 | def place_order(): 106 | code = request.json['code'] 107 | quantity = request.json['quantity'] 108 | price = request.json['price'] 109 | side = request.json['side'] 110 | ltype = request.json['type'] 111 | cc = check_parameters(request.json) 112 | message = cc.place_order(code, quantity, price, side, ltype) 113 | logtext = log_handler(message, '下单') 114 | no_db_logger.info(logtext) 115 | return json.dumps(message, ensure_ascii=False) 116 | 117 | 118 | @app.route('/api/v1/change_order', methods=['POST']) 119 | def change_order(): 120 | order_id = request.json['order_id'] 121 | quantity = request.json['quantity'] 122 | price = request.json['price'] 123 | cc = check_parameters(request.json) 124 | message = cc.change_order(order_id, quantity, price) 125 | logtext = log_handler(message, '改单') 126 | no_db_logger.info(logtext) 127 | return json.dumps(message, ensure_ascii=False) 128 | 129 | 130 | @app.route('/api/v1/cancle_order', methods=['POST']) 131 | def cancle_order(): 132 | order_id = request.json['order_id'] 133 | cc = check_parameters(request.json) 134 | message = cc.cancel_order(order_id) 135 | logtext = log_handler(message, '撤单') 136 | no_db_logger.info(logtext) 137 | return json.dumps(message, ensure_ascii=False) 138 | 139 | 140 | @app.route('/ap1/v1/save_token', methods=['POST']) 141 | def save_token(): 142 | account = request.json['app_account'] 143 | appid = request.json['appid'] 144 | market = request.json['market'] 145 | token = request.json['token'] 146 | card = request.json['card'] 147 | card_desc = request.json['text'] 148 | DB_result = save_update_token(account, appid, market, token, card, False, card_desc) 149 | if DB_result == 'success': 150 | no_db_logger.info('token save success') 151 | return json.dumps({'result_code':0,'error_msg':''}, ensure_ascii=False) 152 | else: 153 | no_db_logger.info('token save fail') 154 | return json.dumps({'result_code':1,'error_msg':'token保存失败'}, ensure_ascii=False) 155 | 156 | 157 | 158 | @app.route('/api/v1/delete_token', methods=['POST']) 159 | def delete_token(): 160 | appid = request.json['appid'] 161 | account = request.json['app_account'] 162 | DB_result = delete_tokens(account, appid) 163 | if DB_result == 'success': 164 | no_db_logger.info('token delete success') 165 | return json.dumps({'result_code':0,'error_msg':''}, ensure_ascii=False) 166 | else: 167 | no_db_logger.info('token delete fail') 168 | return json.dumps({'result_code':1,'error_msg':'token删除失败'}, ensure_ascii=False) 169 | 170 | @app.route('/api/v1/list_card', methods=['POST']) 171 | def list_card(): 172 | appid = request.json['appid'] 173 | account = request.json['app_account'] 174 | cards = list_cards(account, appid) 175 | message = dict(cards=cards) 176 | if isinstance(cards, list): 177 | no_db_logger.info('list cards success') 178 | return json.dumps({'result_code':0,'error_msg':'','data':message}, ensure_ascii=False) 179 | else: 180 | no_db_logger.info('list cards fail') 181 | return json.dumps({'result_code':1,'error_msg':'查询账户卡号失败'}, ensure_ascii=False) 182 | 183 | 184 | 185 | if __name__ == '__main__': 186 | app.run() 187 | -------------------------------------------------------------------------------- /app/myutility.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import hashlib,hmac 3 | import json 4 | import random 5 | import base64 6 | import urllib 7 | from urllib.parse import quote_plus 8 | 9 | def gen_signature(header, body, url, method, app_secret, accesstoken): 10 | if body: 11 | sign = dict(header, **body) 12 | else: 13 | sign = header 14 | 15 | dic = sorted(sign.items(), key = lambda d:d[0]) 16 | params = method + '&' + urllib.parse.quote_plus(url) 17 | 18 | for (key, value) in dic: 19 | params += '&' + key + '=' + urllib.parse.quote_plus(str(value)) 20 | signkey = app_secret + '&' + accesstoken 21 | h = base64.b64encode(hmac.new(signkey.encode('utf-8'), params.encode('utf-8'), hashlib.sha1).digest()) 22 | return h.decode('utf-8') 23 | 24 | -------------------------------------------------------------------------------- /app/script.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | ostr=`cat db.py | grep 'host' |awk -F "'" '{print $4}'` 4 | 5 | var=`cat /etc/hosts | grep 'futudb' | awk '{print $1}'` 6 | 7 | sed -i "s/${ostr}/${var}/g" db.py 8 | 9 | nginx; 10 | 11 | gunicorn mainapp:app -b 127.0.0.1:4000 -w 4 --log-level=debug 12 | -------------------------------------------------------------------------------- /demo.py: -------------------------------------------------------------------------------- 1 | import requests 2 | 3 | # ipport = '127.0.0.1:5000' 4 | ipport = '192.168.111.128:8888' 5 | 6 | # #美股现金 7 | # app_account = 'aa@bb.com' 8 | # card = '1001100200100059' 9 | # appid = '10000001' 10 | #rxu6CEYMSBrB6zSyOKjjk8j-17wRYw0qANky1xHuXPMpqUSVQaUotoBK1LV7OhMR 11 | 12 | #港股保证金账户 13 | app_account = 'aa@bb.com' 14 | card = '1001100100100059' 15 | appid = '10000001' 16 | # YHTNALMOm6IqkKsoOmxwLJ9O_LK8CGJE65rPNEbjA8HOMoAPdTsfk82HauR1Rl5s 17 | 18 | # #港股现金账户 19 | # app_account = 'aa@bb.com' 20 | # card = '1001100120012143' 21 | # appid = '10000001' 22 | 23 | # #保存accesstoken 24 | # r = requests.post( 25 | # "http://%s/ap1/v1/save_token" % ipport, 26 | # json={'app_account':app_account, 27 | # 'appid':appid, 28 | # 'market':'HK', 29 | # 'token':'YHTNALMOm6IqkKsoOmxwLJ9O_LK8CGJE65rPNEbjA8HOMoAPdTsfk82HauR1Rl5s', 30 | # 'card':card, 31 | # 'text':'港股保证金账户' 32 | # } 33 | # ) 34 | # print(r.text) 35 | 36 | # #获取交易密码 37 | # r = requests.post( 38 | # "http://%s/api/v1/tradetoken" % ipport, 39 | # json={ 40 | # 'app_account':app_account, 41 | # 'card':card, 42 | # 'appid':appid, 43 | # 'trade_pswd':'asdasd' 44 | # } 45 | # ) 46 | # print(r.text) 47 | 48 | # #删除token 49 | # r = requests.post( 50 | # "http://%s/api/v1/delete_token" % ipport, 51 | # json={'app_account':app_account, 52 | # 'appid':appid, 53 | # } 54 | # ) 55 | # print(r.text) 56 | 57 | #获取卡号 58 | r = requests.post( 59 | "http://%s/api/v1/list_card" % ipport, 60 | json={'app_account':app_account, 61 | 'appid':appid, 62 | } 63 | ) 64 | print(r.text) 65 | 66 | 67 | # #获取账户信息 68 | # r = requests.post( 69 | # "http://%s/api/v1/account" % ipport, 70 | # json={'app_account':app_account, 71 | # 'card':card, 72 | # 'appid':appid 73 | # } 74 | # ) 75 | # print(r.text) 76 | 77 | # #获取账户现金 78 | # r = requests.post( 79 | # "http://%s/api/v1/account/cash" % ipport, 80 | # json={ 81 | # 'app_account':app_account, 82 | # 'card':card, 83 | # 'appid':appid 84 | # } 85 | # ) 86 | # print(r.text) 87 | 88 | # #获取账户持仓 89 | # r = requests.post( 90 | # "http://%s/api/v1/account/portfolio" % ipport, 91 | # json={ 92 | # 'app_account':app_account, 93 | # 'card':card, 94 | # 'appid':appid 95 | # } 96 | # ) 97 | # print(r.text) 98 | 99 | 100 | # #获取订单列表 101 | # r = requests.post( 102 | # "http://%s/api/v1/get_list_orders" % ipport, 103 | # json={ 104 | # 'app_account':app_account, 105 | # 'card':card, 106 | # 'appid':appid, 107 | # 'date_begin':'', 108 | # 'date_end':'' 109 | # } 110 | # ) 111 | # print(r.text) 112 | 113 | # #获取交易列表 114 | # r = requests.post( 115 | # "http://%s/api/v1/get_list_trades" % ipport, 116 | # json={ 117 | # 'app_account':app_account, 118 | # 'card':card, 119 | # 'appid':appid 120 | # } 121 | # ) 122 | # print(r.text) 123 | 124 | # #美股限价下单 125 | # r = requests.post( 126 | # "http://%s/api/v1/place_order" % ipport, 127 | # json={ 128 | # 'app_account':app_account, 129 | # 'card':card, 130 | # 'appid':appid, 131 | # 'code':'BABA', 132 | # 'quantity':1000, 133 | # 'price':90, 134 | # 'side':'BUY', 135 | # 'type':'LIMIT' 136 | # } 137 | # ) 138 | # print(r.text) 139 | 140 | # #美股市价下单 141 | # r = requests.post( 142 | # "http://%s/api/v1/place_order" % ipport, 143 | # json={ 144 | # 'app_account':app_account, 145 | # 'card':card, 146 | # 'appid':appid, 147 | # 'code':'BABA', 148 | # 'quantity':500, 149 | # 'price':0, 150 | # 'side':'BUY', 151 | # 'type':'MARKET' 152 | # } 153 | # ) 154 | # print(r.text) 155 | 156 | # #港股下单 157 | # r = requests.post( 158 | # "http://%s/api/v1/place_order" % ipport, 159 | # json={ 160 | # 'app_account':app_account, 161 | # 'card':card, 162 | # 'appid':appid, 163 | # 'code':'90008', 164 | # 'quantity':100, 165 | # 'price':1.5, 166 | # 'side':'BUY', 167 | # 'type':'E' 168 | # } 169 | # ) 170 | # print(r.text) 171 | 172 | # #改单 173 | # r = requests.post( 174 | # "http://%s/api/v1/change_order" % ipport, 175 | # json={ 176 | # 'app_account':app_account, 177 | # 'card':card, 178 | # 'appid':appid, 179 | # 'order_id':'odr_us_sht_trd_svc_51_20160507_100059_1', 180 | # 'quantity':1000, 181 | # 'price':80 182 | # } 183 | # ) 184 | # print(r.text) 185 | 186 | # #撤单 187 | # r = requests.post( 188 | # "http://%s/api/v1/cancle_order" % ipport, 189 | # json={ 190 | # 'app_account':app_account, 191 | # 'card':card, 192 | # 'appid':appid, 193 | # 'order_id':'odr_us_sht_trd_svc_51_20160507_100059_6' 194 | # } 195 | # ) 196 | # print(r.text) 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | # import time 205 | # def test(second): 206 | # for x in range(1,5): 207 | # time.sleep(second) 208 | # r = requests.post( 209 | # "http://127.0.0.1:5000/api/v1/account/cash", 210 | # json={ 211 | # 'app_account':app_account, 212 | # 'card':card, 213 | # 'appid':appid 214 | # } 215 | # ) 216 | # print(r.text) 217 | 218 | # test(3) 219 | -------------------------------------------------------------------------------- /futu-openapi-api.md: -------------------------------------------------------------------------------- 1 | # 富途开放平台第三方接口(API)说明文档 2 | 3 | for 第三方开发者 4 | 5 | author: july 6 | 7 | 8 | - [Token API 令牌接口](#token) 9 | - [save_token 保存令牌](#save_token) 10 | - [delete_token 删除令牌](#delete_token) 11 | - [trade_token 交易令牌](#trade_token) 12 | - [list_card 查询账户卡号](#list_card) 13 | - [Accounts API 账户接口](#accounts_api) 14 | - [get_account_detail 获取账户详情](#get_account_detail) 15 | - [get_account_cash 获取账户现金数据](#get_account_cash) 16 | - [get_account_portfolio 获取账户持仓](#get_account_portfolio) 17 | - [get_list_orders 获取订单列表](#get_list_orders) 18 | - [get_list_trades 获取成交列表](#get_list_trades) 19 | - [Order API 交易接口](#order_api) 20 | - [place_order 下单](#place_order) 21 | - [change_order 修改订单](#change_order) 22 | - [cancle_order 撤单](#cancel_order) 23 | - [附录](#附录) 24 | - [接口中涉及的数据结构](#接口中涉及的数据结构) 25 | 26 | 27 | 28 | ## Token API 令牌接口 29 | ###save_token 30 | ####功能说明 31 | 将accesstoken保存到数据库,并与账户及卡号绑定 32 | ####URL 33 | http://127.0.0.1:8888/api/v1/save_token 34 | ####POST请求参数(JSON格式) 35 | | 参数 | 类型 | 描述 | 36 | | -------- | :-----: | :----: | 37 | | app_account | string | 第三方帐号 | 38 | | token | string | 获取的accesstoken | 39 | | card | string | 牛牛账户中相应的卡号,例如港股现金卡号,保证金卡号 | 40 | | text | string | 牛牛账户中卡号的描述 | 41 | | appid | string | 富途分配的第三方应用ID | 42 | | market | string | 所属市场。可能值:HK(港股市场),US(美股市场) | 43 | ####请求参数示例 44 | ```python 45 | { 46 | "app_account":"aa@bb.com", 47 | "card":"1001100200100059", 48 | "appid":"10000001", 49 | "market":"US", 50 | "token":"rxu6CEYMSBrB6zSyOKjjk8j-17wRYw0qANky1xHuXPMpqUSVQaUotoBK1LV7OhMR", 51 | "text":"美股现金账户" 52 | } 53 | ``` 54 | 55 | ####返回数据(JSON格式) 56 | 空 57 | ####返回数据示例 58 | 成功: 59 | ```python 60 | { 61 | "result_code":0, 62 | "error_msg":"" 63 | } 64 | ``` 65 | 失败: 66 | ```python 67 | { 68 | "result_code":1, 69 | "error_msg":"token保存失败" 70 | } 71 | ``` 72 | **备注:若未save_token而直接调用其他接口(除了delete_token),将返回如下信息** 73 | ```python 74 | { 75 | "result_code":2, 76 | "error_msg":"didn't get accesstoken" 77 | } 78 | ``` 79 | 80 | ###delete_token 81 | ####功能说明 82 | 从数据库中删除账户及关联的令牌 83 | ####URL 84 | http://127.0.0.1:8888/api/v1/delete_token 85 | ####POST请求参数(JSON格式) 86 | | 参数 | 类型 | 描述 | 87 | | -------- | :-----: | :----: | 88 | | app_account | string | 第三方帐号 | 89 | | appid | string | 富途分配的第三方应用ID | 90 | ####请求参数示例 91 | ```python 92 | { 93 | "app_account":"aa@bb.com", 94 | "appid":"10000001" 95 | } 96 | ``` 97 | 98 | ####返回数据(JSON格式) 99 | 空 100 | ####返回数据示例 101 | 成功: 102 | ```python 103 | { 104 | "result_code":0, 105 | "error_msg":"" 106 | } 107 | ``` 108 | 失败: 109 | ```python 110 | { 111 | "result_code":1, 112 | "error_msg":"token删除失败" 113 | } 114 | ``` 115 | 116 | ###trade_token 117 | ####功能说明 118 | 验证交易密码,获取tradetoken 119 | ####URL 120 | http://127.0.0.1:8888/api/v1/tradetoken 121 | ####POST请求参数(JSON格式) 122 | | 参数 | 类型 | 描述 | 123 | | -------- | :-----: | :----: | 124 | | app_account | string | 第三方帐号 | 125 | | card | string | 牛牛账户中相应的卡号,例如港股现金卡号,保证金卡号 | 126 | | appid | string | 富途分配的第三方应用ID | 127 | | trade_pswd | string | 交易密码 | 128 | ####请求参数示例 129 | ```python 130 | { 131 | "app_account":"aa@bb.com", 132 | "card":"1001100200100059", 133 | "appid":"10000001", 134 | "trade_pswd": "asdasd" 135 | } 136 | ``` 137 | ####返回数据(JSON格式) 138 | | 参数 | 类型 | 描述 | 139 | | -------- | :-----: | :----: | 140 | | trade_token | string| tradetoken | 141 | ####返回数据示例 142 | 成功: 143 | ```python 144 | { 145 | "result_code": 0, 146 | "error_msg": "", 147 | "data": { 148 | "trade_token": "Ij0UYMooWbBqvyNllTXAysfA1KOutFbzQLwCmUK2GiAaOUmlFWEH_Cg_uf7pHwhgOcf0-MLSurDZgoL4F73gxg==" 149 | } 150 | } 151 | ``` 152 | 失败: 153 | ```python 154 | { 155 | "result_code": 1102, 156 | "error_msg": "交易密码错误" 157 | } 158 | ``` 159 | **备注:若未获得tradetoken而直接调用3种交易接口,将返回如下信息** 160 | ```python 161 | { 162 | "result_code":2, 163 | "error_msg":"didn't get tradetoken" 164 | } 165 | ``` 166 | 167 | ###list_card 168 | ####功能说明 169 | 查询同一应用帐号对应的所有卡号,所属市场及其他描述 170 | ####URL 171 | http://127.0.0.1:8888/api/v1/list_card 172 | ####POST请求参数(JSON格式) 173 | | 参数 | 类型 | 描述 | 174 | | -------- | :-----: | :----: | 175 | | app_account | string | 第三方帐号 | 176 | | appid | string | 富途分配的第三方应用ID | 177 | ####请求参数示例 178 | ```python 179 | { 180 | "app_account":"aa@bb.com", 181 | "appid":"10000001" 182 | } 183 | ``` 184 | ####返回数据(JSON格式) 185 | | 参数 | 类型 | 描述 | 186 | | -------- | :-----: | :----: | 187 | | trade_token | CardInformation| 账户卡号描述,CardInformation数据类型见后面说明 | 188 | ####返回数据示例 189 | 成功: 190 | ```python 191 | { 192 | "result_code": 0, 193 | "error_msg": "", 194 | "data": { 195 | "cards": [ 196 | { 197 | "card":"1001100200100059", 198 | "card_info":"美股现金账户", 199 | "market":"US" 200 | }, 201 | { 202 | "card":"1001100100100059", 203 | "card_info":"港股保证金账户", 204 | "market":"HK" 205 | }, 206 | { 207 | "card":"1001100120012143", 208 | "card_info":"港股现金账户", 209 | "market":"HK" 210 | } 211 | ] 212 | } 213 | } 214 | ``` 215 | 失败: 216 | ```python 217 | { 218 | "result_code": 1, 219 | "error_msg": "查询账户卡号失败" 220 | } 221 | ``` 222 | 223 | 224 | ## Accounts API 账户接口 225 | 226 | ###账户接口调用流程及相关说明(注:以下示例中主机ip为127.0.0.1,端口号为YML配置的8888) 227 | ![Account_information_Sequence](https://raw.githubusercontent.com/zznn/zznn/master/%E6%9F%A5%E7%9C%8B%E4%BF%A1%E6%81%AF%E5%BA%8F%E5%88%97%E5%9B%BE.png) 228 | 229 | **首先,客户端须将已获取到的accesstoken通过save_token接口与account绑定**。 230 | 231 | 232 | ###get_account_detail 233 | ####功能说明 234 | 获取当前账户详情,如账户类型、状态、所属市场 235 | ####URL 236 | http://127.0.0.1:8888/api/v1/account 237 | ####POST请求参数(JSON格式) 238 | | 参数 | 类型 | 描述 | 239 | | -------- | :-----: | :----: | 240 | | app_account | string | 第三方帐号 | 241 | | card | string | 牛牛账户中相应的卡号,例如港股现金卡号,保证金卡号 | 242 | | appid | string | 富途分配的第三方应用ID | 243 | ####请求参数示例 244 | ```python 245 | { 246 | "app_account":"aa@bb.com", 247 | "card":"1001100200100059", 248 | "appid":"10000001" 249 | } 250 | ``` 251 | ####返回数据(JSON格式) 252 | | 参数 | 类型 | 描述 | 253 | | -------- | :-----: | :----: | 254 | | type | string | 账户类型。可能值: CASH(现金账户), MARGIN(保证金账户) | 255 | | state | string | 账户状态。可能值: OPENING(正在开户), OPENED(已开户), CLOSED(已销户) | 256 | | market | string | 所属市场。可能值:HK(港股市场),US(美股市场) | 257 | ####返回数据示例 258 | ```python 259 | { 260 | 'result_code': 0, 261 | 'error_msg': "", 262 | 'data': { 263 | 'account': { 264 | 'type': 'CASH', 265 | 'state': 'OPENED', 266 | 'market': 'HK' 267 | } 268 | } 269 | } 270 | ``` 271 | 272 | ###get_account_cash 273 | ####功能说明 274 | 获取当前账户现金数据 275 | ####URL 276 | http://127.0.0.1:8888/api/v1/account/cash 277 | ####POST请求参数(JSON格式) 278 | | 参数 | 类型 | 描述 | 279 | | -------- | :-----: | :----: | 280 | | app_account | string | 第三方帐号 | 281 | | card | string | 牛牛账户中相应的卡号,例如港股现金卡号,保证金卡号 | 282 | | appid | string | 富途分配的第三方应用ID | 283 | ####请求参数示例 284 | ```python 285 | { 286 | "app_account":"aa@bb.com", 287 | "card":"1001100200100059", 288 | "appid":"10000001" 289 | } 290 | ``` 291 | ####返回数据(JSON格式) 292 | | 参数 | 类型 | 描述 | 293 | | -------- | :-----: | :----: | 294 | | cash | CashPosition | 现金数据,CashPosition数据类型见后面说明 | 295 | ####返回数据示例 296 | ```python 297 | { 298 | 'result_code': 0, 299 | 'error_msg': '', 300 | 'data': { 301 | 'cash': { 302 | 'balance': '10030', 303 | 'debit_recover': '0', 304 | 'drawable': '0', 305 | 'frozen_power': '0', 306 | 'loan_max': '100000', 307 | 'power': '100000', 308 | 'prev_asset_value': '10030', 309 | 'prev_balance': '10030', 310 | 'prev_stock_value': '0', 311 | 'stock_margin_value': '153000', 312 | 'stock_value': '310200', 313 | 'today_profit': '0', 314 | 'today_profit_ratio': 0, 315 | 'today_settled': 0, 316 | 'today_turnover': '0', 317 | 'total_asset_value': '320230', 318 | 'trade_count': 0, 319 | 'type': 'MARGIN', 320 | } 321 | } 322 | } 323 | ``` 324 | 325 | ###get_account_portfolio 326 | ####功能说明 327 | 获取当前账户股票持仓数据 328 | ####URL 329 | http://127.0.0.1:8888/api/v1/account/portfolio 330 | ####POST请求参数(JSON格式) 331 | | 参数 | 类型 | 描述 | 332 | | -------- | :-----: | :----: | 333 | | app_account | string | 第三方帐号 | 334 | | card | string | 牛牛账户中相应的卡号,例如港股现金卡号,保证金卡号 | 335 | | appid | string | 富途分配的第三方应用ID | 336 | ####请求参数示例 337 | ```python 338 | { 339 | "app_account":"aa@bb.com", 340 | "card":"1001100200100059", 341 | "appid":"10000001" 342 | } 343 | ``` 344 | ####返回数据(JSON格式) 345 | | 参数 | 类型 | 描述 | 346 | | -------- | :-----: | :----: | 347 | | portfolio | StockPosition | 股票持仓数据,StockPosition数据类型见后面说明 | 348 | ####返回数据示例 349 | ```python 350 | { 351 | "result_code": 0, 352 | "error_msg": "", 353 | "data": { 354 | "portfolio": [ 355 | { 356 | "code": 90008, 357 | "name": "Futu&stock 8", 358 | "cost_price": "23", 359 | "cost_price_invalid": "", 360 | "power": 8000, 361 | "profit": "7600", 362 | "profit_ratio": 0.041304347826087, 363 | "profit_ratio_invalid": "", 364 | "quantity": 8000, 365 | "today_long_avg_price": "0", 366 | "today_long_shares": 0, 367 | "today_long_turnover": "0", 368 | "today_profit": "0", 369 | "today_short_avg_price": "0", 370 | "today_short_shares": 0, 371 | "today_short_turnover": "0", 372 | "today_turnover": "0", 373 | "value": "191600", 374 | "value_price": "23.95" 375 | }, 376 | { 377 | "code": 90009, 378 | "name": "Futu&stock 9", 379 | "cost_price": "23", 380 | "cost_price_invalid": "", 381 | "power": 8000, 382 | "profit": "7600", 383 | "profit_ratio": 0.041304347826087, 384 | "profit_ratio_invalid": "", 385 | "quantity": 1000, 386 | "today_long_avg_price": "0", 387 | "today_long_shares": 0, 388 | "today_long_turnover": "0", 389 | "today_profit": "0", 390 | "today_short_avg_price": "0", 391 | "today_short_shares": 0, 392 | "today_short_turnover": "0", 393 | "today_turnover": "0", 394 | "value": "41234", 395 | "value_price": "132.95" 396 | } 397 | ] 398 | } 399 | } 400 | ``` 401 | 402 | ###get_list_orders 403 | ####功能说明 404 | 获取当前用户当前账户订单数据 405 | ####URL 406 | http://127.0.0.1:8888/api/v1/get_list_orders 407 | ####POST请求参数(JSON格式) 408 | | 参数 | 类型 | 描述 | 必填 | 409 | | -------- | :-----: | :----: |:----: | 410 | | app_account | string | 第三方帐号 | 411 | | card | string | 牛牛账户中相应的卡号,例如港股现金卡号,保证金卡号 | 412 | | appid | string | 富途分配的第三方应用ID | 413 | |date_begin | string | 起始日期,如20151101,默认为当天日期; | 否 | 414 | |date_end | string | 结束日期,如20151105,默认为当天日期 | 否 | 415 | ####请求参数示例 416 | ```python 417 | { 418 | "app_account":"aa@bb.com", 419 | "card":"1001100200100059", 420 | "appid":"10000001", 421 | "date_begin":"", 422 | "date_end":"" 423 | } 424 | ``` 425 | ####返回数据(JSON格式) 426 | | 参数 | 类型 | 描述 | 427 | | -------- | :-----: | :----: | 428 | | order | Order | 订单列表,Order数据类型见后面说明 | 429 | ####返回数据示例 430 | ```python 431 | { 432 | "result_code": 0, 433 | "error_msg": "", 434 | "data": { 435 | "order": [ 436 | { 437 | "order_id": "1234561", 438 | "avg_price": "142.5", 439 | "code": "00700", 440 | "name": "腾讯", 441 | "created": 1446618508, 442 | "enable": 1, 443 | "last_err": 0, 444 | "matched_quantity": 0, 445 | "modified": 1446618536, 446 | "price": "142", 447 | "quantity": 1000, 448 | "side": "SELL", 449 | "state": 1, 450 | "type": "E", 451 | "last_err_text": "", 452 | "side_text": "卖", 453 | "type_text": "普通", 454 | "state_text": "等待成交" 455 | }, 456 | { 457 | "order_id": "1234562", 458 | "avg_price": "12.5", 459 | "code": "02208", 460 | "name": "金风科技", 461 | "created": 1446618608, 462 | "enable": 1, 463 | "last_err": 0, 464 | "matched_quantity": 0, 465 | "modified": 1446618636, 466 | "price": "13", 467 | "quantity": 1000, 468 | "side": "SELL", 469 | "state": 1, 470 | "type": "E", 471 | "last_err_text": "", 472 | "side_text": "买", 473 | "type_text": "普通", 474 | "state_text": "已成交" 475 | } 476 | ] 477 | } 478 | } 479 | ``` 480 | 481 | ###get_list_trades 482 | ####功能说明 483 | 获取账户今日成交列表,一个订单可能会对应多个成交。成交可能没有对应的订单,比如线下的成交 484 | ####URL 485 | http://127.0.0.1:8888/api/v1/get_list_trades 486 | ####POST请求参数(JSON格式) 487 | | 参数 | 类型 | 描述 | 488 | | -------- | :-----: | :----: |:----: | 489 | | app_account | string | 第三方帐号 | 490 | | card | string | 牛牛账户中相应的卡号,例如港股现金卡号,保证金卡号 | 491 | | appid | string | 富途分配的第三方应用ID | 492 | ####请求参数示例 493 | ```python 494 | { 495 | "app_account":"aa@bb.com", 496 | "card":"1001100200100059", 497 | "appid":"10000001", 498 | } 499 | ``` 500 | ####返回数据(JSON格式) 501 | | 参数 | 类型 | 描述 | 502 | | -------- | :-----: | :----: | 503 | | trade | Trade | 成交列表,Trade数据类型见后面说明 | 504 | ####返回数据示例 505 | ```python 506 | { 507 | "result_code": 0, 508 | "error_msg": "", 509 | "data": { 510 | "trade": [ 511 | { 512 | "code": 90008, 513 | "name": "Futu&stock 8", 514 | "counter_broker_id": 5001, 515 | "created": 1446620585, 516 | "order_created": 1446620585, 517 | "order_id": "23452345", 518 | "order_modified": 1446620585, 519 | "price": "30.5", 520 | "quantity": 200, 521 | "side": "SELL", 522 | "id": 16, 523 | "side_text": "卖" 524 | } 525 | ] 526 | } 527 | } 528 | ``` 529 | 530 | ## Order API 交易接口 531 | 532 | ###交易接口调用流程及相关说明 533 | ![Account_handle_Sequence](https://raw.githubusercontent.com/zznn/zznn/master/%E4%BA%A4%E6%98%93.png) 534 | 535 | **首先,客户端调用trade_token接口,验证客户交易密码,若正确则返回tradetoken并保存进数据库完成绑定,接着可调用相应的API完成下单,改单,撤单功能**。 536 | 537 | ###place_order 538 | ####功能说明 539 | 在当前账户下订单 540 | ####URL 541 | http://127.0.0.1:8888/api/v1/place_order 542 | ####POST请求参数(JSON格式) 543 | | 参数 | 类型 | 描述 | 备注 | 544 | | -------- | :-----: | :----: |:----: | 545 | | app_account | string | 第三方帐号 | 546 | | card | string | 牛牛账户中相应的卡号,例如港股现金卡号,保证金卡号 | 547 | | appid | string | 富途分配的第三方应用ID | 548 | | stockcode | string | 股票代码,如00700(港股账户),或BABA(美股账户) | 549 | | quantity | int | 数量,如1000 | 550 | | price | double | 价格,如150.5 | 若为美股MARKET市价单,请填0 | 551 | | side | string | 方向。BUY买入,SELL卖出 | 552 | |type | string | 订单类型。港股和美股不同。港股:E普通订单(增强限价单),A竞价单,I竞价限价单;美股:LIMIT限价单,MARKET市价单 | 553 | ####请求参数示例 554 | ```python 555 | { 556 | 'app_account':'aa@bb.com', 557 | 'card':'1001100200100059', 558 | "appid":"10000001", 559 | "code": "00700", 560 | "quantity": 1000, 561 | "price": 150.5, 562 | "side": "SELL", 563 | "type": "E" 564 | } 565 | ``` 566 | ####返回数据(JSON格式) 567 | | 参数 | 类型 | 描述 | 568 | | -------- | :-----: | :----: | 569 | | order_id | string| 订单ID | 570 | ####返回数据示例 571 | ```python 572 | { 573 | "result_code": 0, 574 | "error_msg": "", 575 | "data": { 576 | "order_id": "odr_us_sht_trd_svc_51_20160507_100059_6" 577 | } 578 | } 579 | ``` 580 | 581 | ###change_order 582 | ####功能说明 583 | 对还没成交的订单做修改,仅可修改订单数量和价格 584 | ####URL 585 | http://127.0.0.1:8888/api/v1/change_order 586 | ####POST请求参数(JSON格式) 587 | | 参数 | 类型 | 描述 | 588 | | -------- | :-----: | :----: |:----: | 589 | | app_account | string | 第三方帐号 | 590 | | card | string | 牛牛账户中相应的卡号,例如港股现金卡号,保证金卡号 | 591 | | appid | string | 富途分配的第三方应用ID | 592 | | order_id | string | 订单ID | 593 | | quantity | int | 数量 | 594 | | price | double | 价格 | 595 | ####请求参数示例 596 | ```python 597 | { 598 | "app_account":"aa@bb.com", 599 | "card":"1001100200100059", 600 | "appid":"10000001", 601 | "order_id": "odr_us_sht_trd_svc_51_20160507_100059_6", 602 | "quantity": 1000, 603 | "price": 160.5 604 | } 605 | ``` 606 | ####返回数据(JSON格式) 607 | 空 608 | ####返回数据示例 609 | 成功: 610 | ```python 611 | { 612 | "result_code": 0, 613 | "error_msg": "" 614 | } 615 | ``` 616 | 失败: 617 | ```python 618 | { 619 | "result_code": 100, 620 | "error_msg": "资金不足" 621 | } 622 | ``` 623 | 624 | ###cancle_order 625 | ####功能说明 626 | 对还没成交的订单撤单 627 | ####URL 628 | http://127.0.0.1:8888/api/v1/cancle_order 629 | ####POST请求参数(JSON格式) 630 | | 参数 | 类型 | 描述 | 631 | | -------- | :-----: | :----: |:----: | 632 | | app_account | string | 第三方帐号 | 633 | | card | string | 牛牛账户中相应的卡号,例如港股现金卡号,保证金卡号 | 634 | | appid | string | 富途分配的第三方应用ID | 635 | | order_id | string | 订单ID | 636 | ####请求参数示例 637 | ```python 638 | { 639 | "app_account":"aa@bb.com", 640 | "card":"1001100200100059", 641 | "appid":"10000001", 642 | "order_id": 'odr_us_sht_trd_svc_51_20160507_100059_6' 643 | } 644 | ``` 645 | ####返回数据(JSON格式) 646 | 空 647 | ####返回数据示例 648 | 成功: 649 | ```python 650 | { 651 | "result_code": 0, 652 | "error_msg": "" 653 | } 654 | ``` 655 | 失败: 656 | ```python 657 | { 658 | "result_code": 111, 659 | "error_msg": "非交易时间" 660 | } 661 | ``` 662 | 663 | ## 附录 664 | 665 | ### 接口中涉及的数据结构 666 | ##### 现金仓位 CashPosition 667 | 668 | 说明:表示客户资产的现金部分。以下金额单位都为0.001元,如10025000表示10025元 669 | 670 | 字段: 671 | 672 | | 名称 | 说明 | 673 | | ---- | ---- | 674 | | balance | 现金结余 | 675 | | debit_recover | 欠款 | 676 | | drawable | 可提金额(暂时不要用这个金额) | 677 | | loan_max | 可使用的最大信贷额度 | 678 | | power | 当前最大购买力 | 679 | | frozen_power | 已冻结购买力。由于下买单等暂时冻结的购买力 | 680 | | prev_asset_value | 上个交易日结算后的资产市值 | 681 | | prev_balance | 上个交易日结算后的现金结余 | 682 | | prev_stock_value | 上个交易日结算后的股票市值 | 683 | | stock_margin_value | 股票抵押额 | 684 | | stock_value | 股票市值 | 685 | | today_profit | 今日交易的盈亏额 | 686 | | today_profit_ratio | 今日交易的盈亏比例。0.1表示10% | 687 | | today_settled | 今天是否已经结算。0表示未结算,1表示已结算 | 688 | | today_turnover | 今日成交额 | 689 | | total_asset_value | 资产总额,含现金和股票市值 | 690 | | trade_count | 今日成交笔数 | 691 | 692 | 例如: 693 | 694 | { 695 | "balance": "10030", 696 | "debit_recover": "0", 697 | "drawable": "0", 698 | "frozen_power": "0", 699 | "loan_max": "100000", 700 | "power": "100000", 701 | "prev_asset_value": "10030", 702 | "prev_balance": "10030", 703 | "prev_stock_value": "0", 704 | "stock_margin_value": "153000", 705 | "stock_value": "310200", 706 | "today_profit": "0", 707 | "today_profit_ratio": 0, 708 | "today_settled": 0, 709 | "today_turnover": "0", 710 | "total_asset_value": "320230", 711 | "trade_count": 0 712 | } 713 | 714 | 715 | ##### 股票仓位 StockPosition 716 | 717 | 说明:表示客户资产的股票部分 718 | 719 | 字段: 720 | 721 | | 名称 | 说明 | 722 | | ---- | ---- | 723 | | code | 股票代码 | 724 | | name | 股票名称。使用了请求中指定的语言 | 725 | | cost_price | 成本价(以何种价格卖出才能使本次建仓不亏本) | 726 | | cost_price_invalid | 成本价非法。该字段不为空时表示成本价不可用 | 727 | | on_hold | 由于卖单而暂时冻结的可卖股数 | 728 | | power | 可卖股数 | 729 | | quantity | 持有股数 | 730 | | profit | 自建仓以来的总盈亏额 | 731 | | profit_ratio | 自建仓以来的总盈亏比例 | 732 | | profit_ratio_invalid | 总盈亏比例非法。该字段不为空时表示总盈亏额不可用 | 733 | | today_long_avg_price | 今日平均买入价 | 734 | | today_long_shares | 今日买入股数 | 735 | | today_long_turnover | 今日买入成交额 | 736 | | today_profit | 今日盈亏额。今日不管建仓清仓多少次,所有在这只股票上操作的盈亏额。 | 737 | | today_short_avg_price | 今日平均卖出价 | 738 | | today_short_shares | 今日卖出股数 | 739 | | today_short_turnover | 今日卖出成交额 | 740 | | today_turnover | 今日成交额 | 741 | | value | 当前市值 | 742 | | value_price | 用于计算市值的价格 | 743 | 744 | 例如: 745 | 746 | { 747 | "code": 90008, 748 | "name": "Futu&stock 8", 749 | "cost_price": "23", 750 | "cost_price_invalid": "", 751 | "power": 8000, 752 | "profit": "7600", 753 | "profit_ratio": 0.041304347826087, 754 | "profit_ratio_invalid": "", 755 | "quantity": 8000, 756 | "today_long_avg_price": "0", 757 | "today_long_shares": 0, 758 | "today_long_turnover": "0", 759 | "today_profit": "0", 760 | "today_short_avg_price": "0", 761 | "today_short_shares": 0, 762 | "today_short_turnover": "0", 763 | "today_turnover": "0", 764 | "value": "191600", 765 | "value_price": "23.95" 766 | } 767 | 768 | 769 | ##### 订单 Order 770 | 771 | 说明:表示一个订单 772 | 773 | 字段: 774 | 775 | | 名称 | 意义 | 776 | | ---- | ---- | 777 | | avg_price | 平均成交价 | 778 | | code | 股票代码 | 779 | | name | 股票名称。使用了请求中指定的语言 | 780 | | create_time | 创建时间(时间戳) | 781 | | update_time | 最近一次修改时间(时间戳) | 782 | | enable | 生效自段(暂不用管) | 783 | | last_err | 订单最近一次发生的错误码。0为没有错误。 具体的错误文本可以使用下面的last_err_text展示给客户 | 784 | | matched_quantity | 已成交股数 | 785 | | order_id | 订单号,可以唯一标记该用户的一个订单 | 786 | | price | 订单价格 | 787 | | quantity | 订单数量 | 788 | | side | 方向。字符串。BUY:买入, SELL:卖出。可以使用下面的side_text字段展示给客户。 | 789 | | state | 状态。整数。可能的取值有:
0正在提交,1正常,2已撤单,3已删除,4下单失败,5 等待开盘。
可以使用下面的state_text字段展示给客户。 | 790 | | type | 订单类型。字符串,必须是一个字符。 可能的取值如下:
E:增强限价单(Enhanced Limit),A:竞价单(Auction),I:竞价限价单(Auction Limit),L:限价单(Limit),S:特别限价单(Special Limit)。LIMIT:限价单,MARKET:市价单
对港股只有E\A\I三种订单允许客户输入,美股只有LIMIT和MARKET
可以使用下面的type_text字段展示给客户。| 791 | | last_err_text | 对应上面last_err字段的展示文本,文本使用的语言由请求参数决定 | 792 | | side_text | 对应上面side字段的展示文本,文本使用的语言由请求参数决定 | 793 | | type_text | 对应上面type字段的展示文本,文本使用的语言由请求参数决定 | 794 | | state_text | 对应上面state字段的展示文本,文本使用的语言由请求参数决定 | 795 | 796 | 例如: 797 | 798 | { 799 | "avg_price": "0", 800 | "code": 90003, 801 | "name": "Futu&stock 3", 802 | "create_time": 1446618508, 803 | "enable": 1, 804 | "last_err": 0, 805 | "matched_quantity": 0, 806 | "update_time": 1446618536, 807 | "order_id": "13253", 808 | "price": "10.5", 809 | "quantity": 1000, 810 | "side": "SELL", 811 | "state": 1, 812 | "type": "E", 813 | "last_err_text": "", 814 | "side_text": "卖", 815 | "type_text": "普通", 816 | "state_text": "等待成交" 817 | } 818 | 819 | ##### 成交 Trade 820 | 821 | 说明:表示一个成交。一个订单可能会对应多笔成交。 822 | 823 | 字段: 824 | 825 | | 名称 | 意义 | 826 | | ---- | ---- | 827 | | code | 股票代码 | 828 | | name | 股票名称。使用了请求中指定的语言 | 829 | | counter_broker_id | 成交对手经纪号 | 830 | | create_time | 创建时间(时间戳) | 831 | | order_created | 所属订单的创建时间(时间戳) | 832 | | order_id | 所属订单ID。有可能为0,表示该成交不属于任何一个订单。 | 833 | | order_modified | 所属订单的修改时间(时间戳) | 834 | | price | 成交价格 | 835 | | quantity | 成交数量 | 836 | | side | 方向。字符串。BUY:买入, SELL:卖出。可以使用下面的side_text字段展示给客户。 | 837 | | id | 成交ID,唯一标志了一笔成交 | 838 | | side_text | 对应上面side字段的展示文本,文本使用的语言由请求参数决定 | 839 | 840 | 例如: 841 | 842 | { 843 | "code": 90008, 844 | "name": "Futu&stock 8", 845 | "counter_broker_id": 5001, 846 | "create_time": 1446620585, 847 | "order_created": 1446620585, 848 | "order_id": "345673654", 849 | "order_modified": 1446620585, 850 | "price": "30.5", 851 | "quantity": 200, 852 | "side": "SELL", 853 | "id": 16, 854 | "side_text": "卖" 855 | } 856 | 857 | ##### 卡号 CardInformation 858 | 859 | 说明:表示一个账户对应的所有卡号。 860 | 861 | 字段: 862 | 863 | | 名称 | 意义 | 864 | | ---- | ---- | 865 | | card | 牛牛账户中相应的卡号,例如港股现金卡号,保证金卡号| 866 | | card_info | 牛牛账户中卡号的描述 | 867 | | market | 所属市场。可能值:HK(港股市场),US(美股市场) | 868 | 869 | 870 | 例如: 871 | 872 | { 873 | "card":"1001100200100059", 874 | "card_info":"美股现金账户", 875 | "market":"US" 876 | } 877 | 878 | -------------------------------------------------------------------------------- /futu-openapi-instructions.md: -------------------------------------------------------------------------------- 1 | 2 | # 富途开放平台第三方使用手册 3 | 4 | for 第三方开发者 5 | 6 | author: july 7 | 8 | 9 | 10 | - [Step1 下载源代码及数据库表](#app-mysql) 11 | - [Step2 配置自己的Appid](#appid-config) 12 | - [Step3 使用docker部署API server](#docker) 13 | - [服务器支持外部连接(个人主机)](#DaoCloud) 14 | - [服务器不支持外部连接](#Aliyun) 15 | - [参考API说明文档](#api) 16 | 17 | 18 | 19 | ## 下载源代码及数据库表 20 | ####下载app及mydata文件夹并放置在用户目录或具有执行权限的路径下,如/home/zhulei/app, /home/zhulei/mydata; 21 | 22 | ####APP包结构图 23 | - app/ 24 | - ├── CA 25 | - │   ├── client.cer 26 | - │   └── client.key 27 | - ├── conf 28 | - │   ├── appinfo.ini 29 | - │   └── log.ini 30 | - ├── db.py 31 | - ├── futu_server_api.py 32 | - ├── log 33 | - │   └── db.log 34 | - ├── mainapp.py 35 | - ├── myutility.py 36 | - ├── script.sh 37 | 38 | ####包文件说明 39 | 40 | - CA文件夹存放数字证书及密钥 41 | - conf文件夹存放配置文件 42 | - db.py数据库操作 43 | - futu_server_api.py封装富途开放接口 44 | - log文件夹存放服务日志 45 | - mainapp.py主程序 46 | - myutility工具类程序 47 | - script.sh程序启动脚本 48 | 49 | 50 | ## 配置自己的Appid 51 | ####首先请在CA文件夹中存放生成的证书及私钥,并在conf文件夹中按照如下说明配置appinfo.ini文件。 52 | ####appinfo.ini配置说明 53 | ####多个APP请按照如下格式配置在appinfo.ini文件中,请确保配置文件中的证书名与实际证书名一致: 54 | 55 | - [app_id]为富途分配的第三方应用ID 56 | - app_secret为富途分配的第三方签名密钥 57 | - client_cer为富途返回的证书 58 | - client_key为第三方自己生成的私钥 59 | 60 | ####例如 61 | - [1000001] 62 | - app_secret = !UMC+RztTD5De9ZV4sg6H6eUURJdyzlL 63 | - client_cer = ./CA/client.cer 64 | - client_key = ./CA/client.key 65 | - [XXXXXX] 66 | - app_secret = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 67 | - client_cer = XXXXXXXXXXXXXXXXXXXX 68 | - client_key = XXXXXXXXXXXXXXXXXXXX 69 | 70 | ## 使用docker部署API server 71 | ### 服务器支持外部连接(个人主机) 72 | ####首先注册DaoCloud并按下面的步骤(https://dashboard.daocloud.io/nodes/new)连接自己的主机; 73 | ####Step1 74 | ![](https://raw.githubusercontent.com/zznn/zhulei-github/master/step1.jpg) 75 | ####Step2 76 | ![](https://raw.githubusercontent.com/zznn/zhulei-github/master/step2.jpg) 77 | ####Step3 78 | ![](https://raw.githubusercontent.com/zznn/zhulei-github/master/step3.jpg) 79 | ####点击“应用联排”,创建一个新的stack,如图中所示,取名myapp,填写YML文件(说明如下),选择刚刚接入的主机,开始部署, 80 | ####Step4 81 | ![](https://raw.githubusercontent.com/zznn/zhulei-github/master/%E7%BB%98%E5%9B%BE1.jpg) 82 | ####YML文件说明 83 | 请按如下说明修改github示例中的YML文件(只需改动图中的三处): 84 | ![](https://raw.githubusercontent.com/zznn/zhulei-github/master/%E7%BB%98%E5%9B%BE2.jpg) 85 | 86 | ####耐心等待一会,见到如下图所示的“创建成功”即部署成功; 87 | ![](https://raw.githubusercontent.com/zznn/zhulei-github/master/mytu3.png) 88 | ### 服务器不支持外部连接 89 | ####Step1 根据主机系统安装Docker(自行参考Docker官方文档或此链接https://segmentfault.com/a/1190000002485231) 90 | 91 | ####Step2 登录阿里云获取Docker镜像(密码是futu@123456) 92 | sudo docker login --username=富途开放平台 registry.aliyuncs.com 93 | sudo docker pull registry.aliyuncs.com/futu_open/mysql 94 | sudo docker pull registry.aliyuncs.com/futu_open/flask 95 | 96 | ####Step3 运行Docker容器(请依照YML文件说明修改相关路径) 97 | sudo docker run -v /home/zhulei/mydata/:/var/lib/mysql --name mysql -e MYSQL_ROOT_PASSWORD=123456 -d registry.aliyuncs.com/futu_open/mysql 98 | sudo docker run -d --name web -v /home/zhulei/app/:/app -v /etc/localtime:/etc/localtime -p 8080:8080 --link mysql:futudb registry.aliyuncs.com/futu_open/flask ./script.sh 99 | 100 | 101 | ## 参考API说明文档 102 | ####按照接口说明文档调用相关API,若某个接口调用有问题,请将log文件夹中的日志文件发给富途开放助手。 103 | -------------------------------------------------------------------------------- /mydata/ib_logfile0: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/ib_logfile0 -------------------------------------------------------------------------------- /mydata/ibdata1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/ibdata1 -------------------------------------------------------------------------------- /mydata/mysql/columns_priv.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/columns_priv.MYD -------------------------------------------------------------------------------- /mydata/mysql/columns_priv.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/columns_priv.MYI -------------------------------------------------------------------------------- /mydata/mysql/columns_priv.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/columns_priv.frm -------------------------------------------------------------------------------- /mydata/mysql/db.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/db.MYD -------------------------------------------------------------------------------- /mydata/mysql/db.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/db.MYI -------------------------------------------------------------------------------- /mydata/mysql/db.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/db.frm -------------------------------------------------------------------------------- /mydata/mysql/event.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/event.MYD -------------------------------------------------------------------------------- /mydata/mysql/event.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/event.MYI -------------------------------------------------------------------------------- /mydata/mysql/event.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/event.frm -------------------------------------------------------------------------------- /mydata/mysql/func.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/func.MYD -------------------------------------------------------------------------------- /mydata/mysql/func.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/func.MYI -------------------------------------------------------------------------------- /mydata/mysql/func.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/func.frm -------------------------------------------------------------------------------- /mydata/mysql/general_log.CSM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/general_log.CSM -------------------------------------------------------------------------------- /mydata/mysql/general_log.CSV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/general_log.CSV -------------------------------------------------------------------------------- /mydata/mysql/general_log.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/general_log.frm -------------------------------------------------------------------------------- /mydata/mysql/help_category.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/help_category.MYD -------------------------------------------------------------------------------- /mydata/mysql/help_category.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/help_category.MYI -------------------------------------------------------------------------------- /mydata/mysql/help_category.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/help_category.frm -------------------------------------------------------------------------------- /mydata/mysql/help_keyword.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/help_keyword.MYD -------------------------------------------------------------------------------- /mydata/mysql/help_keyword.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/help_keyword.MYI -------------------------------------------------------------------------------- /mydata/mysql/help_keyword.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/help_keyword.frm -------------------------------------------------------------------------------- /mydata/mysql/help_relation.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/help_relation.MYD -------------------------------------------------------------------------------- /mydata/mysql/help_relation.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/help_relation.MYI -------------------------------------------------------------------------------- /mydata/mysql/help_relation.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/help_relation.frm -------------------------------------------------------------------------------- /mydata/mysql/help_topic.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/help_topic.MYD -------------------------------------------------------------------------------- /mydata/mysql/help_topic.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/help_topic.MYI -------------------------------------------------------------------------------- /mydata/mysql/help_topic.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/help_topic.frm -------------------------------------------------------------------------------- /mydata/mysql/host.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/host.MYD -------------------------------------------------------------------------------- /mydata/mysql/host.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/host.MYI -------------------------------------------------------------------------------- /mydata/mysql/host.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/host.frm -------------------------------------------------------------------------------- /mydata/mysql/ndb_binlog_index.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/ndb_binlog_index.MYD -------------------------------------------------------------------------------- /mydata/mysql/ndb_binlog_index.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/ndb_binlog_index.MYI -------------------------------------------------------------------------------- /mydata/mysql/ndb_binlog_index.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/ndb_binlog_index.frm -------------------------------------------------------------------------------- /mydata/mysql/plugin.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/plugin.MYD -------------------------------------------------------------------------------- /mydata/mysql/plugin.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/plugin.MYI -------------------------------------------------------------------------------- /mydata/mysql/plugin.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/plugin.frm -------------------------------------------------------------------------------- /mydata/mysql/proc.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/proc.MYD -------------------------------------------------------------------------------- /mydata/mysql/proc.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/proc.MYI -------------------------------------------------------------------------------- /mydata/mysql/proc.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/proc.frm -------------------------------------------------------------------------------- /mydata/mysql/procs_priv.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/procs_priv.MYD -------------------------------------------------------------------------------- /mydata/mysql/procs_priv.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/procs_priv.MYI -------------------------------------------------------------------------------- /mydata/mysql/procs_priv.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/procs_priv.frm -------------------------------------------------------------------------------- /mydata/mysql/proxies_priv.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/proxies_priv.MYD -------------------------------------------------------------------------------- /mydata/mysql/proxies_priv.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/proxies_priv.MYI -------------------------------------------------------------------------------- /mydata/mysql/proxies_priv.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/proxies_priv.frm -------------------------------------------------------------------------------- /mydata/mysql/servers.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/servers.MYD -------------------------------------------------------------------------------- /mydata/mysql/servers.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/servers.MYI -------------------------------------------------------------------------------- /mydata/mysql/servers.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/servers.frm -------------------------------------------------------------------------------- /mydata/mysql/slow_log.CSM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/slow_log.CSM -------------------------------------------------------------------------------- /mydata/mysql/slow_log.CSV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/slow_log.CSV -------------------------------------------------------------------------------- /mydata/mysql/slow_log.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/slow_log.frm -------------------------------------------------------------------------------- /mydata/mysql/tables_priv.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/tables_priv.MYD -------------------------------------------------------------------------------- /mydata/mysql/tables_priv.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/tables_priv.MYI -------------------------------------------------------------------------------- /mydata/mysql/tables_priv.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/tables_priv.frm -------------------------------------------------------------------------------- /mydata/mysql/time_zone.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone.MYD -------------------------------------------------------------------------------- /mydata/mysql/time_zone.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone.MYI -------------------------------------------------------------------------------- /mydata/mysql/time_zone.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone.frm -------------------------------------------------------------------------------- /mydata/mysql/time_zone_leap_second.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone_leap_second.MYD -------------------------------------------------------------------------------- /mydata/mysql/time_zone_leap_second.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone_leap_second.MYI -------------------------------------------------------------------------------- /mydata/mysql/time_zone_leap_second.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone_leap_second.frm -------------------------------------------------------------------------------- /mydata/mysql/time_zone_name.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone_name.MYD -------------------------------------------------------------------------------- /mydata/mysql/time_zone_name.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone_name.MYI -------------------------------------------------------------------------------- /mydata/mysql/time_zone_name.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone_name.frm -------------------------------------------------------------------------------- /mydata/mysql/time_zone_transition.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone_transition.MYD -------------------------------------------------------------------------------- /mydata/mysql/time_zone_transition.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone_transition.MYI -------------------------------------------------------------------------------- /mydata/mysql/time_zone_transition.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone_transition.frm -------------------------------------------------------------------------------- /mydata/mysql/time_zone_transition_type.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone_transition_type.MYD -------------------------------------------------------------------------------- /mydata/mysql/time_zone_transition_type.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone_transition_type.MYI -------------------------------------------------------------------------------- /mydata/mysql/time_zone_transition_type.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/time_zone_transition_type.frm -------------------------------------------------------------------------------- /mydata/mysql/user.MYD: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/user.MYD -------------------------------------------------------------------------------- /mydata/mysql/user.MYI: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/user.MYI -------------------------------------------------------------------------------- /mydata/mysql/user.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/mysql/user.frm -------------------------------------------------------------------------------- /mydata/performance_schema/cond_instances.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/cond_instances.frm -------------------------------------------------------------------------------- /mydata/performance_schema/db.opt: -------------------------------------------------------------------------------- 1 | default-character-set=utf8 2 | default-collation=utf8_general_ci 3 | -------------------------------------------------------------------------------- /mydata/performance_schema/events_waits_current.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/events_waits_current.frm -------------------------------------------------------------------------------- /mydata/performance_schema/events_waits_history.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/events_waits_history.frm -------------------------------------------------------------------------------- /mydata/performance_schema/events_waits_history_long.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/events_waits_history_long.frm -------------------------------------------------------------------------------- /mydata/performance_schema/events_waits_summary_by_instance.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/events_waits_summary_by_instance.frm -------------------------------------------------------------------------------- /mydata/performance_schema/events_waits_summary_by_thread_by_event_name.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/events_waits_summary_by_thread_by_event_name.frm -------------------------------------------------------------------------------- /mydata/performance_schema/events_waits_summary_global_by_event_name.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/events_waits_summary_global_by_event_name.frm -------------------------------------------------------------------------------- /mydata/performance_schema/file_instances.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/file_instances.frm -------------------------------------------------------------------------------- /mydata/performance_schema/file_summary_by_event_name.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/file_summary_by_event_name.frm -------------------------------------------------------------------------------- /mydata/performance_schema/file_summary_by_instance.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/file_summary_by_instance.frm -------------------------------------------------------------------------------- /mydata/performance_schema/mutex_instances.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/mutex_instances.frm -------------------------------------------------------------------------------- /mydata/performance_schema/performance_timers.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/performance_timers.frm -------------------------------------------------------------------------------- /mydata/performance_schema/rwlock_instances.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/rwlock_instances.frm -------------------------------------------------------------------------------- /mydata/performance_schema/setup_consumers.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/setup_consumers.frm -------------------------------------------------------------------------------- /mydata/performance_schema/setup_instruments.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/setup_instruments.frm -------------------------------------------------------------------------------- /mydata/performance_schema/setup_timers.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/setup_timers.frm -------------------------------------------------------------------------------- /mydata/performance_schema/threads.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/performance_schema/threads.frm -------------------------------------------------------------------------------- /mydata/test/account_token.frm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zznn/futu-openAPI/93046d44a1ba9823440210703566f1b99988ad02/mydata/test/account_token.frm -------------------------------------------------------------------------------- /mydata/test/db.opt: -------------------------------------------------------------------------------- 1 | default-character-set=latin1 2 | default-collation=latin1_swedish_ci 3 | --------------------------------------------------------------------------------