hikyuu 2.7.1__py3-none-win_amd64.whl → 2.7.1.1__py3-none-win_amd64.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/cpp/hikyuu.dll +0 -0
- hikyuu/data/pytdx_to_clickhouse.py +2 -2
- hikyuu/data/pytdx_to_h5.py +4 -4
- hikyuu/data/pytdx_to_mysql.py +2 -2
- hikyuu/include/hikyuu/version.h +2 -2
- hikyuu/plugin/clickhousedriver.dll +0 -0
- {hikyuu-2.7.1.dist-info → hikyuu-2.7.1.1.dist-info}/METADATA +1 -1
- {hikyuu-2.7.1.dist-info → hikyuu-2.7.1.1.dist-info}/RECORD +11 -12
- hikyuu/data/pytdx_to_taos.py +0 -736
- {hikyuu-2.7.1.dist-info → hikyuu-2.7.1.1.dist-info}/WHEEL +0 -0
- {hikyuu-2.7.1.dist-info → hikyuu-2.7.1.1.dist-info}/entry_points.txt +0 -0
- {hikyuu-2.7.1.dist-info → hikyuu-2.7.1.1.dist-info}/top_level.txt +0 -0
hikyuu/cpp/hikyuu.dll
CHANGED
|
Binary file
|
|
@@ -325,11 +325,11 @@ def import_one_stock_data(
|
|
|
325
325
|
hku_error(
|
|
326
326
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord close: {last_krecord[4]}, bar: {bar['close']}")
|
|
327
327
|
return 0
|
|
328
|
-
if ktype == 'DAY' and last_krecord[5] != 0.0 and abs(last_krecord[5] - bar["amount"]*0.001)
|
|
328
|
+
if ktype == 'DAY' and last_krecord[5] != 0.0 and abs(last_krecord[5] - bar["amount"]*0.001) > 10.0:
|
|
329
329
|
hku_error(
|
|
330
330
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord amount: {last_krecord[5]}, bar: {bar['amount']*0.001}")
|
|
331
331
|
return 0
|
|
332
|
-
if ktype == 'DAY' and last_krecord[6] != 0.0 and last_krecord[
|
|
332
|
+
if ktype == 'DAY' and last_krecord[6] != 0.0 and last_krecord[6] != 0.0 and abs(last_krecord[6] - bar["vol"]) > 10.0:
|
|
333
333
|
hku_error(
|
|
334
334
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord count: {last_krecord[6]}, bar: {bar['vol']}")
|
|
335
335
|
return 0
|
hikyuu/data/pytdx_to_h5.py
CHANGED
|
@@ -324,13 +324,13 @@ def import_one_stock_data(connect, api, h5file, market, ktype, stock_record, sta
|
|
|
324
324
|
hku_error(
|
|
325
325
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord close: {last_krecord['closePrice']*0.001}, bar: {bar['close']}")
|
|
326
326
|
return 0
|
|
327
|
-
if ktype == 'DAY' and last_krecord['transAmount'] != 0.0 and abs(last_krecord['transAmount'] -
|
|
327
|
+
if ktype == 'DAY' and last_krecord['transAmount'] != 0.0 and abs(last_krecord['transAmount'] - bar["amount"]*0.001) > 10.:
|
|
328
328
|
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}")
|
|
329
|
+
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord amount: {last_krecord['transAmount']}, bar: {int(bar['amount']*0.001)}")
|
|
330
330
|
return 0
|
|
331
|
-
if ktype == 'DAY' and last_krecord['transCount'] != 0.0 and abs(last_krecord['transCount'] -
|
|
331
|
+
if ktype == 'DAY' and last_krecord['transCount'] != 0.0 and abs(last_krecord['transCount'] - bar["vol"]) > 10:
|
|
332
332
|
hku_error(
|
|
333
|
-
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord count: {last_krecord['transCount']}, bar: {bar['vol']}")
|
|
333
|
+
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord count: {last_krecord['transCount']}, bar: {bar['vol']} {abs(last_krecord['transCount'] - bar["vol"])}")
|
|
334
334
|
return 0
|
|
335
335
|
continue
|
|
336
336
|
|
hikyuu/data/pytdx_to_mysql.py
CHANGED
|
@@ -369,11 +369,11 @@ def import_one_stock_data(
|
|
|
369
369
|
hku_error(
|
|
370
370
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord close: {last_krecord[4]}, bar: {bar['close']}")
|
|
371
371
|
return 0
|
|
372
|
-
if ktype == 'DAY' and last_krecord[5] != 0.0 and abs(last_krecord[5] - bar["amount"]*0.001)
|
|
372
|
+
if ktype == 'DAY' and last_krecord[5] != 0.0 and abs(last_krecord[5] - bar["amount"]*0.001) > 10:
|
|
373
373
|
hku_error(
|
|
374
374
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord amount: {last_krecord[5]}, bar: {bar['amount']*0.001}")
|
|
375
375
|
return 0
|
|
376
|
-
if ktype == 'DAY' and last_krecord[6] != 0.0 and abs(last_krecord[6] - bar["vol"])
|
|
376
|
+
if ktype == 'DAY' and last_krecord[6] != 0.0 and abs(last_krecord[6] - bar["vol"]) > 10:
|
|
377
377
|
hku_error(
|
|
378
378
|
f"fetch data from tdx error! {bar_datetime} {ktype} {market}{code} last_krecord count: {last_krecord[6]}, bar: {bar['vol']}")
|
|
379
379
|
return 0
|
hikyuu/include/hikyuu/version.h
CHANGED
|
@@ -16,9 +16,9 @@
|
|
|
16
16
|
#define HKU_VERSION_MAJOR 2
|
|
17
17
|
#define HKU_VERSION_MINOR 7
|
|
18
18
|
#define HKU_VERSION_ALTER 1
|
|
19
|
-
#define HKU_VERSION_BUILD
|
|
19
|
+
#define HKU_VERSION_BUILD 202512011236
|
|
20
20
|
#define HKU_VERSION_MODE "RELEASE"
|
|
21
|
-
#define HKU_VERSION_GIT "2.7.1
|
|
21
|
+
#define HKU_VERSION_GIT "2.7.1 master.d1695c85 (RELEASE)"
|
|
22
22
|
// clang-format on
|
|
23
23
|
|
|
24
24
|
#endif /* HKU_VERSION_H */
|
|
Binary file
|
|
@@ -33,7 +33,7 @@ hikyuu/cpp/core312.pyd,sha256=SoA51t-RWCPLz-D6sd9hcDDk2EFtvwmE9Vzx6tRJHWM,442316
|
|
|
33
33
|
hikyuu/cpp/core312.pyi,sha256=iXuawBZAEB9hqoV-IEVWZ8cd1JTxwCufvYwUZArCdjE,499470
|
|
34
34
|
hikyuu/cpp/core313.pyd,sha256=rHIPJh7JhN_A0-vzFgefgMo5-yTgBkj_HitP3dwgERM,4423168
|
|
35
35
|
hikyuu/cpp/core313.pyi,sha256=kEel6MPqfKQMiqAqvpF1RGIT4dUarD4ahTn_JsyhefU,498667
|
|
36
|
-
hikyuu/cpp/hikyuu.dll,sha256=
|
|
36
|
+
hikyuu/cpp/hikyuu.dll,sha256=yP-eEbd1yH2cBTAkoWWrhsY_cBNydkB8dpt4SCjHM84,14931456
|
|
37
37
|
hikyuu/cpp/hikyuu.lib,sha256=f7LahzL3BEL_Va4K7IuNnssYcjTW6nrN5iWn5JYv70o,14655978
|
|
38
38
|
hikyuu/cpp/hku_hdf5.dll,sha256=Diks-nS42Ix13UuDSRfafphpc1y7cNdRl1p8Ey_kGsQ,3515392
|
|
39
39
|
hikyuu/cpp/hku_hdf5_cpp.dll,sha256=76Acxay7XVoNBms2FSeg8oT6ApvkO13vE6LimEIYIjs,304128
|
|
@@ -68,10 +68,9 @@ hikyuu/data/hku_config_template.py,sha256=eJbHnijkZGi1FQKN65RD1cWB6U7otuMJTwdFhu
|
|
|
68
68
|
hikyuu/data/pytdx_finance_to_clickhouse.py,sha256=RFeQszAJsQz6gBlVGo-ctH6FhA9T5Gdu1MPDOQEZ_Jk,4794
|
|
69
69
|
hikyuu/data/pytdx_finance_to_mysql.py,sha256=hXtbPdsEqHdKyZbgooSH11_Kh55DzdknZEKHgbTaDKE,6470
|
|
70
70
|
hikyuu/data/pytdx_finance_to_sqlite.py,sha256=-6JA1pYUdqzhKHx6OegBQqJZcngm3ZqbR4wDYVx628s,7157
|
|
71
|
-
hikyuu/data/pytdx_to_clickhouse.py,sha256=
|
|
72
|
-
hikyuu/data/pytdx_to_h5.py,sha256=
|
|
73
|
-
hikyuu/data/pytdx_to_mysql.py,sha256=
|
|
74
|
-
hikyuu/data/pytdx_to_taos.py,sha256=o2HVJrmaaGiq3gYTU0fs_ox9a9IcWLgnNepoIRRqAAY,28205
|
|
71
|
+
hikyuu/data/pytdx_to_clickhouse.py,sha256=w6mX-brCQHmIVip2uV40QqSZffRPVqJhSkanowZSt28,36572
|
|
72
|
+
hikyuu/data/pytdx_to_h5.py,sha256=0wY9OQz-frayPDpVUebvw_6qMjLmNlJlJZY2vNN1Gec,28069
|
|
73
|
+
hikyuu/data/pytdx_to_mysql.py,sha256=6dozaQlGRdtGF0NUx1SFjIFEnhYCGzwyaTBklWuodz8,30308
|
|
75
74
|
hikyuu/data/pytdx_weight_to_clickhouse.py,sha256=D5J94qJXgPU7sn6FRtsAwOMGHjagqaNMYVc2cuAFgkY,9108
|
|
76
75
|
hikyuu/data/pytdx_weight_to_mysql.py,sha256=Sf4QV7EzFGncnBcmJCQm8zF7o9EOxYDpe4IHUw7NHZw,8835
|
|
77
76
|
hikyuu/data/pytdx_weight_to_sqlite.py,sha256=7gtkIWTvsaZxXzutLOE26zSsg-xh0I5Iy_GUdZUj95w,8829
|
|
@@ -308,7 +307,7 @@ hikyuu/include/hikyuu/doc.h,sha256=20HVEEYZPyudKL9fGaLf_JfoOid-UPWjmU024JOEJs4,7
|
|
|
308
307
|
hikyuu/include/hikyuu/hikyuu.h,sha256=FjOt_eY6nujo9YxmihN3CUmvqRY3M1mf4lYtZ5zH03c,1583
|
|
309
308
|
hikyuu/include/hikyuu/lang.h,sha256=_-zcFGu7Sh6vWEuUqUSbK9Kp3_wjkpXjNcIE3vVDFkE,1002
|
|
310
309
|
hikyuu/include/hikyuu/misc.h,sha256=_IQtzzlj6WImaRkDonr7u39i1UF377OFn0R9BMy0rO8,1085
|
|
311
|
-
hikyuu/include/hikyuu/version.h,sha256=
|
|
310
|
+
hikyuu/include/hikyuu/version.h,sha256=iqUq0_UPHFtc_HziY6eSyLfhFAF2VTLGsGviCXXFg7Q,507
|
|
312
311
|
hikyuu/include/hikyuu/analysis/__init__.py,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
313
312
|
hikyuu/include/hikyuu/analysis/analysis_sys.h,sha256=WJpfpLeKqpUjGFwmiRf_NCX8NvAHqBRuPDxMi4n-iVs,3239
|
|
314
313
|
hikyuu/include/hikyuu/analysis/combinate.h,sha256=--OhYTVLQ8bUNgl47V0uNO0IjSULxu7bXhYWbjNY4Ig,4196
|
|
@@ -1005,7 +1004,7 @@ hikyuu/indicator/indicator.py,sha256=YJBrb9130p1Pz9yDuGEsCIRzLQgbb_gA2XiHP7k_Xwg
|
|
|
1005
1004
|
hikyuu/indicator/pyind.py,sha256=dRWOUkidDOpozCdsTtj_84nuV4fdUKWcddGTC0mEbFk,1735
|
|
1006
1005
|
hikyuu/plugin/__init__.py,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
1007
1006
|
hikyuu/plugin/backtest.dll,sha256=10VG-p9USaTJLQaZ9cNaHpyAw7s5VdCwykfLQ6eyBkI,4465152
|
|
1008
|
-
hikyuu/plugin/clickhousedriver.dll,sha256=
|
|
1007
|
+
hikyuu/plugin/clickhousedriver.dll,sha256=gfuWRlcEpnWsapXrf1tlQ9_CkKySGANwLE3YdUp6Yi0,5471232
|
|
1009
1008
|
hikyuu/plugin/dataserver.dll,sha256=mK9cHZ5FtRfevn8WmwFQN2zFg4Fsv0WiW_G6EWJxGI0,5703680
|
|
1010
1009
|
hikyuu/plugin/dataserver_parquet.dll,sha256=8O2FTwtHBGM7jX8QC-XL6xPuWZZm5v2CM_OABCQ-Q_0,158208
|
|
1011
1010
|
hikyuu/plugin/device.dll,sha256=6ZtiWdUDi-JM7AqHi0EittYB1NisxdjBlPfWXYZb_LY,4520448
|
|
@@ -1074,8 +1073,8 @@ hikyuu/util/singleton.pyi,sha256=ZoxjflGbuN-4EV3XVXyH12LZwzUS4cEW_6Y7z2gGgG8,549
|
|
|
1074
1073
|
hikyuu/util/slice.py,sha256=ZPvGFc7MO3USnAS4ADMnjJaPqTRFV0nXY_ssgfysxJ4,1759
|
|
1075
1074
|
hikyuu/util/slice.pyi,sha256=9YS29Ehh3qbGC0F6Ieur25VcuftQL7C4c5nxmybWKHU,243
|
|
1076
1075
|
hikyuu/util/timeout.py,sha256=n1KdeXfXgh6fJKdrxmmL5PU6zIkeuVp1LKMwll8okDo,3031
|
|
1077
|
-
hikyuu-2.7.1.dist-info/METADATA,sha256=
|
|
1078
|
-
hikyuu-2.7.1.dist-info/WHEEL,sha256=ZjXRCNaQ9YSypEK2TE0LRB0sy2OVXSszb4Sx1XjM99k,97
|
|
1079
|
-
hikyuu-2.7.1.dist-info/entry_points.txt,sha256=lKAXjEs7kBs3KiRG88yAXos2X9L2-zQ_YQh0DsKE3kY,137
|
|
1080
|
-
hikyuu-2.7.1.dist-info/top_level.txt,sha256=ieLblpQ-NNGIAyuRrvvOuoi-Tsvt9mN1KE9T7KINpQE,4397
|
|
1081
|
-
hikyuu-2.7.1.dist-info/RECORD,,
|
|
1076
|
+
hikyuu-2.7.1.1.dist-info/METADATA,sha256=hv5hx966UIIJOYo52ZHRiTqxXKKLhuB21z_cG0Ez81Y,14137
|
|
1077
|
+
hikyuu-2.7.1.1.dist-info/WHEEL,sha256=ZjXRCNaQ9YSypEK2TE0LRB0sy2OVXSszb4Sx1XjM99k,97
|
|
1078
|
+
hikyuu-2.7.1.1.dist-info/entry_points.txt,sha256=lKAXjEs7kBs3KiRG88yAXos2X9L2-zQ_YQh0DsKE3kY,137
|
|
1079
|
+
hikyuu-2.7.1.1.dist-info/top_level.txt,sha256=ieLblpQ-NNGIAyuRrvvOuoi-Tsvt9mN1KE9T7KINpQE,4397
|
|
1080
|
+
hikyuu-2.7.1.1.dist-info/RECORD,,
|
hikyuu/data/pytdx_to_taos.py
DELETED
|
@@ -1,736 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/python
|
|
2
|
-
# -*- coding: utf8 -*-
|
|
3
|
-
#
|
|
4
|
-
# Create on: 2025-06-13
|
|
5
|
-
# Author: fasiondog
|
|
6
|
-
|
|
7
|
-
import sys
|
|
8
|
-
import math
|
|
9
|
-
import datetime
|
|
10
|
-
from pytdx.hq import TDXParams
|
|
11
|
-
|
|
12
|
-
from hikyuu.util.mylog import hku_error, hku_debug
|
|
13
|
-
|
|
14
|
-
from hikyuu import Datetime, UTCOffset, Days
|
|
15
|
-
from hikyuu.data.common import *
|
|
16
|
-
from hikyuu.data.common_pytdx import to_pytdx_market, pytdx_get_day_trans
|
|
17
|
-
from hikyuu.data.common_taos import (
|
|
18
|
-
create_database,
|
|
19
|
-
get_marketid,
|
|
20
|
-
get_codepre_list,
|
|
21
|
-
get_stock_list,
|
|
22
|
-
get_table,
|
|
23
|
-
get_lastdatetime,
|
|
24
|
-
get_last_krecord,
|
|
25
|
-
update_extern_data,
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
def ProgressBar(cur, total):
|
|
30
|
-
percent = "{:.0%}".format(cur / total)
|
|
31
|
-
sys.stdout.write("\r")
|
|
32
|
-
sys.stdout.write("[%-50s] %s" % ("=" * int(math.floor(cur * 50 / total)), percent))
|
|
33
|
-
sys.stdout.flush()
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@hku_catch(ret=0, trace=True)
|
|
37
|
-
def import_index_name(connect):
|
|
38
|
-
"""
|
|
39
|
-
导入所有指数代码表
|
|
40
|
-
|
|
41
|
-
:param connect: taos 连接对象
|
|
42
|
-
:return: 指数个数
|
|
43
|
-
"""
|
|
44
|
-
index_list = get_index_code_name_list()
|
|
45
|
-
if not index_list:
|
|
46
|
-
return 0
|
|
47
|
-
|
|
48
|
-
cur = connect.cursor()
|
|
49
|
-
cur.execute(
|
|
50
|
-
"select cast(stockid as bigint), market, code from hku_base.n_stock where type={}".format(
|
|
51
|
-
STOCKTYPE.INDEX
|
|
52
|
-
)
|
|
53
|
-
)
|
|
54
|
-
a = [v for v in cur]
|
|
55
|
-
oldStockDict = {}
|
|
56
|
-
for oldstock in a:
|
|
57
|
-
oldstockid = oldstock[0]
|
|
58
|
-
oldcode = f"{oldstock[1]}{oldstock[2]}"
|
|
59
|
-
oldStockDict[oldcode] = oldstockid
|
|
60
|
-
|
|
61
|
-
today = datetime.date.today()
|
|
62
|
-
today = today.year * 10000 + today.month * 100 + today.day
|
|
63
|
-
now_id = int(datetime.datetime.now().timestamp() * 1000)
|
|
64
|
-
count = 0
|
|
65
|
-
for index in index_list:
|
|
66
|
-
market_code = index["market_code"].upper()
|
|
67
|
-
stockid = oldStockDict[market_code] if market_code in oldStockDict else now_id + count
|
|
68
|
-
# print(stockid)
|
|
69
|
-
|
|
70
|
-
market = market_code[:2].upper()
|
|
71
|
-
sql = (
|
|
72
|
-
"insert into hku_base.n_stock (stockid, market, code, name, type, valid, startDate, endDate) \
|
|
73
|
-
values (%s, '%s', '%s', '%s', %s, %s, %s, %s)"
|
|
74
|
-
% (
|
|
75
|
-
stockid,
|
|
76
|
-
market,
|
|
77
|
-
index["market_code"][2:],
|
|
78
|
-
index["name"], # .encode('utf8').decode('utf8', 'ignore'),
|
|
79
|
-
STOCKTYPE.INDEX,
|
|
80
|
-
1,
|
|
81
|
-
today,
|
|
82
|
-
99999999,
|
|
83
|
-
)
|
|
84
|
-
)
|
|
85
|
-
count += 1
|
|
86
|
-
cur.execute(sql)
|
|
87
|
-
cur.close()
|
|
88
|
-
return len(index_list)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
@hku_catch(ret=0, trace=True)
|
|
92
|
-
def import_stock_name(connect, api, market, quotations=None):
|
|
93
|
-
"""更新每只股票的名称、当前是否有效性、起始日期及结束日期
|
|
94
|
-
如果导入的代码表中不存在对应的代码,则认为该股已失效
|
|
95
|
-
|
|
96
|
-
:param connect: sqlite3实例
|
|
97
|
-
:param api: pytdx接口,必须在函数外进行连接
|
|
98
|
-
:param market: 'SH' | 'SZ'
|
|
99
|
-
:param quotations: 待导入的行情类别,空为导入全部 'stock' | 'fund' | 'bond' | None
|
|
100
|
-
"""
|
|
101
|
-
cur = connect.cursor()
|
|
102
|
-
|
|
103
|
-
deSet = set() # 记录退市证券
|
|
104
|
-
if market == MARKET.SH:
|
|
105
|
-
df = ak.stock_info_sh_delist()
|
|
106
|
-
l = df[['公司代码', '公司简称']].to_dict(orient='records') if not df .empty else []
|
|
107
|
-
for stock in l:
|
|
108
|
-
code = str(stock['公司代码'])
|
|
109
|
-
deSet.add(code)
|
|
110
|
-
elif market == MARKET.SZ:
|
|
111
|
-
for t in ['暂停上市公司', '终止上市公司']:
|
|
112
|
-
df = ak.stock_info_sz_delist(t)
|
|
113
|
-
l = df[['证券代码', '证券简称']].to_dict(orient='records') if not df.empty else []
|
|
114
|
-
for stock in l:
|
|
115
|
-
code = str(stock['证券代码'])
|
|
116
|
-
deSet.add(code)
|
|
117
|
-
|
|
118
|
-
newStockDict = {}
|
|
119
|
-
stk_list = get_stk_code_name_list(market)
|
|
120
|
-
if not stk_list:
|
|
121
|
-
hku_error("获取 {} 股票代码表失败", market)
|
|
122
|
-
return 0
|
|
123
|
-
|
|
124
|
-
if not quotations or "fund" in [v.lower() for v in quotations]:
|
|
125
|
-
stk_list.extend(get_fund_code_name_list(market))
|
|
126
|
-
for stock in stk_list:
|
|
127
|
-
code = str(stock["code"])
|
|
128
|
-
if code not in deSet:
|
|
129
|
-
newStockDict[code] = stock["name"]
|
|
130
|
-
|
|
131
|
-
marketid = get_marketid(connect, market)
|
|
132
|
-
|
|
133
|
-
stktype_list = get_stktype_list(quotations)
|
|
134
|
-
stktype_list = list(stktype_list)
|
|
135
|
-
stktype_list.remove(STOCKTYPE.INDEX) # 移除指数类型
|
|
136
|
-
stktype_list = tuple(stktype_list)
|
|
137
|
-
cur.execute(
|
|
138
|
-
"select cast(stockid as bigint), market, code, name, type, valid, startDate, endDate from hku_base.n_stock where market='{}' and type in {}".format(
|
|
139
|
-
market.upper(), stktype_list
|
|
140
|
-
)
|
|
141
|
-
)
|
|
142
|
-
a = [v for v in cur]
|
|
143
|
-
oldStockDict = {}
|
|
144
|
-
for oldstock in a:
|
|
145
|
-
oldstockid, oldmarket, oldcode, oldname, oldtype, oldvalid, oldstartDate, oldendDate = oldstock
|
|
146
|
-
oldStockDict[oldcode] = oldstockid
|
|
147
|
-
|
|
148
|
-
# 新的代码表中无此股票,则置为无效
|
|
149
|
-
if (oldvalid == 1) and ((oldcode not in newStockDict) or oldcode in deSet):
|
|
150
|
-
cur.execute(
|
|
151
|
-
f"insert into hku_base.n_stock (stockid, market, code, name, type, valid, startDate, endDate) values ({oldstockid}, '{oldmarket}', '{oldcode}', '{oldname}', {oldtype}, 0, {oldstartDate}, {oldendDate})"
|
|
152
|
-
)
|
|
153
|
-
|
|
154
|
-
# 股票名称发生变化,更新股票名称;如果原无效,则置为有效
|
|
155
|
-
if oldcode in newStockDict:
|
|
156
|
-
if oldname != newStockDict[oldcode]:
|
|
157
|
-
cur.execute(
|
|
158
|
-
f"insert into hku_base.n_stock (stockid, market, code, name, type, valid, startDate, endDate) values ({oldstockid}, '{oldmarket}', '{oldcode}', '{newStockDict[oldcode]}', {oldtype}, {oldvalid}, {oldstartDate}, {oldendDate})")
|
|
159
|
-
if oldvalid == 0:
|
|
160
|
-
cur.execute(
|
|
161
|
-
f"insert into hku_base.n_stock (stockid, market, code, name, type, valid, startDate, endDate) values ({oldstockid}, '{oldmarket}', '{oldcode}', '{oldname}', {oldtype}, 1, {oldstartDate}, 99999999)")
|
|
162
|
-
|
|
163
|
-
# 处理新出现的股票
|
|
164
|
-
codepre_list = get_codepre_list(connect, marketid, quotations)
|
|
165
|
-
|
|
166
|
-
today = datetime.date.today()
|
|
167
|
-
today = today.year * 10000 + today.month * 100 + today.day
|
|
168
|
-
now_id = int(datetime.datetime.now().timestamp() * 1000)
|
|
169
|
-
count = 0
|
|
170
|
-
for code in newStockDict:
|
|
171
|
-
if code not in oldStockDict:
|
|
172
|
-
for codepre in codepre_list:
|
|
173
|
-
length = len(codepre[0])
|
|
174
|
-
if code[:length] == codepre[0]:
|
|
175
|
-
# print(market, code, newStockDict[code], codepre)
|
|
176
|
-
sql = (
|
|
177
|
-
"insert into `hku_base`.`n_stock` (stockid, market, code, name, type, valid, startDate, endDate) \
|
|
178
|
-
values (%s, '%s', '%s', '%s', %s, %s, %s, %s)"
|
|
179
|
-
% (
|
|
180
|
-
now_id + count,
|
|
181
|
-
market,
|
|
182
|
-
code,
|
|
183
|
-
newStockDict[code],
|
|
184
|
-
codepre[1],
|
|
185
|
-
1,
|
|
186
|
-
today,
|
|
187
|
-
99999999,
|
|
188
|
-
)
|
|
189
|
-
)
|
|
190
|
-
cur.execute(sql)
|
|
191
|
-
count += 1
|
|
192
|
-
break
|
|
193
|
-
|
|
194
|
-
# print('%s新增股票数:%i' % (market.upper(), count))
|
|
195
|
-
cur.close()
|
|
196
|
-
return count
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
def guess_day_n_step(last_datetime):
|
|
200
|
-
last_date = int(last_datetime // 10000)
|
|
201
|
-
today = datetime.date.today()
|
|
202
|
-
|
|
203
|
-
last_y = last_date // 10000
|
|
204
|
-
n = int((today.year - last_y + 1) * 250 // 800)
|
|
205
|
-
|
|
206
|
-
step = 800
|
|
207
|
-
if n < 1:
|
|
208
|
-
last_m = last_date // 100 - last_y * 100
|
|
209
|
-
last_d = last_date - (last_y * 10000 + last_m * 100)
|
|
210
|
-
step = (today - datetime.date(last_y, last_m, last_d)).days + 1
|
|
211
|
-
if step > 800:
|
|
212
|
-
n = 1
|
|
213
|
-
step = 800
|
|
214
|
-
|
|
215
|
-
return (n, step)
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
def guess_1min_n_step(last_datetime):
|
|
219
|
-
last_date = int(last_datetime // 10000)
|
|
220
|
-
today = datetime.date.today()
|
|
221
|
-
|
|
222
|
-
last_y = last_date // 10000
|
|
223
|
-
last_m = last_date // 100 - last_y * 100
|
|
224
|
-
last_d = last_date - (last_y * 10000 + last_m * 100)
|
|
225
|
-
|
|
226
|
-
n = int(((today - datetime.date(last_y, last_m, last_d)).days * 240 + 1) // 800)
|
|
227
|
-
step = 800
|
|
228
|
-
if n < 1:
|
|
229
|
-
step = (today - datetime.date(last_y, last_m, last_d)).days * 240 + 1
|
|
230
|
-
elif n > 99:
|
|
231
|
-
n = 99
|
|
232
|
-
|
|
233
|
-
return (n, step)
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
def guess_5min_n_step(last_datetime):
|
|
237
|
-
last_date = int(last_datetime // 10000)
|
|
238
|
-
today = datetime.date.today()
|
|
239
|
-
|
|
240
|
-
last_y = last_date // 10000
|
|
241
|
-
last_m = last_date // 100 - last_y * 100
|
|
242
|
-
last_d = last_date - (last_y * 10000 + last_m * 100)
|
|
243
|
-
|
|
244
|
-
n = int(((today - datetime.date(last_y, last_m, last_d)).days * 48 + 1) // 800)
|
|
245
|
-
step = 800
|
|
246
|
-
if n < 1:
|
|
247
|
-
step = (today - datetime.date(last_y, last_m, last_d)).days * 48 + 1
|
|
248
|
-
elif n > 99:
|
|
249
|
-
n = 99
|
|
250
|
-
|
|
251
|
-
return (n, step)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
def import_one_stock_data(
|
|
255
|
-
connect, api, market, ktype, stock_record, startDate=199012191500
|
|
256
|
-
):
|
|
257
|
-
market = market.upper()
|
|
258
|
-
pytdx_market = to_pytdx_market(market)
|
|
259
|
-
|
|
260
|
-
# stockid, market, code, name, type, valid, startDate, endDate
|
|
261
|
-
stockid, market, code, name, stktype, valid, stk_startDate, stk_endDate = stock_record
|
|
262
|
-
hku_debug("{}{}".format(market, code))
|
|
263
|
-
table = get_table(connect, market, code, ktype)
|
|
264
|
-
|
|
265
|
-
last_krecord = get_last_krecord(connect, table)
|
|
266
|
-
last_datetime = startDate if last_krecord is None else last_krecord[0].ymdhm
|
|
267
|
-
|
|
268
|
-
today = datetime.date.today()
|
|
269
|
-
if ktype == "DAY":
|
|
270
|
-
nktype = "day"
|
|
271
|
-
n, step = guess_day_n_step(last_datetime)
|
|
272
|
-
pytdx_kline_type = TDXParams.KLINE_TYPE_RI_K
|
|
273
|
-
today_datetime = (today.year * 10000 + today.month * 100 + today.day) * 10000
|
|
274
|
-
|
|
275
|
-
elif ktype == "1MIN":
|
|
276
|
-
nktype = "min"
|
|
277
|
-
n, step = guess_1min_n_step(last_datetime)
|
|
278
|
-
pytdx_kline_type = TDXParams.KLINE_TYPE_1MIN
|
|
279
|
-
today_datetime = (
|
|
280
|
-
today.year * 10000 + today.month * 100 + today.day
|
|
281
|
-
) * 10000 + 1500
|
|
282
|
-
|
|
283
|
-
elif ktype == "5MIN":
|
|
284
|
-
nktype = "min5"
|
|
285
|
-
n, step = guess_5min_n_step(last_datetime)
|
|
286
|
-
pytdx_kline_type = TDXParams.KLINE_TYPE_5MIN
|
|
287
|
-
today_datetime = (
|
|
288
|
-
today.year * 10000 + today.month * 100 + today.day
|
|
289
|
-
) * 10000 + 1500
|
|
290
|
-
else:
|
|
291
|
-
return 0
|
|
292
|
-
|
|
293
|
-
if today_datetime <= last_datetime:
|
|
294
|
-
return 0
|
|
295
|
-
|
|
296
|
-
get_bars = (
|
|
297
|
-
api.get_index_bars if stktype == STOCKTYPE.INDEX else api.get_security_bars
|
|
298
|
-
)
|
|
299
|
-
|
|
300
|
-
if last_krecord is not None:
|
|
301
|
-
if ktype == 'DAY':
|
|
302
|
-
days = (Datetime.today() - last_krecord[0]).days
|
|
303
|
-
num = days + 1
|
|
304
|
-
elif ktype == '1MIN':
|
|
305
|
-
days = (Datetime.today() - last_krecord[0].start_of_day()).days
|
|
306
|
-
num = days*240+1
|
|
307
|
-
elif ktype == '5MIN':
|
|
308
|
-
days = (Datetime.today() - last_krecord[0].start_of_day()).days
|
|
309
|
-
num = days*48+1
|
|
310
|
-
if num >= 1:
|
|
311
|
-
bars = get_bars(pytdx_kline_type, pytdx_market, code, 0, num)
|
|
312
|
-
if not bars:
|
|
313
|
-
return 0
|
|
314
|
-
bar = bars[-1]
|
|
315
|
-
if ktype == 'DAY':
|
|
316
|
-
bardate = Datetime(bar["year"], bar["month"], bar["day"])
|
|
317
|
-
else:
|
|
318
|
-
bardate = Datetime(bar["year"], bar["month"], bar["day"], bar['hour'], bar['minute'])
|
|
319
|
-
if last_krecord[0] == bardate:
|
|
320
|
-
if abs(last_krecord[1] - bar["open"]) / last_krecord[1] > 0.02:
|
|
321
|
-
hku_error(
|
|
322
|
-
f"fetch data from tdx error! {bardate} {ktype} {market}{code} last_krecord: {last_krecord[1]}, bar: {bar['open']}")
|
|
323
|
-
return 0
|
|
324
|
-
if abs(last_krecord[2] - bar["high"]) / last_krecord[2] > 0.02:
|
|
325
|
-
hku_error(
|
|
326
|
-
f"fetch data from tdx error! {bardate} {ktype} {market}{code} last_krecord: {last_krecord[2]}, bar: {bar['high']}")
|
|
327
|
-
return 0
|
|
328
|
-
if abs(last_krecord[3] - bar["low"]) / last_krecord[3] > 0.02:
|
|
329
|
-
hku_error(
|
|
330
|
-
f"fetch data from tdx error! {bardate} {ktype} {market}{code} last_krecord: {last_krecord[3]}, bar: {bar['low']}")
|
|
331
|
-
return 0
|
|
332
|
-
if abs(last_krecord[4] - bar["close"]) / last_krecord[4] > 0.02:
|
|
333
|
-
hku_error(
|
|
334
|
-
f"fetch data from tdx error! {bardate} {ktype} {market}{code} last_krecord: {last_krecord[4]}, bar: {bar['close']}")
|
|
335
|
-
return 0
|
|
336
|
-
if ktype == 'DAY' and last_krecord[5] != 0.0 and abs(last_krecord[5] - bar["amount"]*0.001) / last_krecord[5] > 0.1:
|
|
337
|
-
hku_error(
|
|
338
|
-
f"fetch data from tdx error! {bardate} {ktype} {market}{code} last_krecord: {last_krecord[5]}, bar: {bar['amount']*0.001}")
|
|
339
|
-
return 0
|
|
340
|
-
if ktype == 'DAY' and last_krecord[5] != 0.0 and abs(last_krecord[6] - bar["vol"]) / last_krecord[6] > 0.1:
|
|
341
|
-
hku_error(
|
|
342
|
-
f"fetch data from tdx error! {bardate} {ktype} {market}{code} last_krecord: {last_krecord[6]}, bar: {bar['vol']}")
|
|
343
|
-
return 0
|
|
344
|
-
|
|
345
|
-
buf = []
|
|
346
|
-
while n >= 0:
|
|
347
|
-
bar_list = get_bars(pytdx_kline_type, pytdx_market, code, n * 800, step)
|
|
348
|
-
n -= 1
|
|
349
|
-
if bar_list is None:
|
|
350
|
-
# print(code, "invalid!!")
|
|
351
|
-
continue
|
|
352
|
-
|
|
353
|
-
for bar in bar_list:
|
|
354
|
-
try:
|
|
355
|
-
if ktype == "DAY":
|
|
356
|
-
tmp = datetime.date(bar["year"], bar["month"], bar["day"])
|
|
357
|
-
bar_datetime = (tmp.year * 10000 + tmp.month * 100 + tmp.day) * 10000
|
|
358
|
-
else:
|
|
359
|
-
tmp = datetime.datetime(bar["year"], bar["month"], bar["day"], bar['hour'], bar['minute'])
|
|
360
|
-
bar_datetime = (tmp.year * 10000 + tmp.month * 100 + tmp.day) * \
|
|
361
|
-
10000 + bar["hour"] * 100 + bar["minute"]
|
|
362
|
-
except Exception as e:
|
|
363
|
-
hku_error("Failed translate datetime: {}, from {}! {}".format(bar, api.ip, e))
|
|
364
|
-
continue
|
|
365
|
-
|
|
366
|
-
if last_krecord is not None and bar_datetime == last_datetime:
|
|
367
|
-
if abs(last_krecord[1] - bar["open"]) / last_krecord[1] > 0.02:
|
|
368
|
-
hku_error(
|
|
369
|
-
f"fetch data from tdx error! {bardate} {ktype} {market}{code} last_krecord: {last_krecord[1]}, bar: {bar['open']}")
|
|
370
|
-
return 0
|
|
371
|
-
if abs(last_krecord[2] - bar["high"]) / last_krecord[2] > 0.02:
|
|
372
|
-
hku_error(
|
|
373
|
-
f"fetch data from tdx error! {bardate} {ktype} {market}{code} last_krecord: {last_krecord[2]}, bar: {bar['high']}")
|
|
374
|
-
return 0
|
|
375
|
-
if abs(last_krecord[3] - bar["low"]) / last_krecord[3] > 0.02:
|
|
376
|
-
hku_error(
|
|
377
|
-
f"fetch data from tdx error! {bardate} {ktype} {market}{code} last_krecord: {last_krecord[3]}, bar: {bar['low']}")
|
|
378
|
-
return 0
|
|
379
|
-
if abs(last_krecord[4] - bar["close"]) / last_krecord[4] > 0.02:
|
|
380
|
-
hku_error(
|
|
381
|
-
f"fetch data from tdx error! {bardate} {ktype} {market}{code} last_krecord: {last_krecord[4]}, bar: {bar['close']}")
|
|
382
|
-
return 0
|
|
383
|
-
if ktype == 'DAY' and last_krecord[5] != 0.0 and abs(last_krecord[5] - bar["amount"]*0.001) / last_krecord[5] > 0.1:
|
|
384
|
-
hku_error(
|
|
385
|
-
f"fetch data from tdx error! {bardate} {ktype} {market}{code} last_krecord: {last_krecord[5]}, bar: {bar['amount']*0.001}")
|
|
386
|
-
return 0
|
|
387
|
-
if ktype == 'DAY' and last_krecord[5] != 0.0 and abs(last_krecord[6] - bar["vol"]) / last_krecord[6] > 0.1:
|
|
388
|
-
hku_error(
|
|
389
|
-
f"fetch data from tdx error! {bardate} {ktype} {market}{code} last_krecord: {last_krecord[6]}, bar: {bar['vol']}")
|
|
390
|
-
return 0
|
|
391
|
-
continue
|
|
392
|
-
|
|
393
|
-
if (
|
|
394
|
-
today_datetime >= bar_datetime > last_datetime
|
|
395
|
-
and bar["high"] >= bar["open"] >= bar["low"] > 0
|
|
396
|
-
and bar["high"] >= bar["close"] >= bar["low"] > 0
|
|
397
|
-
and bar["vol"] >= 0
|
|
398
|
-
and bar["amount"] >= 0
|
|
399
|
-
):
|
|
400
|
-
try:
|
|
401
|
-
buf.append(
|
|
402
|
-
(
|
|
403
|
-
bar_datetime,
|
|
404
|
-
bar["open"],
|
|
405
|
-
bar["high"],
|
|
406
|
-
bar["low"],
|
|
407
|
-
bar["close"],
|
|
408
|
-
bar["amount"] * 0.001,
|
|
409
|
-
bar["vol"]
|
|
410
|
-
# bar['vol'] if stktype == 2 else round(bar['vol'] * 0.01)
|
|
411
|
-
)
|
|
412
|
-
)
|
|
413
|
-
except Exception as e:
|
|
414
|
-
hku_error("Can't trans record({}), {}".format(bar, e))
|
|
415
|
-
last_datetime = bar_datetime
|
|
416
|
-
|
|
417
|
-
if len(buf) > 0:
|
|
418
|
-
cur = connect.cursor()
|
|
419
|
-
rawsql = f"INSERT INTO {table} using {nktype}_data.kdata TAGS ('{market.upper()}', '{code}') VALUES "
|
|
420
|
-
sql = rawsql
|
|
421
|
-
for i, r in enumerate(buf):
|
|
422
|
-
sql += f"({(Datetime(r[0])-UTCOffset()).timestamp()}, {r[1]}, {r[2]}, {r[3]}, {r[4]}, {r[5]}, {r[6]})"
|
|
423
|
-
if i > 0 and i % 8000 == 0:
|
|
424
|
-
cur.execute(sql)
|
|
425
|
-
sql = rawsql
|
|
426
|
-
if sql != rawsql:
|
|
427
|
-
cur.execute(sql)
|
|
428
|
-
|
|
429
|
-
if ktype == "DAY":
|
|
430
|
-
# 更新基础信息数据库中股票对应的起止日期及其有效标志
|
|
431
|
-
# stockid, market, code, name, type, valid, startDate, endDate
|
|
432
|
-
cur.execute(f"select FIRST(date) from {table}")
|
|
433
|
-
a = [v for v in cur]
|
|
434
|
-
first_date = Datetime(a[0][0]).ymd
|
|
435
|
-
sql = f"INSERT INTO hku_base.n_stock (stockid, market, code, name, type, valid, startDate, endDate) VALUES ({stockid}, '{market.upper()}', '{code}', '{name}', {stktype}, 1, {first_date}, {stk_endDate})"
|
|
436
|
-
# print(sql)
|
|
437
|
-
cur.execute(sql)
|
|
438
|
-
|
|
439
|
-
# 记录最新更新日期
|
|
440
|
-
if (
|
|
441
|
-
(code == "000001" and market == MARKET.SH)
|
|
442
|
-
or (code == "399001" and market == MARKET.SZ)
|
|
443
|
-
or (code == "830799" and market == MARKET.BJ)
|
|
444
|
-
):
|
|
445
|
-
cur.execute(f"select cast(id as bigint) from hku_base.n_market where market='{market.upper()}'")
|
|
446
|
-
a = [v for v in cur]
|
|
447
|
-
id = a[0][0]
|
|
448
|
-
sql = f"INSERT INTO hku_base.n_market (id, lastdate) VALUES ({id}, {buf[-1][0]//10000})"
|
|
449
|
-
# print(sql)
|
|
450
|
-
cur.execute(sql)
|
|
451
|
-
cur.close()
|
|
452
|
-
|
|
453
|
-
return len(buf)
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
@hku_catch(trace=True, re_raise=True)
|
|
457
|
-
def import_data(
|
|
458
|
-
connect,
|
|
459
|
-
market,
|
|
460
|
-
ktype,
|
|
461
|
-
quotations,
|
|
462
|
-
api,
|
|
463
|
-
dest_dir=None,
|
|
464
|
-
startDate=199012190000,
|
|
465
|
-
progress=ProgressBar,
|
|
466
|
-
):
|
|
467
|
-
"""导入通达信指定盘后数据路径中的K线数据。注:只导入基础信息数据库中存在的股票。
|
|
468
|
-
|
|
469
|
-
:param connect : sqlit3链接
|
|
470
|
-
:param market : 'SH' | 'SZ'
|
|
471
|
-
:param ktype : 'DAY' | '1MIN' | '5MIN'
|
|
472
|
-
:param quotations: 'stock' | 'fund' | 'bond'
|
|
473
|
-
:param src_dir : 盘后K线数据路径,如上证5分钟线:D:\\Tdx\\vipdoc\\sh\\fzline
|
|
474
|
-
:param dest_dir : HDF5数据文件所在目录
|
|
475
|
-
:param progress : 进度显示函数
|
|
476
|
-
:return: 导入记录数
|
|
477
|
-
"""
|
|
478
|
-
add_record_count = 0
|
|
479
|
-
market = market.upper()
|
|
480
|
-
|
|
481
|
-
# stockid, marketid, code, name, type, valid, startDate, endDate
|
|
482
|
-
stock_list = get_stock_list(connect, market, quotations)
|
|
483
|
-
|
|
484
|
-
total = len(stock_list)
|
|
485
|
-
for i, stock in enumerate(stock_list):
|
|
486
|
-
if stock[5] == 0 or len(stock[2]) != 6:
|
|
487
|
-
if progress:
|
|
488
|
-
progress(i, total)
|
|
489
|
-
continue
|
|
490
|
-
|
|
491
|
-
this_count = import_one_stock_data(
|
|
492
|
-
connect, api, market, ktype, stock, startDate
|
|
493
|
-
)
|
|
494
|
-
add_record_count += this_count
|
|
495
|
-
if this_count > 0:
|
|
496
|
-
if ktype == "DAY":
|
|
497
|
-
update_extern_data(connect, market.upper(), stock[2], "DAY")
|
|
498
|
-
elif ktype == "5MIN":
|
|
499
|
-
update_extern_data(connect, market.upper(), stock[2], "5MIN")
|
|
500
|
-
|
|
501
|
-
if progress:
|
|
502
|
-
progress(i, total)
|
|
503
|
-
|
|
504
|
-
connect.commit()
|
|
505
|
-
return add_record_count
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
@hku_catch(trace=True)
|
|
509
|
-
def import_on_stock_trans(connect, api, market, stock_record, max_days):
|
|
510
|
-
market = market.upper()
|
|
511
|
-
pytdx_market = to_pytdx_market(market)
|
|
512
|
-
|
|
513
|
-
# stockid, marketid, code, name, type, valid, startDate, endDate
|
|
514
|
-
stockid, marketid, code, name, stktype, valid = stock_record[:6]
|
|
515
|
-
hku_debug("{}{}".format(market, code))
|
|
516
|
-
table = get_table(connect, market, code, 'transdata')
|
|
517
|
-
last_datetime = get_lastdatetime(connect, table)
|
|
518
|
-
|
|
519
|
-
today = Datetime.today()
|
|
520
|
-
if last_datetime is not None:
|
|
521
|
-
# yyyymmddHHMMSS
|
|
522
|
-
last_date = last_datetime.start_of_day()
|
|
523
|
-
need_days = (today - last_date).days
|
|
524
|
-
else:
|
|
525
|
-
need_days = max_days
|
|
526
|
-
|
|
527
|
-
date_list = []
|
|
528
|
-
for i in range(need_days):
|
|
529
|
-
cur_date = today - Days(i)
|
|
530
|
-
if cur_date.day_of_week not in (0, 6):
|
|
531
|
-
date_list.append(cur_date.ymd)
|
|
532
|
-
date_list.reverse()
|
|
533
|
-
|
|
534
|
-
trans_buf = []
|
|
535
|
-
for cur_date in date_list:
|
|
536
|
-
buf = pytdx_get_day_trans(api, pytdx_market, code, cur_date)
|
|
537
|
-
if not buf:
|
|
538
|
-
continue
|
|
539
|
-
|
|
540
|
-
second = 2
|
|
541
|
-
pre_minute = 900
|
|
542
|
-
|
|
543
|
-
for record in buf:
|
|
544
|
-
try:
|
|
545
|
-
minute = int(record["time"][0:2]) * 100 + int(record["time"][3:])
|
|
546
|
-
if minute != pre_minute:
|
|
547
|
-
second = 0 if minute == 1500 else 2
|
|
548
|
-
pre_minute = minute
|
|
549
|
-
else:
|
|
550
|
-
second += 3
|
|
551
|
-
if second > 59:
|
|
552
|
-
continue
|
|
553
|
-
|
|
554
|
-
trans_buf.append(
|
|
555
|
-
(
|
|
556
|
-
cur_date * 1000000 + minute * 100 + second,
|
|
557
|
-
record["price"],
|
|
558
|
-
record["vol"],
|
|
559
|
-
record["buyorsell"],
|
|
560
|
-
)
|
|
561
|
-
)
|
|
562
|
-
except Exception as e:
|
|
563
|
-
hku_error("Failed trans to record! {}", e)
|
|
564
|
-
|
|
565
|
-
if trans_buf:
|
|
566
|
-
cur = connect.cursor()
|
|
567
|
-
rawsql = f"INSERT INTO {table} using transdata_data.transdata TAGS ('{market.upper()}', '{code}') VALUES "
|
|
568
|
-
sql = rawsql
|
|
569
|
-
for i, r in enumerate(trans_buf):
|
|
570
|
-
sql += f"({(Datetime(r[0])-UTCOffset()).timestamp()}, {r[1]}, {r[2]}, {r[3]})"
|
|
571
|
-
if i > 0 and i % 15000 == 0:
|
|
572
|
-
cur.execute(sql)
|
|
573
|
-
sql = rawsql
|
|
574
|
-
if sql != rawsql:
|
|
575
|
-
cur.execute(sql)
|
|
576
|
-
cur.close()
|
|
577
|
-
return len(trans_buf)
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
def import_trans(
|
|
581
|
-
connect, market, quotations, api, dest_dir=None, max_days=30, progress=ProgressBar
|
|
582
|
-
):
|
|
583
|
-
add_record_count = 0
|
|
584
|
-
market = market.upper()
|
|
585
|
-
|
|
586
|
-
stock_list = get_stock_list(connect, market, quotations)
|
|
587
|
-
total = len(stock_list)
|
|
588
|
-
a_stktype_list = get_a_stktype_list()
|
|
589
|
-
for i, stock in enumerate(stock_list):
|
|
590
|
-
# stockid, marketid, code, name, type, valid, startDate, endDate
|
|
591
|
-
if stock[5] == 0 or len(stock[2]) != 6 or stock[4] not in a_stktype_list:
|
|
592
|
-
if progress:
|
|
593
|
-
progress(i, total)
|
|
594
|
-
continue
|
|
595
|
-
|
|
596
|
-
this_count = import_on_stock_trans(connect, api, market, stock, max_days)
|
|
597
|
-
add_record_count += this_count
|
|
598
|
-
if progress:
|
|
599
|
-
progress(i, total)
|
|
600
|
-
|
|
601
|
-
return add_record_count
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
@hku_catch(trace=True)
|
|
605
|
-
def import_on_stock_time(connect, api, market, stock_record, max_days):
|
|
606
|
-
market = market.upper()
|
|
607
|
-
pytdx_market = to_pytdx_market(market)
|
|
608
|
-
|
|
609
|
-
# stockid, marketid, code, name, type, valid, startDate, endDate
|
|
610
|
-
stockid, marketid, code, name, stktype, valid = stock_record[:6]
|
|
611
|
-
hku_debug("{}{}".format(market, code))
|
|
612
|
-
table = get_table(connect, market, code, 'timeline')
|
|
613
|
-
last_datetime = get_lastdatetime(connect, table)
|
|
614
|
-
|
|
615
|
-
today = Datetime.today()
|
|
616
|
-
if last_datetime is not None:
|
|
617
|
-
# yyyymmddHHMM
|
|
618
|
-
last_date = last_datetime.start_of_day()
|
|
619
|
-
need_days = (today - last_date).days
|
|
620
|
-
else:
|
|
621
|
-
need_days = max_days
|
|
622
|
-
|
|
623
|
-
date_list = []
|
|
624
|
-
for i in range(need_days):
|
|
625
|
-
cur_date = today - Days(i)
|
|
626
|
-
if cur_date.day_of_week() not in (0, 6):
|
|
627
|
-
date_list.append(cur_date.ymd)
|
|
628
|
-
date_list.reverse()
|
|
629
|
-
|
|
630
|
-
time_buf = []
|
|
631
|
-
for cur_date in date_list:
|
|
632
|
-
buf = api.get_history_minute_time_data(pytdx_market, code, cur_date)
|
|
633
|
-
if buf is None or len(buf) != 240:
|
|
634
|
-
# print(cur_date, "获取的分时线长度不为240!", stock_record[1], stock_record[2])
|
|
635
|
-
continue
|
|
636
|
-
this_date = cur_date * 10000
|
|
637
|
-
time = 930
|
|
638
|
-
for record in buf:
|
|
639
|
-
if time == 960:
|
|
640
|
-
time = 1000
|
|
641
|
-
elif time == 1060:
|
|
642
|
-
time = 1100
|
|
643
|
-
elif time == 1130:
|
|
644
|
-
time = 1300
|
|
645
|
-
elif time == 1360:
|
|
646
|
-
time = 1400
|
|
647
|
-
try:
|
|
648
|
-
time_buf.append((this_date + time, record['price'], record['vol']))
|
|
649
|
-
time += 1
|
|
650
|
-
except Exception as e:
|
|
651
|
-
hku_error("Failed trans record {}! {}".format(record, e))
|
|
652
|
-
|
|
653
|
-
if time_buf:
|
|
654
|
-
cur = connect.cursor()
|
|
655
|
-
rawsql = f"INSERT INTO {table} using timeline_data.timeline TAGS ('{market.upper()}', '{code}') VALUES "
|
|
656
|
-
sql = rawsql
|
|
657
|
-
for i, r in enumerate(time_buf):
|
|
658
|
-
sql += f"({(Datetime(r[0])-UTCOffset()).timestamp()}, {r[1]}, {r[2]})"
|
|
659
|
-
if i > 0 and i % 16000 == 0:
|
|
660
|
-
cur.execute(sql)
|
|
661
|
-
sql = rawsql
|
|
662
|
-
if sql != rawsql:
|
|
663
|
-
cur.execute(sql)
|
|
664
|
-
cur.close()
|
|
665
|
-
|
|
666
|
-
return len(time_buf)
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
def import_time(connect, market, quotations, api, dest_dir=None, max_days=9000, progress=ProgressBar):
|
|
670
|
-
add_record_count = 0
|
|
671
|
-
market = market.upper()
|
|
672
|
-
|
|
673
|
-
stock_list = get_stock_list(connect, market, quotations)
|
|
674
|
-
total = len(stock_list)
|
|
675
|
-
for i, stock in enumerate(stock_list):
|
|
676
|
-
# stockid, marketid, code, name, type, valid, startDate, endDate
|
|
677
|
-
if stock[5] == 0 or len(stock[2]) != 6:
|
|
678
|
-
if progress:
|
|
679
|
-
progress(i, total)
|
|
680
|
-
continue
|
|
681
|
-
|
|
682
|
-
this_count = import_on_stock_time(connect, api, market, stock, max_days)
|
|
683
|
-
add_record_count += this_count
|
|
684
|
-
if progress:
|
|
685
|
-
progress(i, total)
|
|
686
|
-
|
|
687
|
-
return add_record_count
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
if __name__ == '__main__':
|
|
691
|
-
import os
|
|
692
|
-
from configparser import ConfigParser
|
|
693
|
-
dev_config = ConfigParser()
|
|
694
|
-
dev_config.read(os.path.expanduser("~") + '/workspace/dev.ini')
|
|
695
|
-
db = 'taos54'
|
|
696
|
-
user = dev_config.get(db, 'user')
|
|
697
|
-
password = dev_config.get(db, 'pwd')
|
|
698
|
-
host = dev_config.get(db, 'host')
|
|
699
|
-
port = dev_config.getint(db, 'port')
|
|
700
|
-
|
|
701
|
-
tdx_server = '180.101.48.170'
|
|
702
|
-
tdx_port = 7709
|
|
703
|
-
|
|
704
|
-
from pytdx.hq import TdxHq_API, TDXParams
|
|
705
|
-
|
|
706
|
-
api = TdxHq_API()
|
|
707
|
-
api.connect(tdx_server, tdx_port)
|
|
708
|
-
|
|
709
|
-
from hikyuu.data.common_taos import get_taos
|
|
710
|
-
connect = get_taos().connect(
|
|
711
|
-
user=user, password=password, host=host, port=port)
|
|
712
|
-
|
|
713
|
-
# import_index_name(connect)
|
|
714
|
-
|
|
715
|
-
# import_stock_name(connect, None, MARKET.SH, None)
|
|
716
|
-
|
|
717
|
-
quotations = ["stock", "fund"]
|
|
718
|
-
|
|
719
|
-
stock_list = get_stock_list(connect, "SH", quotations)
|
|
720
|
-
stock_record = None
|
|
721
|
-
for r in stock_list:
|
|
722
|
-
if r[2] == "000001":
|
|
723
|
-
stock_record = r
|
|
724
|
-
break
|
|
725
|
-
print(stock_record)
|
|
726
|
-
|
|
727
|
-
import_one_stock_data(connect, api, "SH", "5MIN", stock_record, startDate=199012191500)
|
|
728
|
-
|
|
729
|
-
# print("\n导入上证日线数据")
|
|
730
|
-
# add_count = import_data(connect, "SH", "DAY", quotations, api, progress=ProgressBar)
|
|
731
|
-
# print("\n导入数量:", add_count)
|
|
732
|
-
|
|
733
|
-
# import_time(connect, "SH", quotations, api, max_days=30)
|
|
734
|
-
|
|
735
|
-
api.disconnect()
|
|
736
|
-
connect.close()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|