hikyuu 2.7.0__py3-none-manylinux2014_aarch64.whl → 2.7.3__py3-none-manylinux2014_aarch64.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.
- hikyuu/__init__.py +25 -7
- hikyuu/__init__.pyi +23 -12
- hikyuu/analysis/__init__.pyi +6 -1
- hikyuu/analysis/analysis.pyi +7 -2
- hikyuu/core.pyi +8 -3
- hikyuu/cpp/core310.pyi +94 -24
- hikyuu/cpp/core310.so +0 -0
- hikyuu/cpp/core311.pyi +94 -24
- hikyuu/cpp/core311.so +0 -0
- hikyuu/cpp/core312.pyi +94 -24
- hikyuu/cpp/core312.so +0 -0
- hikyuu/cpp/core313.pyi +94 -24
- hikyuu/cpp/core313.so +0 -0
- hikyuu/cpp/i18n/zh_CN/hikyuu.mo +0 -0
- hikyuu/cpp/i18n/zh_CN/hikyuu_plugin.mo +0 -0
- hikyuu/cpp/libboost_atomic.so +0 -0
- hikyuu/cpp/libboost_atomic.so.1.90.0 +0 -0
- hikyuu/cpp/{libboost_charconv-mt.so → libboost_charconv.so} +0 -0
- hikyuu/cpp/{libboost_charconv-mt.so.1.88.0 → libboost_charconv.so.1.90.0} +0 -0
- hikyuu/cpp/libboost_chrono.so +0 -0
- hikyuu/cpp/libboost_chrono.so.1.90.0 +0 -0
- hikyuu/cpp/libboost_container.so +0 -0
- hikyuu/cpp/libboost_container.so.1.90.0 +0 -0
- hikyuu/cpp/libboost_date_time.so +0 -0
- hikyuu/cpp/libboost_date_time.so.1.90.0 +0 -0
- hikyuu/cpp/libboost_locale.so +0 -0
- hikyuu/cpp/libboost_locale.so.1.90.0 +0 -0
- hikyuu/cpp/libboost_random.so +0 -0
- hikyuu/cpp/libboost_random.so.1.90.0 +0 -0
- hikyuu/cpp/libboost_serialization.so +0 -0
- hikyuu/cpp/libboost_serialization.so.1.90.0 +0 -0
- hikyuu/cpp/libboost_thread.so +0 -0
- hikyuu/cpp/libboost_thread.so.1.90.0 +0 -0
- hikyuu/cpp/libboost_wserialization.so +0 -0
- hikyuu/cpp/libboost_wserialization.so.1.90.0 +0 -0
- hikyuu/cpp/libhikyuu.so +0 -0
- hikyuu/cpp/libsqlite3.so +0 -0
- hikyuu/data/clickhouse_upgrade/0001.sql +2 -0
- hikyuu/data/common_clickhouse.py +1 -3
- hikyuu/data/download_block.py +1 -1
- hikyuu/data/hku_config_template.py +30 -3
- hikyuu/data/mysql_upgrade/0029.sql +2 -0
- hikyuu/data/pytdx_to_clickhouse.py +86 -32
- hikyuu/data/pytdx_to_h5.py +73 -28
- hikyuu/data/pytdx_to_mysql.py +65 -21
- hikyuu/data/pytdx_weight_to_clickhouse.py +2 -0
- hikyuu/data/pytdx_weight_to_mysql.py +2 -0
- hikyuu/data/pytdx_weight_to_sqlite.py +2 -0
- hikyuu/data/sqlite_upgrade/0029.sql +4 -0
- hikyuu/data/tdx_to_clickhouse.py +2 -2
- hikyuu/data/tdx_to_h5.py +11 -11
- hikyuu/data/tdx_to_mysql.py +2 -2
- hikyuu/draw/drawplot/bokeh_draw.pyi +14 -7
- hikyuu/draw/drawplot/echarts_draw.pyi +14 -7
- hikyuu/draw/drawplot/matplotlib_draw.py +8 -2
- hikyuu/draw/drawplot/matplotlib_draw.pyi +14 -7
- hikyuu/extend.pyi +8 -3
- hikyuu/gui/HikyuuTDX.py +42 -3
- hikyuu/gui/data/MainWindow.py +189 -129
- hikyuu/hub.pyi +6 -6
- hikyuu/include/hikyuu/StockManager.h +17 -2
- hikyuu/include/hikyuu/StrategyContext.h +4 -4
- hikyuu/include/hikyuu/data_driver/BaseInfoDriver.h +2 -1
- hikyuu/include/hikyuu/data_driver/KDataDriver.h +2 -4
- hikyuu/include/hikyuu/data_driver/kdata/mysql/MySQLKDataDriver.h +5 -1
- hikyuu/include/hikyuu/data_driver/kdata/sqlite/SQLiteKDataDriver.h +1 -1
- hikyuu/include/hikyuu/global/sysinfo.h +24 -5
- hikyuu/include/hikyuu/indicator/IndicatorImp.h +1 -1
- hikyuu/include/hikyuu/plugin/KDataToClickHouseImporter.h +40 -0
- hikyuu/include/hikyuu/plugin/KDataToMySQLImporter.h +40 -0
- hikyuu/include/hikyuu/plugin/checkdata.h +20 -0
- hikyuu/include/hikyuu/plugin/extind.h +3 -0
- hikyuu/include/hikyuu/plugin/hkuextra.h +2 -0
- hikyuu/include/hikyuu/plugin/interface/CheckDataPluginInterface.h +25 -0
- hikyuu/include/hikyuu/plugin/interface/HkuExtraPluginInterface.h +2 -0
- hikyuu/include/hikyuu/plugin/interface/ImportKDataToClickHousePluginInterface.h +44 -0
- hikyuu/include/hikyuu/plugin/interface/ImportKDataToMySQLPluginInterface.h +42 -0
- hikyuu/include/hikyuu/plugin/interface/plugins.h +6 -0
- hikyuu/include/hikyuu/python/convert_any.h +9 -6
- hikyuu/include/hikyuu/python/pybind_utils.h +1 -1
- hikyuu/include/hikyuu/strategy/Strategy.h +1 -1
- hikyuu/include/hikyuu/trade_manage/TradeManagerBase.h +0 -1
- hikyuu/include/hikyuu/trade_manage/TradeRecord.h +2 -1
- hikyuu/include/hikyuu/trade_sys/allocatefunds/AllocateFundsBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/allocatefunds/build_in.h +1 -0
- hikyuu/include/hikyuu/trade_sys/allocatefunds/crt/AF_FixedAmount.h +26 -0
- hikyuu/include/hikyuu/trade_sys/allocatefunds/imp/FixAmountFunds.h +18 -0
- hikyuu/include/hikyuu/trade_sys/condition/ConditionBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/environment/EnvironmentBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/moneymanager/MoneyManagerBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/multifactor/MultiFactorBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/multifactor/NormalizeBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/multifactor/ScoresFilterBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/portfolio/Portfolio.h +13 -13
- hikyuu/include/hikyuu/trade_sys/profitgoal/ProfitGoalBase.h +9 -11
- hikyuu/include/hikyuu/trade_sys/selector/SelectorBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/signal/SignalBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/slippage/SlippageBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/stoploss/StoplossBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/system/System.h +1 -2
- hikyuu/include/hikyuu/utilities/Log.h +6 -7
- hikyuu/include/hikyuu/utilities/Parameter.h +17 -0
- hikyuu/include/hikyuu/utilities/config.h +28 -0
- hikyuu/include/hikyuu/utilities/plugin/PluginBase.h +17 -2
- hikyuu/include/hikyuu/utilities/plugin/PluginManager.h +41 -22
- hikyuu/include/hikyuu/utilities/thread/GlobalStealThreadPool.h +1 -2
- hikyuu/include/hikyuu/utilities/thread/GlobalThreadPool.h +1 -1
- hikyuu/include/hikyuu/utilities/thread/MQStealThreadPool.h +286 -0
- hikyuu/include/hikyuu/utilities/thread/MQThreadPool.h +1 -0
- hikyuu/include/hikyuu/utilities/thread/StealThreadPool.h +297 -0
- hikyuu/include/hikyuu/utilities/thread/ThreadPool.h +1 -0
- hikyuu/include/hikyuu/utilities/thread/WorkStealQueue.h +9 -8
- hikyuu/include/hikyuu/utilities/thread/algorithm.h +64 -14
- hikyuu/include/hikyuu/version.h +4 -4
- hikyuu/plugin/libbacktest.so +0 -0
- hikyuu/plugin/libcheckdata.so +0 -0
- hikyuu/plugin/libclickhousedriver.so +0 -0
- hikyuu/plugin/libdataserver.so +0 -0
- hikyuu/plugin/libdataserver_parquet.so +0 -0
- hikyuu/plugin/libdevice.so +0 -0
- hikyuu/plugin/libextind.so +0 -0
- hikyuu/plugin/libhkuextra.so +0 -0
- hikyuu/plugin/libimport2ch.so +0 -0
- hikyuu/plugin/libimport2hdf5.so +0 -0
- hikyuu/plugin/libimport2mysql.so +0 -0
- hikyuu/plugin/libtmreport.so +0 -0
- hikyuu/trade_manage/__init__.pyi +12 -7
- hikyuu/trade_manage/trade.pyi +12 -7
- hikyuu/trade_sys/trade_sys.py +54 -5
- hikyuu/util/__init__.pyi +1 -1
- hikyuu/util/singleton.pyi +1 -1
- {hikyuu-2.7.0.dist-info → hikyuu-2.7.3.dist-info}/METADATA +10 -4
- {hikyuu-2.7.0.dist-info → hikyuu-2.7.3.dist-info}/RECORD +136 -114
- hikyuu/cpp/libboost_chrono-mt.so +0 -0
- hikyuu/cpp/libboost_chrono-mt.so.1.88.0 +0 -0
- hikyuu/cpp/libboost_date_time-mt.so +0 -0
- hikyuu/cpp/libboost_date_time-mt.so.1.88.0 +0 -0
- hikyuu/cpp/libboost_serialization-mt.so +0 -0
- hikyuu/cpp/libboost_serialization-mt.so.1.88.0 +0 -0
- hikyuu/cpp/libboost_system-mt.so +0 -0
- hikyuu/cpp/libboost_system-mt.so.1.88.0 +0 -0
- hikyuu/cpp/libboost_thread-mt.so +0 -0
- hikyuu/cpp/libboost_thread-mt.so.1.88.0 +0 -0
- hikyuu/cpp/libboost_wserialization-mt.so +0 -0
- hikyuu/cpp/libboost_wserialization-mt.so.1.88.0 +0 -0
- hikyuu/data/pytdx_to_taos.py +0 -736
- {hikyuu-2.7.0.dist-info → hikyuu-2.7.3.dist-info}/WHEEL +0 -0
- {hikyuu-2.7.0.dist-info → hikyuu-2.7.3.dist-info}/entry_points.txt +0 -0
- {hikyuu-2.7.0.dist-info → hikyuu-2.7.3.dist-info}/top_level.txt +0 -0
|
@@ -23,13 +23,15 @@
|
|
|
23
23
|
# SOFTWARE.
|
|
24
24
|
|
|
25
25
|
import sys
|
|
26
|
+
import os
|
|
26
27
|
import math
|
|
27
28
|
import datetime
|
|
28
29
|
from pytdx.hq import TDXParams
|
|
30
|
+
from configparser import ConfigParser
|
|
29
31
|
|
|
30
32
|
from hikyuu.util import hku_error, hku_debug, hku_run_ignore_exception
|
|
31
33
|
|
|
32
|
-
from hikyuu import Datetime, roundEx
|
|
34
|
+
from hikyuu import Datetime, roundEx, is_valid_license, KDataToClickHouseImporter
|
|
33
35
|
from hikyuu.data.common import *
|
|
34
36
|
from hikyuu.data.common_pytdx import to_pytdx_market, pytdx_get_day_trans
|
|
35
37
|
from hikyuu.data.common_clickhouse import (
|
|
@@ -134,6 +136,9 @@ def import_stock_name(connect, api, market, quotations=None):
|
|
|
134
136
|
if code not in deSet:
|
|
135
137
|
newStockDict[code] = stock["name"]
|
|
136
138
|
|
|
139
|
+
# 号码前缀
|
|
140
|
+
codepre_list = get_codepre_list(connect, market, quotations)
|
|
141
|
+
|
|
137
142
|
stktype_list = get_stktype_list(quotations)
|
|
138
143
|
stktype_list = list(stktype_list)
|
|
139
144
|
stktype_list.remove(STOCKTYPE.INDEX) # 移除指数类型
|
|
@@ -149,23 +154,29 @@ def import_stock_name(connect, api, market, quotations=None):
|
|
|
149
154
|
|
|
150
155
|
oldname, oldtype, oldvalid, oldstartDate, oldendDate = oldstock[2], oldstock[3], oldstock[4], oldstock[5], oldstock[6]
|
|
151
156
|
|
|
157
|
+
# 检测是否类型发生变化
|
|
158
|
+
newtype = oldtype
|
|
159
|
+
for codepre in codepre_list:
|
|
160
|
+
length = len(codepre[0])
|
|
161
|
+
if oldcode[:length] == codepre[0]:
|
|
162
|
+
if oldtype != codepre[1]:
|
|
163
|
+
newtype = codepre[1]
|
|
164
|
+
break
|
|
165
|
+
|
|
152
166
|
# 新的代码表中无此股票,则置为无效
|
|
153
|
-
# if (oldvalid == 1) and (oldcode not in newStockDict):
|
|
154
167
|
if (oldvalid == 1) and ((oldcode not in newStockDict) or oldcode in deSet):
|
|
155
168
|
sql = f"delete from hku_base.stock where market='{market}' and code='{oldcode}'"
|
|
156
169
|
connect.command(sql)
|
|
157
|
-
insert_records.append((market, oldcode, oldname,
|
|
170
|
+
insert_records.append((market, oldcode, oldname, newtype, 0, oldstartDate, oldendDate))
|
|
158
171
|
|
|
159
172
|
# 股票名称发生变化,更新股票名称;如果原无效,则置为有效
|
|
160
173
|
if oldcode in newStockDict:
|
|
161
|
-
if oldname != newStockDict[oldcode] or oldvalid == 0:
|
|
174
|
+
if oldname != newStockDict[oldcode] or oldvalid == 0 or oldtype != newtype:
|
|
162
175
|
sql = f"delete from hku_base.stock where market='{market}' and code='{oldcode}'"
|
|
163
176
|
connect.command(sql)
|
|
164
|
-
insert_records.append((market, oldcode, newStockDict[oldcode],
|
|
177
|
+
insert_records.append((market, oldcode, newStockDict[oldcode], newtype, 1, oldstartDate, 99999999))
|
|
165
178
|
|
|
166
179
|
# 处理新出现的股票
|
|
167
|
-
codepre_list = get_codepre_list(connect, market, quotations)
|
|
168
|
-
|
|
169
180
|
today = datetime.date.today()
|
|
170
181
|
today = today.year * 10000 + today.month * 100 + today.day
|
|
171
182
|
count = 0
|
|
@@ -274,10 +285,10 @@ def import_one_stock_data(
|
|
|
274
285
|
today.year * 10000 + today.month * 100 + today.day
|
|
275
286
|
) * 10000 + 1500
|
|
276
287
|
else:
|
|
277
|
-
return 0
|
|
288
|
+
return (0, True, Datetime(last_datetime))
|
|
278
289
|
|
|
279
290
|
if today_datetime <= last_datetime:
|
|
280
|
-
return 0
|
|
291
|
+
return (0, True, Datetime(last_datetime))
|
|
281
292
|
|
|
282
293
|
get_bars = (
|
|
283
294
|
api.get_index_bars if stktype == STOCKTYPE.INDEX else api.get_security_bars
|
|
@@ -312,27 +323,27 @@ def import_one_stock_data(
|
|
|
312
323
|
if abs(last_krecord[1] - bar["open"]) / last_krecord[1] > 0.01:
|
|
313
324
|
hku_error(
|
|
314
325
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord open: {last_krecord[1]}, bar: {bar['open']}")
|
|
315
|
-
return 0
|
|
326
|
+
return (0, False, Datetime(last_datetime))
|
|
316
327
|
if abs(last_krecord[2] - bar["high"]) / last_krecord[2] > 0.01:
|
|
317
328
|
hku_error(
|
|
318
329
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord high: {last_krecord[2]}, bar: {bar['high']}")
|
|
319
|
-
return 0
|
|
320
|
-
if abs(last_krecord[3] - bar["low"]) / last_krecord[3] > 0.01:
|
|
330
|
+
return (0, False, Datetime(last_datetime))
|
|
331
|
+
if abs(last_krecord[3] - bar["low"]) / last_krecord[3] > 0.01 and abs(last_krecord[3] - bar["low"]) > 0.01:
|
|
321
332
|
hku_error(
|
|
322
333
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord low: {last_krecord[3]}, bar: {bar['low']}")
|
|
323
|
-
return 0
|
|
334
|
+
return (0, False, Datetime(last_datetime))
|
|
324
335
|
if abs(last_krecord[4] - bar["close"]) / last_krecord[4] > 0.01:
|
|
325
336
|
hku_error(
|
|
326
337
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord close: {last_krecord[4]}, bar: {bar['close']}")
|
|
327
|
-
return 0
|
|
328
|
-
if ktype == 'DAY' and last_krecord[5] != 0.0 and abs(last_krecord[5] - bar["amount"]
|
|
338
|
+
return (0, False, Datetime(last_datetime))
|
|
339
|
+
if ktype == 'DAY' and last_krecord[5] != 0.0 and abs(last_krecord[5] - bar["amount"]) > 10000:
|
|
329
340
|
hku_error(
|
|
330
|
-
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord amount: {last_krecord[5]}, bar: {bar['amount']
|
|
331
|
-
return 0
|
|
332
|
-
if ktype == 'DAY' and last_krecord[6] != 0.0 and last_krecord[
|
|
341
|
+
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord amount: {last_krecord[5]}, bar: {bar['amount']}")
|
|
342
|
+
return (0, False, Datetime(last_datetime))
|
|
343
|
+
if ktype == 'DAY' and last_krecord[6] != 0.0 and last_krecord[6] != 0.0 and abs(last_krecord[6] - bar["vol"]) > 10000:
|
|
333
344
|
hku_error(
|
|
334
345
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord count: {last_krecord[6]}, bar: {bar['vol']}")
|
|
335
|
-
return 0
|
|
346
|
+
return (0, False, Datetime(last_datetime))
|
|
336
347
|
continue
|
|
337
348
|
|
|
338
349
|
if (
|
|
@@ -365,7 +376,7 @@ def import_one_stock_data(
|
|
|
365
376
|
data=buf)
|
|
366
377
|
connect.insert(context=ic, settings={"prefer_warmed_unmerged_parts_seconds": 86400})
|
|
367
378
|
|
|
368
|
-
return len(buf)
|
|
379
|
+
return (len(buf), True, Datetime(last_datetime))
|
|
369
380
|
|
|
370
381
|
|
|
371
382
|
def update_stock_info(connect, market):
|
|
@@ -409,7 +420,7 @@ def clear_extern_data(connect, market, data_type):
|
|
|
409
420
|
index_list = ('min15', 'min30', 'min60', 'hour2')
|
|
410
421
|
lastdate = connect.command(
|
|
411
422
|
f"select toInt32(max(date)) from hku_data.min5_k where market='SH' and code='000001'")
|
|
412
|
-
lastdate = Datetime.from_timestamp_utc(lastdate*1000000).start_of_day()
|
|
423
|
+
lastdate = Datetime.from_timestamp_utc(int(lastdate*1000000)).start_of_day()
|
|
413
424
|
last_timestamp = Datetime(lastdate).timestamp_utc()//1000000
|
|
414
425
|
for index_type in index_list:
|
|
415
426
|
sql = f"delete from hku_data.{index_type}_k where market='{market}' and date>={last_timestamp}"
|
|
@@ -420,6 +431,16 @@ def clear_extern_data(connect, market, data_type):
|
|
|
420
431
|
hku_info(f"清理 {market} {data_type} 线扩展数据完毕")
|
|
421
432
|
|
|
422
433
|
|
|
434
|
+
@hku_catch(ret=None)
|
|
435
|
+
def get_clickhouse_importer():
|
|
436
|
+
filename = os.path.expanduser('~') + '/.hikyuu/hikyuu.ini'
|
|
437
|
+
config = ConfigParser()
|
|
438
|
+
config.read(filename, encoding='utf-8')
|
|
439
|
+
importer = KDataToClickHouseImporter()
|
|
440
|
+
return importer if importer.set_config(config.get("kdata", "host"), config.getint("kdata", "port", fallback=9000),
|
|
441
|
+
config.get("kdata", "usr"), config.get("kdata", "pwd")) else None
|
|
442
|
+
|
|
443
|
+
|
|
423
444
|
@hku_catch(trace=True, re_raise=True)
|
|
424
445
|
def import_data(
|
|
425
446
|
connect,
|
|
@@ -460,6 +481,9 @@ def import_data(
|
|
|
460
481
|
for index_type in index_list:
|
|
461
482
|
update_data[index_type] = []
|
|
462
483
|
|
|
484
|
+
failed_limit = 20
|
|
485
|
+
failed_count = 0
|
|
486
|
+
failed_list = []
|
|
463
487
|
total = len(stock_list)
|
|
464
488
|
# market, code, valid, type
|
|
465
489
|
for i, stock in enumerate(stock_list):
|
|
@@ -468,9 +492,15 @@ def import_data(
|
|
|
468
492
|
progress(i, total)
|
|
469
493
|
continue
|
|
470
494
|
|
|
471
|
-
this_count = import_one_stock_data(
|
|
495
|
+
this_count, success, lastdate = import_one_stock_data(
|
|
472
496
|
connect, api, market, ktype, stock, startDate
|
|
473
497
|
)
|
|
498
|
+
if not success:
|
|
499
|
+
failed_count += 1
|
|
500
|
+
failed_list.append((market, stock[1], lastdate))
|
|
501
|
+
if failed_count >= failed_limit:
|
|
502
|
+
# hku_error(f"{market} {ktype} 连续失败20个股票,已停止导入, 建议重新导入")
|
|
503
|
+
break
|
|
474
504
|
add_record_count += this_count
|
|
475
505
|
if ktype in ("DAY", "5MIN"):
|
|
476
506
|
if ktype == "DAY":
|
|
@@ -490,6 +520,9 @@ def import_data(
|
|
|
490
520
|
if progress:
|
|
491
521
|
progress(i, total)
|
|
492
522
|
|
|
523
|
+
if total > 0 and progress:
|
|
524
|
+
progress(total, total)
|
|
525
|
+
|
|
493
526
|
if ktype in ("DAY", "5MIN"):
|
|
494
527
|
for index_type in index_list:
|
|
495
528
|
if len(update_data[index_type]) > 0:
|
|
@@ -501,6 +534,25 @@ def import_data(
|
|
|
501
534
|
update_data[index_type].clear()
|
|
502
535
|
update_data.clear()
|
|
503
536
|
|
|
537
|
+
if 0 < failed_count < failed_limit and is_valid_license():
|
|
538
|
+
# 删除最后记录
|
|
539
|
+
ktype_dict = {
|
|
540
|
+
'DAY': 'DAY',
|
|
541
|
+
'1MIN': 'MIN',
|
|
542
|
+
'5MIN': 'MIN5'
|
|
543
|
+
}
|
|
544
|
+
nktype = ktype_dict[ktype]
|
|
545
|
+
ch_importer = get_clickhouse_importer()
|
|
546
|
+
if ch_importer is not None:
|
|
547
|
+
for r in failed_list:
|
|
548
|
+
hku_warn(f"清理 {r[0]} {r[1]} {nktype} {r[2].start_of_day()}")
|
|
549
|
+
ch_importer.remove(r[0], r[1], nktype, r[2].start_of_day())
|
|
550
|
+
hku_warn(f"已清理 {market} {failed_count} 个失败股票的最后记录,建议重新导入")
|
|
551
|
+
|
|
552
|
+
if failed_count >= failed_limit:
|
|
553
|
+
hku_error(f"{market} {ktype} 连续失败20个股票,已停止导入, 建议重新导入")
|
|
554
|
+
return add_record_count
|
|
555
|
+
|
|
504
556
|
cur_year = Datetime.today().year
|
|
505
557
|
if ktype == "DAY":
|
|
506
558
|
update_stock_info(connect, market)
|
|
@@ -592,15 +644,16 @@ def import_on_stock_trans(connect, api, market, stock_record, max_days):
|
|
|
592
644
|
if second > 59:
|
|
593
645
|
continue
|
|
594
646
|
|
|
595
|
-
|
|
596
|
-
(
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
647
|
+
if record['price'] > 0.0 and record['vol'] >= 0.0:
|
|
648
|
+
trans_buf.append(
|
|
649
|
+
(
|
|
650
|
+
market, code,
|
|
651
|
+
Datetime(cur_date * 1000000 + minute * 100 + second).timestamp_utc()//1000000,
|
|
652
|
+
int(roundEx(record["price"], 3) * 1000.0),
|
|
653
|
+
int(record["vol"]),
|
|
654
|
+
record["buyorsell"],
|
|
655
|
+
)
|
|
602
656
|
)
|
|
603
|
-
)
|
|
604
657
|
except Exception as e:
|
|
605
658
|
hku_error("Failed trans to record! {}", e)
|
|
606
659
|
|
|
@@ -701,8 +754,9 @@ def import_on_stock_time(connect, api, market, stock_record, max_days):
|
|
|
701
754
|
elif time == 1360:
|
|
702
755
|
time = 1400
|
|
703
756
|
try:
|
|
704
|
-
|
|
705
|
-
|
|
757
|
+
if record['price'] > 0.0 and record['vol'] >= 0.0:
|
|
758
|
+
time_buf.append((market, code, Datetime(this_date + time).timestamp_utc() //
|
|
759
|
+
ticks, int(roundEx(record['price'], 3) * 1000.0), int(record['vol'])))
|
|
706
760
|
time += 1
|
|
707
761
|
except Exception as e:
|
|
708
762
|
hku_error("Failed trans record {}! {}".format(record, e))
|
hikyuu/data/pytdx_to_h5.py
CHANGED
|
@@ -23,13 +23,15 @@
|
|
|
23
23
|
# SOFTWARE.
|
|
24
24
|
|
|
25
25
|
import sys
|
|
26
|
+
import os
|
|
26
27
|
import math
|
|
27
28
|
import datetime
|
|
28
29
|
import sqlite3
|
|
29
30
|
from pytdx.hq import TDXParams
|
|
31
|
+
from configparser import ConfigParser
|
|
30
32
|
|
|
31
33
|
from hikyuu.util.mylog import get_default_logger, hku_error, hku_debug
|
|
32
|
-
from hikyuu import Datetime
|
|
34
|
+
from hikyuu import Datetime, is_valid_license, KDataToHdf5Importer
|
|
33
35
|
from hikyuu.data.common import *
|
|
34
36
|
from hikyuu.data.common_pytdx import to_pytdx_market, pytdx_get_day_trans
|
|
35
37
|
from hikyuu.data.common_sqlite3 import (
|
|
@@ -235,6 +237,7 @@ def guess_5min_n_step(last_datetime):
|
|
|
235
237
|
return (n, step)
|
|
236
238
|
|
|
237
239
|
|
|
240
|
+
@hku_catch(trace=True)
|
|
238
241
|
def import_one_stock_data(connect, api, h5file, market, ktype, stock_record, startDate=199012191500):
|
|
239
242
|
market = market.upper()
|
|
240
243
|
pytdx_market = to_pytdx_market(market)
|
|
@@ -246,9 +249,9 @@ def import_one_stock_data(connect, api, h5file, market, ktype, stock_record, sta
|
|
|
246
249
|
table = get_h5table(h5file, market, code)
|
|
247
250
|
if table is None:
|
|
248
251
|
hku_error("Can't get table({}{})".format(market, code))
|
|
249
|
-
return 0
|
|
252
|
+
return (0, True, Datetime())
|
|
250
253
|
|
|
251
|
-
last_datetime = table[-1]['datetime'] if table.nrows > 0 else startDate
|
|
254
|
+
last_datetime = int(table[-1]['datetime']) if table.nrows > 0 else startDate
|
|
252
255
|
|
|
253
256
|
today = datetime.date.today()
|
|
254
257
|
if ktype == 'DAY':
|
|
@@ -266,10 +269,10 @@ def import_one_stock_data(connect, api, h5file, market, ktype, stock_record, sta
|
|
|
266
269
|
pytdx_kline_type = TDXParams.KLINE_TYPE_5MIN
|
|
267
270
|
today_datetime = (today.year * 10000 + today.month * 100 + today.day) * 10000 + 1500
|
|
268
271
|
else:
|
|
269
|
-
return 0
|
|
272
|
+
return (0, True, Datetime(last_datetime))
|
|
270
273
|
|
|
271
274
|
if today_datetime <= last_datetime:
|
|
272
|
-
return 0
|
|
275
|
+
return (0, True, Datetime(last_datetime))
|
|
273
276
|
|
|
274
277
|
get_bars = api.get_index_bars if stktype == STOCKTYPE.INDEX else api.get_security_bars
|
|
275
278
|
|
|
@@ -311,27 +314,27 @@ def import_one_stock_data(connect, api, h5file, market, ktype, stock_record, sta
|
|
|
311
314
|
if abs(last_krecord['openPrice']*0.001 - bar["open"]) / (last_krecord['openPrice']*0.001) > 0.02:
|
|
312
315
|
hku_error(
|
|
313
316
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord open: {last_krecord['openPrice']*0.001}, bar: {bar['open']}")
|
|
314
|
-
return 0
|
|
317
|
+
return (0, False, Datetime(last_datetime))
|
|
315
318
|
if abs(last_krecord['highPrice']*0.001 - bar["high"]) / (last_krecord['highPrice']*0.001) > 0.02:
|
|
316
319
|
hku_error(
|
|
317
320
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord high: {last_krecord['highPrice']*0.001}, bar: {bar['high']}")
|
|
318
|
-
return 0
|
|
321
|
+
return (0, False, Datetime(last_datetime))
|
|
319
322
|
if abs(last_krecord['lowPrice']*0.001 - bar["low"]) / (last_krecord['lowPrice']*0.001) > 0.02:
|
|
320
323
|
hku_error(
|
|
321
324
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord low: {last_krecord['lowPrice']*0.001}, bar: {bar['low']}")
|
|
322
|
-
return 0
|
|
325
|
+
return (0, False, Datetime(last_datetime))
|
|
323
326
|
if abs(last_krecord['closePrice']*0.001 - bar["close"]) / (last_krecord['closePrice']*0.001) > 0.02:
|
|
324
327
|
hku_error(
|
|
325
328
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord close: {last_krecord['closePrice']*0.001}, bar: {bar['close']}")
|
|
326
|
-
return 0
|
|
327
|
-
if ktype == 'DAY' and last_krecord['transAmount'] != 0
|
|
329
|
+
return (0, False, Datetime(last_datetime))
|
|
330
|
+
if ktype == 'DAY' and last_krecord['transAmount'] != 0 and (abs(float(last_krecord['transAmount']) - round(bar["amount"]*0.001))) > 10:
|
|
328
331
|
hku_error(
|
|
329
|
-
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord amount: {last_krecord['transAmount']}, bar: {bar['amount']*0.001}")
|
|
330
|
-
return 0
|
|
331
|
-
if ktype == 'DAY' and last_krecord['transCount'] != 0
|
|
332
|
+
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord amount: {float(last_krecord['transAmount'])}, bar: {round(bar['amount']*0.001)}")
|
|
333
|
+
return (0, False, Datetime(last_datetime))
|
|
334
|
+
if ktype == 'DAY' and last_krecord['transCount'] != 0 and abs(float(last_krecord['transCount']) - bar["vol"]) > 10:
|
|
332
335
|
hku_error(
|
|
333
336
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord count: {last_krecord['transCount']}, bar: {bar['vol']}")
|
|
334
|
-
return 0
|
|
337
|
+
return (0, False, Datetime(last_datetime))
|
|
335
338
|
continue
|
|
336
339
|
|
|
337
340
|
if today_datetime >= bar_datetime > last_datetime \
|
|
@@ -378,7 +381,16 @@ def import_one_stock_data(connect, api, h5file, market, ktype, stock_record, sta
|
|
|
378
381
|
table.remove()
|
|
379
382
|
|
|
380
383
|
# table.close()
|
|
381
|
-
return add_record_count
|
|
384
|
+
return (add_record_count, True, Datetime(last_datetime))
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
@hku_catch(ret=None)
|
|
388
|
+
def get_hdf5_importer(market, ktype):
|
|
389
|
+
filename = os.path.expanduser('~') + '/.hikyuu/hikyuu.ini'
|
|
390
|
+
config = ConfigParser()
|
|
391
|
+
config.read(filename, encoding='utf-8')
|
|
392
|
+
importer = KDataToHdf5Importer()
|
|
393
|
+
return importer if importer.set_config(config.get("hikyuu", "datadir"), [market], [ktype]) else None
|
|
382
394
|
|
|
383
395
|
|
|
384
396
|
def import_data(connect, market, ktype, quotations, api, dest_dir, startDate=199012190000, progress=ProgressBar):
|
|
@@ -401,6 +413,9 @@ def import_data(connect, market, ktype, quotations, api, dest_dir, startDate=199
|
|
|
401
413
|
if not stock_list:
|
|
402
414
|
return 0
|
|
403
415
|
|
|
416
|
+
failed_limit = 20
|
|
417
|
+
failed_count = 0
|
|
418
|
+
failed_list = []
|
|
404
419
|
total = len(stock_list)
|
|
405
420
|
for i, stock in enumerate(stock_list):
|
|
406
421
|
if stock[3] == 0 or len(stock[2]) != 6:
|
|
@@ -408,7 +423,12 @@ def import_data(connect, market, ktype, quotations, api, dest_dir, startDate=199
|
|
|
408
423
|
progress(i, total)
|
|
409
424
|
continue
|
|
410
425
|
|
|
411
|
-
this_count = import_one_stock_data(connect, api, h5file, market, ktype, stock, startDate)
|
|
426
|
+
this_count, success, lastdate = import_one_stock_data(connect, api, h5file, market, ktype, stock, startDate)
|
|
427
|
+
if not success:
|
|
428
|
+
failed_count += 1
|
|
429
|
+
failed_list.append((market, stock[2], lastdate))
|
|
430
|
+
if failed_count >= failed_limit:
|
|
431
|
+
break
|
|
412
432
|
add_record_count += this_count
|
|
413
433
|
if this_count > 0:
|
|
414
434
|
if ktype == 'DAY':
|
|
@@ -418,8 +438,31 @@ def import_data(connect, market, ktype, quotations, api, dest_dir, startDate=199
|
|
|
418
438
|
if progress:
|
|
419
439
|
progress(i, total)
|
|
420
440
|
|
|
441
|
+
if total > 0 and progress:
|
|
442
|
+
progress(total, total)
|
|
443
|
+
|
|
421
444
|
connect.commit()
|
|
422
445
|
h5file.close()
|
|
446
|
+
|
|
447
|
+
if 0 < failed_count < failed_limit and is_valid_license():
|
|
448
|
+
# 删除最后记录
|
|
449
|
+
ktype_dict = {
|
|
450
|
+
'DAY': 'DAY',
|
|
451
|
+
'1MIN': 'MIN',
|
|
452
|
+
'5MIN': 'MIN5'
|
|
453
|
+
}
|
|
454
|
+
nktype = ktype_dict[ktype]
|
|
455
|
+
h5_importer = get_hdf5_importer(market, nktype)
|
|
456
|
+
if h5_importer is not None:
|
|
457
|
+
for r in failed_list:
|
|
458
|
+
hku_warn("清理 {}{} {}: {}", r[0], r[1], nktype, r[2].start_of_day())
|
|
459
|
+
h5_importer.remove(r[0], r[1], nktype, r[2].start_of_day())
|
|
460
|
+
hku_warn(f"已清理 {market} {failed_count} 个失败股票的最后记录,建议重新导入")
|
|
461
|
+
|
|
462
|
+
if failed_count >= failed_limit:
|
|
463
|
+
hku_error(f"{market} {ktype} 连续失败20个股票,已停止导入, 建议重新导入")
|
|
464
|
+
return add_record_count
|
|
465
|
+
|
|
423
466
|
return add_record_count
|
|
424
467
|
|
|
425
468
|
|
|
@@ -479,12 +522,13 @@ def import_on_stock_trans(connect, api, h5file, market, stock_record, max_days):
|
|
|
479
522
|
second += 3
|
|
480
523
|
if second > 59:
|
|
481
524
|
continue
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
525
|
+
if record['price'] > 0.0 and record['vol'] >= 0.0:
|
|
526
|
+
row['datetime'] = cur_date * 1000000 + minute * 100 + second
|
|
527
|
+
row['price'] = int(record['price'] * 1000)
|
|
528
|
+
row['vol'] = record['vol']
|
|
529
|
+
row['buyorsell'] = record['buyorsell']
|
|
530
|
+
row.append()
|
|
531
|
+
add_record_count += 1
|
|
488
532
|
except Exception as e:
|
|
489
533
|
hku_error("Failed trans to record! {}", e)
|
|
490
534
|
|
|
@@ -578,12 +622,13 @@ def import_on_stock_time(connect, api, h5file, market, stock_record, max_days):
|
|
|
578
622
|
elif time == 1360:
|
|
579
623
|
time = 1400
|
|
580
624
|
try:
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
625
|
+
if record['price'] > 0.0 and record['vol'] >= 0.0:
|
|
626
|
+
row['datetime'] = this_date + time
|
|
627
|
+
row['price'] = int(record['price'] * 1000)
|
|
628
|
+
row['vol'] = record['vol']
|
|
629
|
+
row.append()
|
|
630
|
+
add_record_count += 1
|
|
585
631
|
time += 1
|
|
586
|
-
add_record_count += 1
|
|
587
632
|
except Exception as e:
|
|
588
633
|
hku_error("Failed trans record {}! {}".format(record, e))
|
|
589
634
|
|
|
@@ -624,7 +669,7 @@ if __name__ == '__main__':
|
|
|
624
669
|
import time
|
|
625
670
|
starttime = time.time()
|
|
626
671
|
|
|
627
|
-
dest_dir = "
|
|
672
|
+
dest_dir = "/Users/fasiondog/stock"
|
|
628
673
|
tdx_server = '180.101.48.170'
|
|
629
674
|
tdx_port = 7709
|
|
630
675
|
quotations = ['stock', 'fund']
|
hikyuu/data/pytdx_to_mysql.py
CHANGED
|
@@ -23,15 +23,17 @@
|
|
|
23
23
|
# SOFTWARE.
|
|
24
24
|
|
|
25
25
|
import sys
|
|
26
|
+
import os
|
|
26
27
|
import math
|
|
27
28
|
import datetime
|
|
28
29
|
from pytdx.hq import TDXParams
|
|
30
|
+
from configparser import ConfigParser
|
|
29
31
|
|
|
30
32
|
from hikyuu.util.mylog import hku_error, hku_debug
|
|
31
33
|
|
|
32
34
|
import mysql.connector
|
|
33
35
|
|
|
34
|
-
from hikyuu import Datetime
|
|
36
|
+
from hikyuu import Datetime, is_valid_license, KDataToMySQLImporter
|
|
35
37
|
from .common import *
|
|
36
38
|
from .common_pytdx import to_pytdx_market, pytdx_get_day_trans
|
|
37
39
|
from .common_mysql import (
|
|
@@ -318,10 +320,10 @@ def import_one_stock_data(
|
|
|
318
320
|
today.year * 10000 + today.month * 100 + today.day
|
|
319
321
|
) * 10000 + 1500
|
|
320
322
|
else:
|
|
321
|
-
return 0
|
|
323
|
+
return (0, True, Datetime(last_datetime))
|
|
322
324
|
|
|
323
325
|
if today_datetime <= last_datetime:
|
|
324
|
-
return 0
|
|
326
|
+
return (0, True, Datetime(last_datetime))
|
|
325
327
|
|
|
326
328
|
get_bars = (
|
|
327
329
|
api.get_index_bars if stktype == STOCKTYPE.INDEX else api.get_security_bars
|
|
@@ -356,27 +358,27 @@ def import_one_stock_data(
|
|
|
356
358
|
if abs(last_krecord[1] - bar["open"]) / last_krecord[1] > 0.01:
|
|
357
359
|
hku_error(
|
|
358
360
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord open: {last_krecord[1]}, bar: {bar['open']}")
|
|
359
|
-
return 0
|
|
361
|
+
return (0, False, Datetime(last_datetime))
|
|
360
362
|
if abs(last_krecord[2] - bar["high"]) / last_krecord[2] > 0.01:
|
|
361
363
|
hku_error(
|
|
362
364
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord high: {last_krecord[2]}, bar: {bar['high']}")
|
|
363
|
-
return 0
|
|
365
|
+
return (0, False, Datetime(last_datetime))
|
|
364
366
|
if abs(last_krecord[3] - bar["low"]) / last_krecord[3] > 0.01:
|
|
365
367
|
hku_error(
|
|
366
368
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord low: {last_krecord[3]}, bar: {bar['low']}")
|
|
367
|
-
return 0
|
|
369
|
+
return (0, False, Datetime(last_datetime))
|
|
368
370
|
if abs(last_krecord[4] - bar["close"]) / last_krecord[4] > 0.01:
|
|
369
371
|
hku_error(
|
|
370
372
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord close: {last_krecord[4]}, bar: {bar['close']}")
|
|
371
|
-
return 0
|
|
372
|
-
if ktype == 'DAY' and last_krecord[5] != 0.0 and abs(last_krecord[5] - bar["amount"]*0.001)
|
|
373
|
+
return (0, False, Datetime(last_datetime))
|
|
374
|
+
if ktype == 'DAY' and last_krecord[5] != 0.0 and abs(last_krecord[5] - bar["amount"]*0.001) > 10:
|
|
373
375
|
hku_error(
|
|
374
376
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord amount: {last_krecord[5]}, bar: {bar['amount']*0.001}")
|
|
375
|
-
return 0
|
|
376
|
-
if ktype == 'DAY' and last_krecord[6] != 0.0 and abs(last_krecord[6] - bar["vol"])
|
|
377
|
+
return (0, False, Datetime(last_datetime))
|
|
378
|
+
if ktype == 'DAY' and last_krecord[6] != 0.0 and abs(last_krecord[6] - bar["vol"]) > 10:
|
|
377
379
|
hku_error(
|
|
378
380
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord count: {last_krecord[6]}, bar: {bar['vol']}")
|
|
379
|
-
return 0
|
|
381
|
+
return (0, False, Datetime(last_datetime))
|
|
380
382
|
continue
|
|
381
383
|
|
|
382
384
|
if (
|
|
@@ -440,7 +442,17 @@ def import_one_stock_data(
|
|
|
440
442
|
connect.commit()
|
|
441
443
|
cur.close()
|
|
442
444
|
|
|
443
|
-
return len(buf)
|
|
445
|
+
return (len(buf), True, Datetime(last_datetime))
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
@hku_catch(ret=None)
|
|
449
|
+
def get_mysql_importer():
|
|
450
|
+
filename = os.path.expanduser('~') + '/.hikyuu/hikyuu.ini'
|
|
451
|
+
config = ConfigParser()
|
|
452
|
+
config.read(filename, encoding='utf-8')
|
|
453
|
+
importer = KDataToMySQLImporter()
|
|
454
|
+
return importer if importer.set_config(config.get("kdata", "host"), config.getint("kdata", "port", fallback=3306),
|
|
455
|
+
config.get("kdata", "usr"), config.get("kdata", "pwd")) else None
|
|
444
456
|
|
|
445
457
|
|
|
446
458
|
@hku_catch(trace=True, re_raise=True)
|
|
@@ -470,6 +482,9 @@ def import_data(
|
|
|
470
482
|
|
|
471
483
|
stock_list = get_stock_list(connect, market, quotations)
|
|
472
484
|
|
|
485
|
+
failed_limit = 20
|
|
486
|
+
failed_count = 0
|
|
487
|
+
failed_list = []
|
|
473
488
|
total = len(stock_list)
|
|
474
489
|
for i, stock in enumerate(stock_list):
|
|
475
490
|
if stock[3] == 0 or len(stock[2]) != 6:
|
|
@@ -477,9 +492,14 @@ def import_data(
|
|
|
477
492
|
progress(i, total)
|
|
478
493
|
continue
|
|
479
494
|
|
|
480
|
-
this_count = import_one_stock_data(
|
|
495
|
+
this_count, success, lastdate = import_one_stock_data(
|
|
481
496
|
connect, api, market, ktype, stock, startDate
|
|
482
497
|
)
|
|
498
|
+
if not success:
|
|
499
|
+
failed_count += 1
|
|
500
|
+
failed_list.append((market, stock[2], lastdate))
|
|
501
|
+
if failed_count >= failed_limit:
|
|
502
|
+
break
|
|
483
503
|
add_record_count += this_count
|
|
484
504
|
if this_count > 0:
|
|
485
505
|
if ktype == "DAY":
|
|
@@ -491,6 +511,28 @@ def import_data(
|
|
|
491
511
|
progress(i, total)
|
|
492
512
|
|
|
493
513
|
connect.commit()
|
|
514
|
+
|
|
515
|
+
if total > 0 and progress:
|
|
516
|
+
progress(total, total)
|
|
517
|
+
|
|
518
|
+
if 0 < failed_count < failed_limit and is_valid_license():
|
|
519
|
+
# 删除最后记录
|
|
520
|
+
ktype_dict = {
|
|
521
|
+
'DAY': 'DAY',
|
|
522
|
+
'1MIN': 'MIN',
|
|
523
|
+
'5MIN': 'MIN5'
|
|
524
|
+
}
|
|
525
|
+
nktype = ktype_dict[ktype]
|
|
526
|
+
h5_importer = get_mysql_importer(market, nktype)
|
|
527
|
+
if h5_importer is not None:
|
|
528
|
+
for r in failed_list:
|
|
529
|
+
hku_warn("remove {}{} {}: {}", r[0], r[1], nktype, r[2].start_of_day())
|
|
530
|
+
h5_importer.remove(r[0], r[1], nktype, r[2].start_of_day())
|
|
531
|
+
hku_warn(f"已清理 {market} {failed_count} 个失败股票的最后记录,建议重新导入")
|
|
532
|
+
|
|
533
|
+
if failed_count >= failed_limit:
|
|
534
|
+
hku_error(f"{market} {ktype} 连续失败20个股票,已停止导入, 建议重新导入")
|
|
535
|
+
return add_record_count
|
|
494
536
|
return add_record_count
|
|
495
537
|
|
|
496
538
|
|
|
@@ -588,14 +630,15 @@ def import_on_stock_trans(connect, api, market, stock_record, max_days):
|
|
|
588
630
|
if second > 59:
|
|
589
631
|
continue
|
|
590
632
|
|
|
591
|
-
|
|
592
|
-
(
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
633
|
+
if record['price'] > 0.0 and record['vol'] >= 0.0:
|
|
634
|
+
trans_buf.append(
|
|
635
|
+
(
|
|
636
|
+
cur_date * 1000000 + minute * 100 + second,
|
|
637
|
+
record["price"],
|
|
638
|
+
record["vol"],
|
|
639
|
+
record["buyorsell"],
|
|
640
|
+
)
|
|
597
641
|
)
|
|
598
|
-
)
|
|
599
642
|
except Exception as e:
|
|
600
643
|
hku_error("Failed trans to record! {}", e)
|
|
601
644
|
|
|
@@ -721,7 +764,8 @@ def import_on_stock_time(connect, api, market, stock_record, max_days):
|
|
|
721
764
|
elif time == 1360:
|
|
722
765
|
time = 1400
|
|
723
766
|
try:
|
|
724
|
-
|
|
767
|
+
if record['price'] > 0.0 and record['vol'] >= 0.0:
|
|
768
|
+
time_buf.append((this_date + time, record['price'], record['vol']))
|
|
725
769
|
time += 1
|
|
726
770
|
except Exception as e:
|
|
727
771
|
hku_error("Failed trans record {}! {}".format(record, e))
|
|
@@ -55,6 +55,8 @@ def pytdx_import_weight_to_clickhouse(pytdx_api, connect, market):
|
|
|
55
55
|
db_last_date, last_total_count, last_free_count = (0, 0, 0)
|
|
56
56
|
|
|
57
57
|
xdxr_list = pytdx_api.get_xdxr_info(pytdx_market, code)
|
|
58
|
+
if xdxr_list is None:
|
|
59
|
+
continue
|
|
58
60
|
update_last_db_weight = False
|
|
59
61
|
new_last_db_weight = last_db_weight
|
|
60
62
|
records = {}
|
|
@@ -67,6 +67,8 @@ def pytdx_import_weight_to_mysql(pytdx_api, connect, market):
|
|
|
67
67
|
cur.close()
|
|
68
68
|
|
|
69
69
|
xdxr_list = pytdx_api.get_xdxr_info(pytdx_market, code)
|
|
70
|
+
if xdxr_list is None:
|
|
71
|
+
continue
|
|
70
72
|
update_last_db_weight = False
|
|
71
73
|
new_last_db_weight = last_db_weight
|
|
72
74
|
records = {}
|
|
@@ -64,6 +64,8 @@ def pytdx_import_weight_to_sqlite(pytdx_api, connect, market):
|
|
|
64
64
|
cur.close()
|
|
65
65
|
|
|
66
66
|
xdxr_list = pytdx_api.get_xdxr_info(pytdx_market, code)
|
|
67
|
+
if xdxr_list is None:
|
|
68
|
+
continue
|
|
67
69
|
update_last_db_weight = False
|
|
68
70
|
new_last_db_weight = last_db_weight
|
|
69
71
|
records = {}
|