hikyuu 2.5.3__py3-none-win_amd64.whl → 2.5.6__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/__init__.pyi +514 -514
- hikyuu/analysis/__init__.pyi +490 -489
- hikyuu/analysis/analysis.pyi +491 -490
- hikyuu/core.pyi +492 -491
- hikyuu/cpp/__init__.pyi +2 -2
- hikyuu/cpp/core310.pyd +0 -0
- hikyuu/cpp/core310.pyi +21 -2
- hikyuu/cpp/core311.pyd +0 -0
- hikyuu/cpp/core311.pyi +21 -2
- hikyuu/cpp/core312.pyd +0 -0
- hikyuu/cpp/core312.pyi +21 -2
- hikyuu/cpp/core313.pyd +0 -0
- hikyuu/cpp/core313.pyi +21 -2
- hikyuu/cpp/core38.pyd +0 -0
- hikyuu/cpp/core38.pyi +21 -2
- hikyuu/cpp/core39.pyd +0 -0
- hikyuu/cpp/core39.pyi +21 -2
- hikyuu/cpp/hikyuu.dll +0 -0
- hikyuu/cpp/hikyuu.lib +0 -0
- hikyuu/cpp/sqlite3.dll +0 -0
- hikyuu/data/tdx_to_mysql.py +15 -15
- hikyuu/draw/__init__.pyi +1 -1
- hikyuu/draw/drawplot/__init__.pyi +9 -9
- hikyuu/draw/drawplot/bokeh_draw.pyi +505 -505
- hikyuu/draw/drawplot/common.pyi +1 -1
- hikyuu/draw/drawplot/echarts_draw.pyi +507 -507
- hikyuu/draw/drawplot/matplotlib_draw.pyi +516 -516
- hikyuu/draw/elder.pyi +11 -11
- hikyuu/draw/kaufman.pyi +18 -18
- hikyuu/draw/volume.pyi +10 -10
- hikyuu/extend.pyi +500 -500
- hikyuu/fetcher/stock/zh_block_em.py +18 -7
- hikyuu/gui/data/UseTdxImportToH5Thread.py +2 -2
- hikyuu/hub.py +7 -13
- hikyuu/hub.pyi +9 -6
- hikyuu/include/hikyuu/indicator/crt/BARSSINCE.h +14 -2
- hikyuu/include/hikyuu/indicator/imp/IBarsSince.h +6 -0
- hikyuu/include/hikyuu/utilities/config.h +1 -1
- hikyuu/include/hikyuu/utilities/datetime/Datetime.h +4 -3
- hikyuu/include/hikyuu/utilities/datetime/TimeDelta.h +8 -0
- hikyuu/include/hikyuu/utilities/plugin/PluginBase.h +47 -0
- hikyuu/include/hikyuu/utilities/plugin/PluginClient.h +55 -0
- hikyuu/include/hikyuu/utilities/plugin/PluginLoader.h +64 -0
- hikyuu/include/hikyuu/utilities/plugin/__init__.py +1 -0
- hikyuu/include/hikyuu/utilities/thread/MQStealThreadPool.h +1 -1
- hikyuu/include/hikyuu/utilities/thread/MQThreadPool.h +1 -1
- hikyuu/include/hikyuu/utilities/thread/StealThreadPool.h +1 -1
- hikyuu/include/hikyuu/utilities/thread/ThreadPool.h +1 -1
- hikyuu/include/hikyuu/version.h +4 -4
- hikyuu/indicator/indicator.py +1 -1
- hikyuu/trade_manage/__init__.pyi +505 -505
- hikyuu/trade_manage/broker.pyi +3 -3
- hikyuu/trade_manage/broker_easytrader.pyi +1 -1
- hikyuu/trade_manage/trade.pyi +505 -505
- hikyuu/util/singleton.pyi +1 -1
- {hikyuu-2.5.3.dist-info → hikyuu-2.5.6.dist-info}/METADATA +1 -1
- {hikyuu-2.5.3.dist-info → hikyuu-2.5.6.dist-info}/RECORD +61 -57
- {hikyuu-2.5.3.dist-info → hikyuu-2.5.6.dist-info}/top_level.txt +1 -0
- {hikyuu-2.5.3.dist-info → hikyuu-2.5.6.dist-info}/LICENSE +0 -0
- {hikyuu-2.5.3.dist-info → hikyuu-2.5.6.dist-info}/WHEEL +0 -0
- {hikyuu-2.5.3.dist-info → hikyuu-2.5.6.dist-info}/entry_points.txt +0 -0
|
@@ -10,6 +10,8 @@ import akshare as ak
|
|
|
10
10
|
import pandas as pd
|
|
11
11
|
from hikyuu.util import *
|
|
12
12
|
|
|
13
|
+
em_num_per_page = 100
|
|
14
|
+
|
|
13
15
|
|
|
14
16
|
@hku_catch(ret=[], trace=True)
|
|
15
17
|
def get_hybk_names():
|
|
@@ -17,7 +19,7 @@ def get_hybk_names():
|
|
|
17
19
|
url = "https://19.push2.eastmoney.com/api/qt/clist/get"
|
|
18
20
|
params = {
|
|
19
21
|
"pn": "1",
|
|
20
|
-
"pz":
|
|
22
|
+
"pz": str(em_num_per_page),
|
|
21
23
|
"po": "1",
|
|
22
24
|
"np": "1",
|
|
23
25
|
"ut": "bd1d9ddb04089700cf9c27f6f7426281",
|
|
@@ -31,6 +33,15 @@ def get_hybk_names():
|
|
|
31
33
|
r = requests.get(url, params=params, timeout=15)
|
|
32
34
|
data_json = r.json()
|
|
33
35
|
ret = [(v['f12'], v['f14']) for v in data_json["data"]["diff"]]
|
|
36
|
+
total_page = math.ceil(data_json["data"]["total"] / em_num_per_page)
|
|
37
|
+
for page in range(2, total_page + 1):
|
|
38
|
+
params["pn"] = page
|
|
39
|
+
r = requests.get(url, params=params, timeout=15)
|
|
40
|
+
data_json = r.json()
|
|
41
|
+
if data_json["data"] is None:
|
|
42
|
+
continue
|
|
43
|
+
tmp = [(v['f12'], v['f14']) for v in data_json["data"]["diff"]]
|
|
44
|
+
ret.extend(tmp)
|
|
34
45
|
return ret
|
|
35
46
|
|
|
36
47
|
|
|
@@ -40,7 +51,7 @@ def get_hybk_cons_code(blk_code):
|
|
|
40
51
|
url = "http://30.push2.eastmoney.com/api/qt/clist/get"
|
|
41
52
|
params = {
|
|
42
53
|
"pn": "1",
|
|
43
|
-
"pz":
|
|
54
|
+
"pz": str(em_num_per_page),
|
|
44
55
|
"po": "1",
|
|
45
56
|
"np": "1",
|
|
46
57
|
"ut": "bd1d9ddb04089700cf9c27f6f7426281",
|
|
@@ -54,7 +65,7 @@ def get_hybk_cons_code(blk_code):
|
|
|
54
65
|
r = requests.get(url, params=params, timeout=15)
|
|
55
66
|
data_json = r.json()
|
|
56
67
|
ret = [v['f12'] for v in data_json["data"]["diff"]]
|
|
57
|
-
total_page = math.ceil(data_json["data"]["total"] /
|
|
68
|
+
total_page = math.ceil(data_json["data"]["total"] / em_num_per_page)
|
|
58
69
|
for page in range(2, total_page + 1):
|
|
59
70
|
params["pn"] = page
|
|
60
71
|
r = requests.get(url, params=params, timeout=15)
|
|
@@ -99,7 +110,7 @@ def get_dybk_names():
|
|
|
99
110
|
url = "http://13.push2.eastmoney.com/api/qt/clist/get"
|
|
100
111
|
params = {
|
|
101
112
|
"pn": "1",
|
|
102
|
-
"pz":
|
|
113
|
+
"pz": str(em_num_per_page),
|
|
103
114
|
"po": "1",
|
|
104
115
|
"np": "1",
|
|
105
116
|
"ut": "bd1d9ddb04089700cf9c27f6f7426281",
|
|
@@ -115,7 +126,7 @@ def get_dybk_names():
|
|
|
115
126
|
hku_check(data_json['data'] is not None, "获取地域板块名称列表失败!")
|
|
116
127
|
ret = [(v["f12"], v["f14"]) for v in data_json["data"]["diff"]]
|
|
117
128
|
|
|
118
|
-
total_page = math.ceil(data_json["data"]["total"] /
|
|
129
|
+
total_page = math.ceil(data_json["data"]["total"] / em_num_per_page)
|
|
119
130
|
for page in range(2, total_page + 1):
|
|
120
131
|
params["pn"] = page
|
|
121
132
|
r = requests.get(url, params=params, timeout=15)
|
|
@@ -133,7 +144,7 @@ def get_all_dybk_info(code_market_dict, sep=""):
|
|
|
133
144
|
url = "http://13.push2.eastmoney.com/api/qt/clist/get"
|
|
134
145
|
params = {
|
|
135
146
|
"pn": "1",
|
|
136
|
-
"pz":
|
|
147
|
+
"pz": str(em_num_per_page),
|
|
137
148
|
"po": "1",
|
|
138
149
|
"np": "1",
|
|
139
150
|
"ut": "bd1d9ddb04089700cf9c27f6f7426281",
|
|
@@ -160,7 +171,7 @@ def get_all_dybk_info(code_market_dict, sep=""):
|
|
|
160
171
|
ret[blk_name] = [
|
|
161
172
|
f"{code_market_dict[v['f12']]}{sep}{v['f12']}" for v in stk_json if v['f12'] in code_market_dict]
|
|
162
173
|
|
|
163
|
-
total_page = math.ceil(data["data"]["total"] /
|
|
174
|
+
total_page = math.ceil(data["data"]["total"] / em_num_per_page)
|
|
164
175
|
for page in range(2, total_page + 1):
|
|
165
176
|
params["pn"] = page
|
|
166
177
|
r = requests.get(url, params=params, timeout=15)
|
|
@@ -145,8 +145,8 @@ class UseTdxImportToH5Thread(QThread):
|
|
|
145
145
|
connect = sqlite3.connect(dest_dir + "/stock.db")
|
|
146
146
|
create_database(connect)
|
|
147
147
|
|
|
148
|
-
tdx_import_stock_name_from_file(connect, src_dir + "
|
|
149
|
-
tdx_import_stock_name_from_file(connect, src_dir + "
|
|
148
|
+
tdx_import_stock_name_from_file(connect, src_dir + "/T0002/hq_cache/shm.tnf", 'SH', self.quotations)
|
|
149
|
+
tdx_import_stock_name_from_file(connect, src_dir + "/T0002/hq_cache/szm.tnf", 'SZ', self.quotations)
|
|
150
150
|
|
|
151
151
|
self.send_message(['FINISHED_IMPORT_CODE'])
|
|
152
152
|
|
hikyuu/hub.py
CHANGED
|
@@ -344,6 +344,10 @@ class HubManager(metaclass=SingletonType):
|
|
|
344
344
|
self._session.query(PartModel).filter_by(hub_name=name).delete()
|
|
345
345
|
self._session.query(HubModel).filter_by(name=name).delete()
|
|
346
346
|
|
|
347
|
+
@lru_cache
|
|
348
|
+
def _get_module(self, module_name):
|
|
349
|
+
return importlib.import_module(module_name)
|
|
350
|
+
|
|
347
351
|
@dbsession
|
|
348
352
|
def import_part_to_db(self, hub_model):
|
|
349
353
|
part_dict = {
|
|
@@ -387,7 +391,8 @@ class HubManager(metaclass=SingletonType):
|
|
|
387
391
|
|
|
388
392
|
# 导入模块
|
|
389
393
|
try:
|
|
390
|
-
part_module = importlib.import_module(module_name)
|
|
394
|
+
# part_module = importlib.import_module(module_name)
|
|
395
|
+
part_module = self._get_module(module_name)
|
|
391
396
|
except ModuleNotFoundError:
|
|
392
397
|
self.logger.error('{} 缺失 part.py 文件, 位置:"{}"!'.format(module_name, entry.path))
|
|
393
398
|
continue
|
|
@@ -645,18 +650,7 @@ def get_part(name, *args, **kwargs):
|
|
|
645
650
|
:param args: 其他部件相关参数
|
|
646
651
|
:param kwargs: 其他部件相关参数
|
|
647
652
|
"""
|
|
648
|
-
|
|
649
|
-
def _get_part(name, *args, **kwargs):
|
|
650
|
-
return HubManager().get_part(name, *args, **kwargs)
|
|
651
|
-
|
|
652
|
-
try:
|
|
653
|
-
return _get_part(name, *args, **kwargs)
|
|
654
|
-
except TypeError as e:
|
|
655
|
-
if "unhashable type" in str(e):
|
|
656
|
-
hku_info("{}! 该对象不可hash无法缓存, 可考虑优化", str(e))
|
|
657
|
-
return HubManager().get_part(name, *args, **kwargs)
|
|
658
|
-
else:
|
|
659
|
-
raise e
|
|
653
|
+
return HubManager().get_part(name, *args, **kwargs)
|
|
660
654
|
|
|
661
655
|
|
|
662
656
|
def get_part_list(name_list):
|
hikyuu/hub.pyi
CHANGED
|
@@ -28,11 +28,11 @@ import sys as sys
|
|
|
28
28
|
import typing
|
|
29
29
|
__all__: list = ['add_remote_hub', 'add_local_hub', 'update_hub', 'remove_hub', 'build_hub', 'help_part', 'get_part', 'get_part_list', 'get_hub_path', 'get_part_info', 'get_part_module', 'print_part_info', 'get_hub_name_list', 'get_part_name_list', 'get_current_hub', 'search_part']
|
|
30
30
|
class ConfigModel(sqlalchemy.orm.decl_api.Base):
|
|
31
|
-
__mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at
|
|
31
|
+
__mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at 0x1b27916c590; ConfigModel>
|
|
32
32
|
__table__: typing.ClassVar[sqlalchemy.sql.schema.Table] # value = Table('hub_config', MetaData(), Column('id', Integer(), table=<hub_config>, primary_key=True, nullable=False, default=Sequence('config_id_seq', metadata=MetaData())), Column('key', String(), table=<hub_config>), Column('value', String(), table=<hub_config>), schema=None)
|
|
33
33
|
__table_args__: typing.ClassVar[tuple] # value = (UniqueConstraint(Column('key', String(), table=<hub_config>)))
|
|
34
34
|
__tablename__: typing.ClassVar[str] = 'hub_config'
|
|
35
|
-
_sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.ConfigModel'> at
|
|
35
|
+
_sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.ConfigModel'> at 1b279530550>
|
|
36
36
|
def __init__(self, **kwargs):
|
|
37
37
|
"""
|
|
38
38
|
A simple constructor that allows initialization from kwargs.
|
|
@@ -55,6 +55,9 @@ class HubManager:
|
|
|
55
55
|
"""
|
|
56
56
|
_instance: typing.ClassVar[HubManager] # value = <hikyuu.hub.HubManager object>
|
|
57
57
|
@staticmethod
|
|
58
|
+
def _get_module(*args, **kwargs):
|
|
59
|
+
...
|
|
60
|
+
@staticmethod
|
|
58
61
|
def add_local_hub(*args, **kwargs):
|
|
59
62
|
...
|
|
60
63
|
@staticmethod
|
|
@@ -106,11 +109,11 @@ class HubManager:
|
|
|
106
109
|
def print_part_info(self, name):
|
|
107
110
|
...
|
|
108
111
|
class HubModel(sqlalchemy.orm.decl_api.Base):
|
|
109
|
-
__mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at
|
|
112
|
+
__mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at 0x1b27951e630; HubModel>
|
|
110
113
|
__table__: typing.ClassVar[sqlalchemy.sql.schema.Table] # value = Table('hub_repo', MetaData(), Column('id', Integer(), table=<hub_repo>, primary_key=True, nullable=False, default=Sequence('remote_id_seq', metadata=MetaData())), Column('name', String(), table=<hub_repo>), Column('hub_type', String(), table=<hub_repo>), Column('local_base', String(), table=<hub_repo>), Column('local', String(), table=<hub_repo>), Column('url', String(), table=<hub_repo>), Column('branch', String(), table=<hub_repo>), schema=None)
|
|
111
114
|
__table_args__: typing.ClassVar[tuple] # value = (UniqueConstraint(Column('name', String(), table=<hub_repo>)))
|
|
112
115
|
__tablename__: typing.ClassVar[str] = 'hub_repo'
|
|
113
|
-
_sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.HubModel'> at
|
|
116
|
+
_sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.HubModel'> at 1b279548e60>
|
|
114
117
|
def __init__(self, **kwargs):
|
|
115
118
|
"""
|
|
116
119
|
A simple constructor that allows initialization from kwargs.
|
|
@@ -143,11 +146,11 @@ class ModuleConflictError(Exception):
|
|
|
143
146
|
def __str__(self):
|
|
144
147
|
...
|
|
145
148
|
class PartModel(sqlalchemy.orm.decl_api.Base):
|
|
146
|
-
__mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at
|
|
149
|
+
__mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at 0x1b27951f020; PartModel>
|
|
147
150
|
__table__: typing.ClassVar[sqlalchemy.sql.schema.Table] # value = Table('hub_part', MetaData(), Column('id', Integer(), table=<hub_part>, primary_key=True, nullable=False, default=Sequence('part_id_seq', metadata=MetaData())), Column('hub_name', String(), table=<hub_part>), Column('part', String(), table=<hub_part>), Column('name', String(), table=<hub_part>), Column('author', String(), table=<hub_part>), Column('version', String(), table=<hub_part>), Column('doc', String(), table=<hub_part>), Column('module_name', String(), table=<hub_part>), Column('label', String(), table=<hub_part>), schema=None)
|
|
148
151
|
__table_args__: typing.ClassVar[tuple] # value = (UniqueConstraint(Column('name', String(), table=<hub_part>)))
|
|
149
152
|
__tablename__: typing.ClassVar[str] = 'hub_part'
|
|
150
|
-
_sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.PartModel'> at
|
|
153
|
+
_sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.PartModel'> at 1b2795499f0>
|
|
151
154
|
def __init__(self, **kwargs):
|
|
152
155
|
"""
|
|
153
156
|
A simple constructor that allows initialization from kwargs.
|
|
@@ -25,8 +25,6 @@ namespace hku {
|
|
|
25
25
|
* @ingroup Indicator
|
|
26
26
|
*/
|
|
27
27
|
Indicator HKU_API BARSSINCE();
|
|
28
|
-
Indicator BARSSINCE(Indicator::value_t);
|
|
29
|
-
Indicator BARSSINCE(const Indicator& ind);
|
|
30
28
|
|
|
31
29
|
inline Indicator BARSSINCE(const Indicator& ind) {
|
|
32
30
|
return BARSSINCE()(ind);
|
|
@@ -36,6 +34,20 @@ inline Indicator BARSSINCE(Indicator::value_t val) {
|
|
|
36
34
|
return BARSSINCE(CVAL(val));
|
|
37
35
|
}
|
|
38
36
|
|
|
37
|
+
/**
|
|
38
|
+
* N周期内首个条件成立位置
|
|
39
|
+
* @details N周期内第一个条件成立到当前的周期数
|
|
40
|
+
* <pre>
|
|
41
|
+
* 用法:BARSSINCEN(X,N):N周期内第一次X不为0到现在的周期数,N为常量BARSSINCEN(X,N):
|
|
42
|
+
* 例如:BARSSINCEN(HIGH>10,10)表示10个周期内股价超过10元时到当前的周期数
|
|
43
|
+
* </pre>
|
|
44
|
+
* @ingroup Indicator
|
|
45
|
+
*/
|
|
46
|
+
Indicator HKU_API BARSSINCEN(int n);
|
|
47
|
+
inline Indicator BARSSINCEN(const Indicator& ind, int n) {
|
|
48
|
+
return BARSSINCEN(n)(ind);
|
|
49
|
+
}
|
|
50
|
+
|
|
39
51
|
} // namespace hku
|
|
40
52
|
|
|
41
53
|
#endif /* INDICATOR_CRT_BARSSINCE_H_ */
|
|
@@ -15,6 +15,11 @@
|
|
|
15
15
|
|
|
16
16
|
namespace hku {
|
|
17
17
|
|
|
18
|
+
/*
|
|
19
|
+
* N周期内首个条件成立位置, N为0时,为整个序列
|
|
20
|
+
* 用法:BARSSINCEN(X,N):N周期内第一次X不为0到现在的周期数,N为常量BARSSINCEN(X,N):
|
|
21
|
+
* 例如:BARSSINCEN(HIGH>10,10)表示10个周期内股价超过10元时到当前的周期数
|
|
22
|
+
*/
|
|
18
23
|
class IBarsSince : public IndicatorImp {
|
|
19
24
|
INDICATOR_IMP(IBarsSince)
|
|
20
25
|
INDICATOR_IMP_NO_PRIVATE_MEMBER_SERIALIZATION
|
|
@@ -22,6 +27,7 @@ class IBarsSince : public IndicatorImp {
|
|
|
22
27
|
public:
|
|
23
28
|
IBarsSince();
|
|
24
29
|
virtual ~IBarsSince();
|
|
30
|
+
virtual void _checkParam(const string& name) const override;
|
|
25
31
|
};
|
|
26
32
|
|
|
27
33
|
} /* namespace hku */
|
|
@@ -298,9 +298,10 @@ HKU_UTILS_API std::ostream &operator<<(std::ostream &, const Datetime &);
|
|
|
298
298
|
typedef std::vector<Datetime> DatetimeList;
|
|
299
299
|
|
|
300
300
|
/**
|
|
301
|
-
* 获取指定范围的日历日期列表[start,
|
|
301
|
+
* 获取指定范围的日历日期列表[start,end),仅仅是日,不含时分秒。
|
|
302
|
+
* @note 如果指定的结束日期过大,可能会耗费大量内存
|
|
302
303
|
* @param start 起始日期
|
|
303
|
-
* @param end
|
|
304
|
+
* @param end 结束日期, 如果为空,将使用 Datetime::max
|
|
304
305
|
* @return [start, end)范围内的日历日期
|
|
305
306
|
*/
|
|
306
307
|
DatetimeList HKU_UTILS_API getDateRange(const Datetime &start, const Datetime &end);
|
|
@@ -411,7 +412,7 @@ template <>
|
|
|
411
412
|
class hash<hku::Datetime> {
|
|
412
413
|
public:
|
|
413
414
|
size_t operator()(hku::Datetime const &d) const noexcept {
|
|
414
|
-
return d.ticks();
|
|
415
|
+
return std::hash<uint64_t>()(d.ticks());
|
|
415
416
|
}
|
|
416
417
|
};
|
|
417
418
|
|
|
@@ -320,6 +320,14 @@ inline TimeDelta Microseconds(int64_t microsecs) {
|
|
|
320
320
|
|
|
321
321
|
namespace std {
|
|
322
322
|
|
|
323
|
+
template <>
|
|
324
|
+
class hash<hku::TimeDelta> {
|
|
325
|
+
public:
|
|
326
|
+
size_t operator()(hku::TimeDelta const &d) const noexcept {
|
|
327
|
+
return std::hash<int64_t>()(d.ticks());
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
|
|
323
331
|
inline string to_string(const hku::TimeDelta &delta) {
|
|
324
332
|
return delta.str();
|
|
325
333
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 hikyuu.org
|
|
3
|
+
*
|
|
4
|
+
* Created on: 2025-03-18
|
|
5
|
+
* Author: fasiondog
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
#ifndef HKU_UTILS_PLUGIN_BASE_H_
|
|
10
|
+
#define HKU_UTILS_PLUGIN_BASE_H_
|
|
11
|
+
|
|
12
|
+
#include <string>
|
|
13
|
+
#include "hikyuu/utilities/config.h"
|
|
14
|
+
#include "hikyuu/utilities/osdef.h"
|
|
15
|
+
|
|
16
|
+
namespace hku {
|
|
17
|
+
|
|
18
|
+
class PluginBase {
|
|
19
|
+
public:
|
|
20
|
+
PluginBase() = default;
|
|
21
|
+
virtual ~PluginBase() = default;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* @brief 返回插件信息
|
|
25
|
+
* @details
|
|
26
|
+
* 插件信息为json格式,包含name(string)、version(int)、description(string)、author(string)字段
|
|
27
|
+
* 如:{"name":"unknown","version": 1.0,"description":"","author":"unknown"}
|
|
28
|
+
* @return std::string
|
|
29
|
+
*/
|
|
30
|
+
virtual std::string info() const noexcept = 0;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
} // namespace hku
|
|
34
|
+
|
|
35
|
+
#if HKU_OS_WINDOWS
|
|
36
|
+
#define HKU_PLUGIN_DEFINE(plugin) \
|
|
37
|
+
extern "C" __declspec(dllexport) hku::PluginBase* createPlugin() { \
|
|
38
|
+
return new plugin(); \
|
|
39
|
+
}
|
|
40
|
+
#else
|
|
41
|
+
#define HKU_PLUGIN_DEFINE(plugin) \
|
|
42
|
+
extern "C" hku::PluginBase* createPlugin() { \
|
|
43
|
+
return new plugin(); \
|
|
44
|
+
}
|
|
45
|
+
#endif
|
|
46
|
+
|
|
47
|
+
#endif /* HKU_UTILS_PLUGIN_BASE_H_ */
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 hikyuu.org
|
|
3
|
+
*
|
|
4
|
+
* Created on: 2025-04-06
|
|
5
|
+
* Author: fasiondog
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include "PluginLoader.h"
|
|
11
|
+
|
|
12
|
+
namespace hku {
|
|
13
|
+
|
|
14
|
+
template <typename InterfaceT>
|
|
15
|
+
class PluginClient : public InterfaceT {
|
|
16
|
+
public:
|
|
17
|
+
PluginClient() = delete;
|
|
18
|
+
PluginClient(const std::string &path, const std::string &filename) {
|
|
19
|
+
m_loader = std::make_unique<PluginLoader>(path);
|
|
20
|
+
m_loader->load(filename);
|
|
21
|
+
m_impl = m_loader->instance<InterfaceT>();
|
|
22
|
+
}
|
|
23
|
+
virtual ~PluginClient() = default;
|
|
24
|
+
|
|
25
|
+
PluginClient(const PluginClient &) = delete;
|
|
26
|
+
PluginClient &operator=(const PluginClient &) = delete;
|
|
27
|
+
|
|
28
|
+
PluginClient(PluginClient &&rhs) : m_impl(rhs.m_impl), m_loader(std::move(rhs.m_loader)) {
|
|
29
|
+
rhs.m_impl = nullptr;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
PluginClient &operator=(PluginClient &&rhs) {
|
|
33
|
+
if (this != &rhs) {
|
|
34
|
+
m_loader = std::move(rhs.m_loader);
|
|
35
|
+
m_impl = rhs.m_impl;
|
|
36
|
+
rhs.m_impl = nullptr;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
std::string info() const noexcept override {
|
|
41
|
+
return m_impl->info();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
InterfaceT *getPlugin() const {
|
|
45
|
+
return m_impl;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
protected:
|
|
49
|
+
InterfaceT *m_impl;
|
|
50
|
+
|
|
51
|
+
protected:
|
|
52
|
+
std::unique_ptr<PluginLoader> m_loader;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
} // namespace hku
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 hikyuu.org
|
|
3
|
+
*
|
|
4
|
+
* Created on: 2025-03-18
|
|
5
|
+
* Author: fasiondog
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
#ifndef HKU_UTILS_PLUGIN_LOADER_H_
|
|
10
|
+
#define HKU_UTILS_PLUGIN_LOADER_H_
|
|
11
|
+
|
|
12
|
+
#include <mutex>
|
|
13
|
+
#include <string>
|
|
14
|
+
#include <memory>
|
|
15
|
+
#include "hikyuu/utilities/config.h"
|
|
16
|
+
#include "hikyuu/utilities/osdef.h"
|
|
17
|
+
#include "hikyuu/utilities/Log.h"
|
|
18
|
+
#include "PluginBase.h"
|
|
19
|
+
|
|
20
|
+
#if HKU_OS_WINDOWS
|
|
21
|
+
#include <windows.h>
|
|
22
|
+
#endif
|
|
23
|
+
|
|
24
|
+
#ifndef HKU_UTILS_API
|
|
25
|
+
#define HKU_UTILS_API
|
|
26
|
+
#endif
|
|
27
|
+
|
|
28
|
+
namespace hku {
|
|
29
|
+
|
|
30
|
+
class HKU_UTILS_API PluginLoader final {
|
|
31
|
+
public:
|
|
32
|
+
PluginLoader();
|
|
33
|
+
explicit PluginLoader(const std::string& path);
|
|
34
|
+
PluginLoader(const PluginLoader&) = delete;
|
|
35
|
+
PluginLoader(PluginLoader&&) = delete;
|
|
36
|
+
|
|
37
|
+
~PluginLoader();
|
|
38
|
+
|
|
39
|
+
bool load(const std::string& pluginname) noexcept;
|
|
40
|
+
|
|
41
|
+
template <typename T>
|
|
42
|
+
T* instance() const noexcept {
|
|
43
|
+
HKU_IF_RETURN(!m_plugin, nullptr);
|
|
44
|
+
return dynamic_cast<T*>(m_plugin.get());
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private:
|
|
48
|
+
void unload() noexcept;
|
|
49
|
+
void* getFunciton(const char* symbol) noexcept;
|
|
50
|
+
std::string getFileName(const std::string& pluginname) const noexcept;
|
|
51
|
+
|
|
52
|
+
private:
|
|
53
|
+
#if HKU_OS_WINDOWS
|
|
54
|
+
HMODULE m_handle{nullptr};
|
|
55
|
+
#else
|
|
56
|
+
void* m_handle{nullptr};
|
|
57
|
+
#endif
|
|
58
|
+
std::string m_path;
|
|
59
|
+
std::unique_ptr<PluginBase> m_plugin{nullptr};
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
} // namespace hku
|
|
63
|
+
|
|
64
|
+
#endif /* HKU_UTILS_PLUGIN_LOADER_H_ */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -242,7 +242,7 @@ private:
|
|
|
242
242
|
std::vector<std::thread> m_threads; // 工作线程
|
|
243
243
|
|
|
244
244
|
// 线程本地变量
|
|
245
|
-
#if CPP_STANDARD >= CPP_STANDARD_17
|
|
245
|
+
#if CPP_STANDARD >= CPP_STANDARD_17 && !defined(__clang__)
|
|
246
246
|
inline static thread_local MQStealQueue<task_type>* m_local_work_queue =
|
|
247
247
|
nullptr; // 本地任务队列
|
|
248
248
|
inline static thread_local int m_index = -1; // 在线程池中的序号
|
|
@@ -235,7 +235,7 @@ private:
|
|
|
235
235
|
std::vector<std::thread> m_threads; // 工作线程
|
|
236
236
|
|
|
237
237
|
// 线程本地变量
|
|
238
|
-
#if CPP_STANDARD >= CPP_STANDARD_17
|
|
238
|
+
#if CPP_STANDARD >= CPP_STANDARD_17 && !defined(__clang__)
|
|
239
239
|
inline static thread_local ThreadSafeQueue<task_type>* m_local_work_queue =
|
|
240
240
|
nullptr; // 本地任务队列
|
|
241
241
|
inline static thread_local int m_index = -1; // 在线程池中的序号
|
|
@@ -239,7 +239,7 @@ private:
|
|
|
239
239
|
std::vector<std::thread> m_threads; // 工作线程
|
|
240
240
|
|
|
241
241
|
// 线程本地变量
|
|
242
|
-
#if CPP_STANDARD >= CPP_STANDARD_17
|
|
242
|
+
#if CPP_STANDARD >= CPP_STANDARD_17 && !defined(__clang__)
|
|
243
243
|
inline static thread_local WorkStealQueue* m_local_work_queue = nullptr; // 本地任务队列
|
|
244
244
|
inline static thread_local int m_index = -1; // 在线程池中的序号
|
|
245
245
|
inline static thread_local InterruptFlag m_thread_need_stop; // 线程停止运行指示
|
|
@@ -193,7 +193,7 @@ private:
|
|
|
193
193
|
std::vector<InterruptFlag*> m_interrupt_flags; // 线程中断标志
|
|
194
194
|
|
|
195
195
|
// 线程本地变量
|
|
196
|
-
#if CPP_STANDARD >= CPP_STANDARD_17
|
|
196
|
+
#if CPP_STANDARD >= CPP_STANDARD_17 && !defined(__clang__)
|
|
197
197
|
inline static thread_local InterruptFlag m_thread_need_stop; // 线程停止运行指示
|
|
198
198
|
inline static thread_local int m_index = -1; // 在线程池中的序号
|
|
199
199
|
#else
|
hikyuu/include/hikyuu/version.h
CHANGED
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
#define HKU_VERSION_H
|
|
13
13
|
|
|
14
14
|
// clang-format off
|
|
15
|
-
#define HKU_VERSION "2.5.
|
|
15
|
+
#define HKU_VERSION "2.5.6"
|
|
16
16
|
#define HKU_VERSION_MAJOR 2
|
|
17
17
|
#define HKU_VERSION_MINOR 5
|
|
18
|
-
#define HKU_VERSION_ALTER
|
|
19
|
-
#define HKU_VERSION_BUILD
|
|
18
|
+
#define HKU_VERSION_ALTER 6
|
|
19
|
+
#define HKU_VERSION_BUILD 202504131513
|
|
20
20
|
#define HKU_VERSION_MODE "RELEASE"
|
|
21
|
-
#define HKU_VERSION_GIT "2.5.
|
|
21
|
+
#define HKU_VERSION_GIT "2.5.6 release.2e933ae9 (RELEASE)"
|
|
22
22
|
// clang-format on
|
|
23
23
|
|
|
24
24
|
#endif /* HKU_VERSION_H */
|
hikyuu/indicator/indicator.py
CHANGED
|
@@ -90,7 +90,7 @@ def concat_to_df(dates, ind_list, head_stock_code=True, head_ind_name=False):
|
|
|
90
90
|
示例:
|
|
91
91
|
query = Query(-200)
|
|
92
92
|
k_list = [stk.get_kdata(query) for stk in [sm['sz000001'], sm['sz000002']]]
|
|
93
|
-
ma_list = [MA(k) for k in k_list]
|
|
93
|
+
ma_list = [MA(CLOSE(k)) for k in k_list]
|
|
94
94
|
concat_to_df(sm.get_trading_calendar(query), ma_list, head_stock_code=True, head_ind_name=False)
|
|
95
95
|
|
|
96
96
|
输出:
|