├── 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 | 
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 | 
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 | 
75 | ####Step2
76 | 
77 | ####Step3
78 | 
79 | ####点击“应用联排”,创建一个新的stack,如图中所示,取名myapp,填写YML文件(说明如下),选择刚刚接入的主机,开始部署,
80 | ####Step4
81 | 
82 | ####YML文件说明
83 | 请按如下说明修改github示例中的YML文件(只需改动图中的三处):
84 | 
85 |
86 | ####耐心等待一会,见到如下图所示的“创建成功”即部署成功;
87 | 
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 |
--------------------------------------------------------------------------------