cfquant 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. LTtx/__init__.py +2 -0
  2. LTtx/tx/Config.txt +8 -0
  3. LTtx/tx/LTtx_server.py +1177 -0
  4. LTtx/tx/__init__.py +5 -0
  5. LTtx/tx/tx.py +1935 -0
  6. cfquant/__init__.py +26 -0
  7. cfquant/account_routing.py +119 -0
  8. cfquant/channels.py +76 -0
  9. cfquant/cli.py +266 -0
  10. cfquant/client.py +365 -0
  11. cfquant/config.py +86 -0
  12. cfquant/hub.py +304 -0
  13. cfquant/logging_i18n.py +348 -0
  14. cfquant/normal_bridge.py +676 -0
  15. cfquant/pipe_bridge.py +249 -0
  16. cfquant/pipe_client.py +223 -0
  17. cfquant/pipe_hub.py +602 -0
  18. cfquant/pipe_transport.py +493 -0
  19. cfquant/protocol.py +238 -0
  20. cfquant/qmt_bridge.py +1081 -0
  21. cfquant/runtime_report.py +334 -0
  22. cfquant/tx.py +1898 -0
  23. cfquant/tx_trade_bridge.py +1905 -0
  24. cfquant/version.py +5 -0
  25. cfquant/xtconstant.py +262 -0
  26. cfquant/xtdata.py +462 -0
  27. cfquant/xttrader.py +955 -0
  28. cfquant/xttype.py +586 -0
  29. cfquant-0.2.0.dist-info/LICENSE +21 -0
  30. cfquant-0.2.0.dist-info/METADATA +144 -0
  31. cfquant-0.2.0.dist-info/RECORD +90 -0
  32. cfquant-0.2.0.dist-info/WHEEL +5 -0
  33. cfquant-0.2.0.dist-info/entry_points.txt +4 -0
  34. cfquant-0.2.0.dist-info/top_level.txt +6 -0
  35. cfquant_pipe_hub.py +45 -0
  36. cfquant_web_server.py +12137 -0
  37. qmt_scripts/CFQUANT.py +507 -0
  38. qmt_scripts/CFQUANT_CTYPE_ALL_LOWLAT.py +830 -0
  39. qmt_scripts/CFQUANT_LITE.py +4928 -0
  40. qmt_scripts/CFQUANT_TRADE_LOWLAT.py +382 -0
  41. qmt_scripts/__init__.py +1 -0
  42. qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_CTYPE_ALL_LOWLAT_SH.py +866 -0
  43. qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_CTYPE_ALL_LOWLAT_SZ.py +866 -0
  44. qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_LITE_SH.py +5020 -0
  45. qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_LITE_SZ.py +5020 -0
  46. qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_TRADE_LOWLAT_SH.py +436 -0
  47. qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/CFQUANT_TRADE_LOWLAT_SZ.py +436 -0
  48. qmt_scripts//321/205/320/240/320/234/321/210/342/224/244/320/266/321/205/320/237/342/225/226/321/207/320/233/320/274/321/207/320/273/320/233/321/205/342/225/225/320/222/321/205/320/254/342/225/221/readme.md +95 -0
  49. web_dashboard/__init__.py +1 -0
  50. web_dashboard/app.js +9847 -0
  51. web_dashboard/avatars/amber-pulse.svg +15 -0
  52. web_dashboard/avatars/copper-grid.svg +15 -0
  53. web_dashboard/avatars/market-blue.svg +15 -0
  54. web_dashboard/avatars/rose-circuit.svg +15 -0
  55. web_dashboard/avatars/signal-green.svg +15 -0
  56. web_dashboard/avatars/slate-wave.svg +15 -0
  57. web_dashboard/avatars/teal-orbit.svg +16 -0
  58. web_dashboard/avatars/violet-node.svg +15 -0
  59. web_dashboard/favicon.svg +5 -0
  60. web_dashboard/image/qmt_deploy/image-10.png +0 -0
  61. web_dashboard/image/qmt_deploy/image-11.png +0 -0
  62. web_dashboard/image/qmt_deploy/image-12.png +0 -0
  63. web_dashboard/image/qmt_deploy/image-13.png +0 -0
  64. web_dashboard/image/qmt_deploy/image-14.png +0 -0
  65. web_dashboard/image/qmt_deploy/image-15.png +0 -0
  66. web_dashboard/image/qmt_deploy/image-16.png +0 -0
  67. web_dashboard/image/qmt_deploy/image-17.png +0 -0
  68. web_dashboard/image/qmt_deploy/image-18.png +0 -0
  69. web_dashboard/image/qmt_deploy/image-19.png +0 -0
  70. web_dashboard/image/qmt_deploy/image-20.png +0 -0
  71. web_dashboard/image/qmt_deploy/image-21.png +0 -0
  72. web_dashboard/image/qmt_deploy/image-4.png +0 -0
  73. web_dashboard/image/qmt_deploy/image-5.png +0 -0
  74. web_dashboard/image/qmt_deploy/image-6.png +0 -0
  75. web_dashboard/image/qmt_deploy/image-7.png +0 -0
  76. web_dashboard/image/qmt_deploy/image-8.png +0 -0
  77. web_dashboard/image/qmt_deploy/image-9.png +0 -0
  78. web_dashboard/image//321/211/320/220/320/252/321/207/320/244/320/270/321/206/320/270/320/261/321/205/342/225/235/320/237/321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/image-1.png +0 -0
  79. web_dashboard/image//321/211/320/220/320/252/321/207/320/244/320/270/321/206/320/270/320/261/321/205/342/225/235/320/237/321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/image-2.png +0 -0
  80. web_dashboard/image//321/211/320/220/320/252/321/207/320/244/320/270/321/206/320/270/320/261/321/205/342/225/235/320/237/321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/image-3.png +0 -0
  81. web_dashboard/image//321/211/320/220/320/252/321/207/320/244/320/270/321/206/320/270/320/261/321/205/342/225/235/320/237/321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/image.png +0 -0
  82. web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783479325179.png +0 -0
  83. web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783479745262.png +0 -0
  84. web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783480178700.png +0 -0
  85. web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783480428759.png +0 -0
  86. web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783489807217.png +0 -0
  87. web_dashboard/image//321/211/320/223/320/270/321/207/342/225/234/342/226/223/321/206/320/234/320/227/321/205/320/235/320/247/1783490503491.png +0 -0
  88. web_dashboard/index.html +2317 -0
  89. web_dashboard/styles.css +7817 -0
  90. web_dashboard/vendor/mermaid.min.js +2029 -0
cfquant/xtdata.py ADDED
@@ -0,0 +1,462 @@
1
+ # -*- coding: utf-8 -*-
2
+ import time
3
+
4
+ from .client import configure, get_client
5
+
6
+
7
+ _subscription_callbacks = {}
8
+
9
+
10
+ def get_market_data(
11
+ field_list=[],
12
+ stock_list=[],
13
+ period="1d",
14
+ start_time="",
15
+ end_time="",
16
+ count=-1,
17
+ dividend_type="none",
18
+ fill_data=True,
19
+ ):
20
+ return get_client().request("xtdata.get_market_data", {
21
+ "field_list": field_list,
22
+ "stock_list": stock_list,
23
+ "period": period,
24
+ "start_time": start_time,
25
+ "end_time": end_time,
26
+ "count": count,
27
+ "dividend_type": dividend_type,
28
+ "fill_data": fill_data,
29
+ })
30
+
31
+
32
+ def get_market_data_ex(
33
+ field_list=[],
34
+ stock_list=[],
35
+ period="1d",
36
+ start_time="",
37
+ end_time="",
38
+ count=-1,
39
+ dividend_type="none",
40
+ fill_data=True,
41
+ ):
42
+ return get_client().request("xtdata.get_market_data_ex", {
43
+ "field_list": field_list,
44
+ "stock_list": stock_list,
45
+ "period": period,
46
+ "start_time": start_time,
47
+ "end_time": end_time,
48
+ "count": count,
49
+ "dividend_type": dividend_type,
50
+ "fill_data": fill_data,
51
+ })
52
+
53
+
54
+ def get_full_tick(code_list):
55
+ return get_client().request("xtdata.get_full_tick", {
56
+ "code_list": code_list,
57
+ })
58
+
59
+
60
+ def get_local_data(
61
+ field_list=[],
62
+ stock_list=[],
63
+ period="1d",
64
+ start_time="",
65
+ end_time="",
66
+ count=-1,
67
+ dividend_type="none",
68
+ fill_data=True,
69
+ data_dir=None,
70
+ stock_code="",
71
+ divid_type=None,
72
+ ):
73
+ return get_client().request("xtdata.get_local_data", {
74
+ "field_list": field_list,
75
+ "stock_list": stock_list,
76
+ "stock_code": stock_code,
77
+ "period": period,
78
+ "start_time": start_time,
79
+ "end_time": end_time,
80
+ "count": count,
81
+ "dividend_type": dividend_type,
82
+ "divid_type": divid_type if divid_type is not None else dividend_type,
83
+ "fill_data": fill_data,
84
+ "data_dir": data_dir,
85
+ })
86
+
87
+
88
+ def subscribe_quote(stock_code, period="1d", start_time="", end_time="", count=0, callback=None):
89
+ result = get_client().request("xtdata.subscribe_quote", {
90
+ "stock_code": stock_code,
91
+ "period": period,
92
+ "start_time": start_time,
93
+ "end_time": end_time,
94
+ "count": count,
95
+ })
96
+ subscribe_id = result.get("subscribe_id") if isinstance(result, dict) else result
97
+ if callback and subscribe_id is not None:
98
+ event_name = "quote:%s" % subscribe_id
99
+ _subscription_callbacks[subscribe_id] = (event_name, callback)
100
+ get_client().add_callback(event_name, callback)
101
+ return subscribe_id
102
+
103
+
104
+ def subscribe_whole_quote(code_list, callback=None):
105
+ result = get_client().request("xtdata.subscribe_whole_quote", {
106
+ "code_list": code_list,
107
+ })
108
+ subscribe_id = result.get("subscribe_id") if isinstance(result, dict) else result
109
+ if callback and subscribe_id is not None:
110
+ event_name = "quote:%s" % subscribe_id
111
+ _subscription_callbacks[subscribe_id] = (event_name, callback)
112
+ get_client().add_callback(event_name, callback)
113
+ return subscribe_id
114
+
115
+
116
+ def subscribe_quote2(stock_code, period="1d", start_time="", end_time="", count=0, dividend_type=None, callback=None):
117
+ result = get_client().request("xtdata.subscribe_quote", {
118
+ "stock_code": stock_code,
119
+ "period": period,
120
+ "start_time": start_time,
121
+ "end_time": end_time,
122
+ "count": count,
123
+ "dividend_type": dividend_type,
124
+ })
125
+ subscribe_id = result.get("subscribe_id") if isinstance(result, dict) else result
126
+ if callback and subscribe_id is not None:
127
+ event_name = "quote:%s" % subscribe_id
128
+ _subscription_callbacks[subscribe_id] = (event_name, callback)
129
+ get_client().add_callback(event_name, callback)
130
+ return subscribe_id
131
+
132
+
133
+ def unsubscribe_quote(seq):
134
+ item = _subscription_callbacks.pop(seq, None)
135
+ if item:
136
+ event_name, callback = item
137
+ get_client().remove_callback(event_name, callback)
138
+ return get_client().request("xtdata.unsubscribe_quote", {
139
+ "subscribe_id": seq,
140
+ })
141
+
142
+
143
+ def download_history_data(stock_code, period, start_time="", end_time="", incrementally=None, callback=None):
144
+ if callback:
145
+ return download_history_data2([stock_code], period, start_time, end_time, callback=callback, incrementally=incrementally)
146
+ return get_client().request("xtdata.download_history_data", {
147
+ "stock_code": stock_code,
148
+ "period": period,
149
+ "start_time": start_time,
150
+ "end_time": end_time,
151
+ "incrementally": incrementally,
152
+ })
153
+
154
+
155
+ def download_history_data2(
156
+ stock_list,
157
+ period,
158
+ start_time="",
159
+ end_time="",
160
+ callback=None,
161
+ incrementally=None,
162
+ job_id=None,
163
+ keep_callback=False,
164
+ ):
165
+ event_name = None
166
+ if callback:
167
+ event_name = "download_history:%s:%s" % (period, int(time.time() * 1000))
168
+ get_client().add_callback(event_name, callback)
169
+ try:
170
+ return get_client().request("xtdata.download_history_data2", {
171
+ "stock_list": stock_list,
172
+ "period": period,
173
+ "start_time": start_time,
174
+ "end_time": end_time,
175
+ "incrementally": incrementally,
176
+ "callback_event": event_name,
177
+ "download_job_id": job_id,
178
+ "download_emit_lifecycle": bool(event_name),
179
+ })
180
+ finally:
181
+ if event_name and callback and not keep_callback:
182
+ get_client().remove_callback(event_name, callback)
183
+
184
+
185
+ def get_instrument_detail(stock_code, iscomplete=False):
186
+ return get_client().request("xtdata.get_instrument_detail", {
187
+ "stock_code": stock_code,
188
+ "iscomplete": iscomplete,
189
+ })
190
+
191
+
192
+ def get_stock_list_in_sector(sector_name):
193
+ return get_client().request("xtdata.get_stock_list_in_sector", {
194
+ "sector_name": sector_name,
195
+ })
196
+
197
+
198
+ def get_financial_data(field_list, stock_list, start_time="", end_time="", report_type="announce_time"):
199
+ return get_client().request("xtdata.get_financial_data", {
200
+ "field_list": field_list,
201
+ "stock_list": stock_list,
202
+ "start_time": start_time,
203
+ "end_time": end_time,
204
+ "report_type": report_type,
205
+ })
206
+
207
+
208
+ def get_financial_data_ori(field_list, stock_list, start_time="", end_time="", report_type="announce_time"):
209
+ return get_client().request("xtdata.get_financial_data_ori", {
210
+ "field_list": field_list,
211
+ "stock_list": stock_list,
212
+ "start_time": start_time,
213
+ "end_time": end_time,
214
+ "report_type": report_type,
215
+ })
216
+
217
+
218
+ def get_raw_financial_data(field_list, stock_list, start_time="", end_time="", report_type="announce_time"):
219
+ return get_financial_data_ori(field_list, stock_list, start_time, end_time, report_type)
220
+
221
+
222
+ def download_financial_data(stock_list, table_list=None, start_time="", end_time="", callback=None, job_id=None, keep_callback=False):
223
+ event_name = None
224
+ if callback:
225
+ event_name = "download_financial:%s" % int(time.time() * 1000)
226
+ get_client().add_callback(event_name, callback)
227
+ try:
228
+ return get_client().request("xtdata.download_financial_data", {
229
+ "stock_list": stock_list,
230
+ "table_list": table_list or [],
231
+ "start_time": start_time,
232
+ "end_time": end_time,
233
+ "callback_event": event_name,
234
+ "download_job_id": job_id,
235
+ "download_emit_lifecycle": bool(event_name),
236
+ })
237
+ finally:
238
+ if event_name and callback and not keep_callback:
239
+ get_client().remove_callback(event_name, callback)
240
+
241
+
242
+ def download_financial_data2(stock_list, table_list=None, start_time="", end_time="", callback=None, job_id=None, keep_callback=False):
243
+ return download_financial_data(stock_list, table_list, start_time, end_time, callback, job_id, keep_callback)
244
+
245
+
246
+ def get_trading_dates(stockcode, start_date="", end_date="", count=-1, period="1d"):
247
+ return get_client().request("xtdata.get_trading_dates", {
248
+ "stockcode": stockcode,
249
+ "start_date": start_date,
250
+ "end_date": end_date,
251
+ "count": count,
252
+ "period": period,
253
+ })
254
+
255
+
256
+ def is_stock(stock_code):
257
+ return _stock_basic_request("is_stock", stock_code)
258
+
259
+
260
+ def is_fund(stock_code):
261
+ return _stock_basic_request("is_fund", stock_code)
262
+
263
+
264
+ def is_future(stock_code):
265
+ return _stock_basic_request("is_future", stock_code)
266
+
267
+
268
+ def get_stock_type(stock_code):
269
+ return _stock_basic_request("get_stock_type", stock_code)
270
+
271
+
272
+ def get_stock_name(stock_code):
273
+ return _stock_basic_request("get_stock_name", stock_code)
274
+
275
+
276
+ def get_open_date(stock_code):
277
+ return _stock_basic_request("get_open_date", stock_code)
278
+
279
+
280
+ def get_contract_expire_date(stock_code):
281
+ return _stock_basic_request("get_contract_expire_date", stock_code)
282
+
283
+
284
+ def get_contract_multiplier(stock_code):
285
+ return _stock_basic_request("get_contract_multiplier", stock_code)
286
+
287
+
288
+ def get_weight_in_index(mtkindexcode, stockcode):
289
+ return get_client().request("xtdata.get_weight_in_index", {
290
+ "mtkindexcode": mtkindexcode,
291
+ "stockcode": stockcode,
292
+ })
293
+
294
+
295
+ def get_turnover_rate(stock_code, start_time="", end_time=""):
296
+ return get_client().request("xtdata.get_turnover_rate", {
297
+ "stock_code": stock_code,
298
+ "start_time": start_time,
299
+ "end_time": end_time,
300
+ })
301
+
302
+
303
+ def get_ETF_list(market="", stockcode="", typeList=None):
304
+ return get_client().request("xtdata.get_ETF_list", {
305
+ "market": market,
306
+ "stockcode": stockcode,
307
+ "typeList": typeList or [],
308
+ })
309
+
310
+
311
+ def get_etf_list(market="", stockcode="", type_list=None):
312
+ return get_ETF_list(market, stockcode, type_list)
313
+
314
+
315
+ def get_option_detail_data(stockcode):
316
+ return get_client().request("xtdata.get_option_detail_data", {
317
+ "stockcode": stockcode,
318
+ })
319
+
320
+
321
+ def get_option_list(object, dedate, opttype="", isavailavle=False):
322
+ return get_client().request("xtdata.get_option_list", {
323
+ "object": object,
324
+ "dedate": dedate,
325
+ "opttype": opttype,
326
+ "isavailavle": isavailavle,
327
+ })
328
+
329
+
330
+ def get_option_undl(opt_code):
331
+ return get_client().request("xtdata.get_option_undl", {
332
+ "opt_code": opt_code,
333
+ })
334
+
335
+
336
+ def get_option_undl_data(undl_code_ref=""):
337
+ return get_client().request("xtdata.get_option_undl_data", {
338
+ "undl_code_ref": undl_code_ref,
339
+ })
340
+
341
+
342
+ def get_his_st_data(stockCode):
343
+ return get_client().request("xtdata.get_his_st_data", {
344
+ "stockCode": stockCode,
345
+ })
346
+
347
+
348
+ def get_his_index_data(stockCode):
349
+ return get_client().request("xtdata.get_his_index_data", {
350
+ "stockCode": stockCode,
351
+ })
352
+
353
+
354
+ def get_factor_data(field_list, stock_list, start_date="", end_date=""):
355
+ return get_client().request("xtdata.get_factor_data", {
356
+ "field_list": field_list,
357
+ "stock_list": stock_list,
358
+ "start_date": start_date,
359
+ "end_date": end_date,
360
+ })
361
+
362
+
363
+ def _callback_placeholder():
364
+ return {"__cfquant_callback_arg__": True}
365
+
366
+
367
+ def _generic_xtdata_request(action, *args, **kwargs):
368
+ timeout = kwargs.pop("timeout", None)
369
+ keep_callback = bool(kwargs.pop("keep_callback", str(action).startswith("subscribe_")))
370
+ callback_name = str(kwargs.pop("callback_name", "callback") or "callback")
371
+ callback = kwargs.pop(callback_name, None)
372
+ callback_positions = []
373
+ wire_args = []
374
+ for index, value in enumerate(args):
375
+ if callable(value):
376
+ if callback is not None:
377
+ raise TypeError("only one callback can be passed to xtdata.%s" % action)
378
+ callback = value
379
+ callback_positions.append(index)
380
+ wire_args.append(_callback_placeholder())
381
+ else:
382
+ wire_args.append(value)
383
+ event_name = None
384
+ if callback is not None:
385
+ if not callable(callback):
386
+ raise TypeError("callback must be callable")
387
+ event_name = "xtdata:%s:%s" % (action, int(time.time() * 1000))
388
+ get_client().add_callback(event_name, callback)
389
+ try:
390
+ return get_client().request("xtdata.%s" % action, {
391
+ "args": wire_args,
392
+ "kwargs": kwargs,
393
+ "callback_event": event_name,
394
+ "callback_positions": callback_positions,
395
+ "callback_name": callback_name,
396
+ }, timeout=timeout)
397
+ finally:
398
+ if event_name and callback and not keep_callback:
399
+ get_client().remove_callback(event_name, callback)
400
+
401
+
402
+ def _make_generic_xtdata_func(action):
403
+ def func(*args, **kwargs):
404
+ return _generic_xtdata_request(action, *args, **kwargs)
405
+ func.__name__ = action
406
+ func.__qualname__ = action
407
+ func.__doc__ = (
408
+ "Conditional xtdata compatibility wrapper. "
409
+ "It forwards to the same-named QMT callable when the running QMT environment exposes it."
410
+ )
411
+ return func
412
+
413
+
414
+ _CONDITIONAL_XTDATA_METHODS = [
415
+ "get_trading_calendar",
416
+ "get_trading_period",
417
+ "get_kline_trading_period",
418
+ "get_all_trading_periods",
419
+ "get_period_list",
420
+ "create_sector",
421
+ "add_sector",
422
+ "remove_sector",
423
+ "reset_sector",
424
+ "remove_stock_from_sector",
425
+ "create_formula",
426
+ "call_formula",
427
+ "subscribe_formula",
428
+ "unsubscribe_formula",
429
+ "get_formula_result",
430
+ "get_l2_quote",
431
+ "get_l2_order",
432
+ "get_l2_transaction",
433
+ "subscribe_l2thousand",
434
+ "get_l2thousand_queue",
435
+ "get_tabular_data",
436
+ "download_tabular_data",
437
+ "push_custom_data",
438
+ "download_sector_data",
439
+ "download_index_weight",
440
+ "download_history_contracts",
441
+ "download_holiday_data",
442
+ "download_etf_info",
443
+ "download_cb_data",
444
+ "download_his_st_data",
445
+ "download_metatable_data",
446
+ ]
447
+
448
+ for _method in _CONDITIONAL_XTDATA_METHODS:
449
+ globals()[_method] = _make_generic_xtdata_func(_method)
450
+ del _method
451
+
452
+
453
+ def _stock_basic_request(action, stock_code):
454
+ return get_client().request("xtdata.%s" % action, {
455
+ "stock_code": stock_code,
456
+ })
457
+
458
+
459
+ def run():
460
+ get_client().start()
461
+ while True:
462
+ time.sleep(1)