hikyuu 2.5.1__py3-none-win_amd64.whl → 2.5.3__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__.py +5 -1
- hikyuu/__init__.pyi +522 -505
- hikyuu/analysis/__init__.pyi +489 -478
- hikyuu/analysis/analysis.pyi +490 -479
- hikyuu/core.pyi +491 -480
- hikyuu/cpp/__init__.pyi +3 -0
- hikyuu/cpp/core310.pyd +0 -0
- hikyuu/cpp/core310.pyi +13154 -0
- hikyuu/cpp/core311.pyd +0 -0
- hikyuu/cpp/core311.pyi +13154 -0
- hikyuu/cpp/core312.pyd +0 -0
- hikyuu/cpp/core312.pyi +13154 -0
- hikyuu/cpp/core313.pyd +0 -0
- hikyuu/cpp/core313.pyi +13132 -0
- hikyuu/cpp/core38.pyd +0 -0
- hikyuu/cpp/core38.pyi +13154 -0
- hikyuu/cpp/core39.pyd +0 -0
- hikyuu/cpp/core39.pyi +13154 -0
- hikyuu/cpp/hikyuu.dll +0 -0
- hikyuu/cpp/hikyuu.lib +0 -0
- hikyuu/data/mysql_upgrade/0027.sql +6 -0
- hikyuu/data/pytdx_to_h5.py +7 -4
- hikyuu/data/pytdx_to_mysql.py +7 -4
- hikyuu/data/sqlite_upgrade/0027.sql +8 -0
- hikyuu/draw/drawplot/__init__.py +8 -1
- hikyuu/draw/drawplot/__init__.pyi +11 -7
- hikyuu/draw/drawplot/bokeh_draw.pyi +510 -495
- hikyuu/draw/drawplot/common.pyi +1 -1
- hikyuu/draw/drawplot/echarts_draw.pyi +512 -497
- hikyuu/draw/drawplot/matplotlib_draw.py +134 -12
- hikyuu/draw/drawplot/matplotlib_draw.pyi +571 -509
- hikyuu/draw/elder.pyi +11 -11
- hikyuu/draw/kaufman.pyi +18 -18
- hikyuu/draw/volume.pyi +10 -10
- hikyuu/extend.py +0 -24
- hikyuu/extend.pyi +500 -506
- hikyuu/hub.py +154 -9
- hikyuu/hub.pyi +51 -13
- hikyuu/include/hikyuu/DataType.h +1 -2
- hikyuu/include/hikyuu/StockManager.h +2 -1
- hikyuu/include/hikyuu/StrategyContext.h +12 -3
- hikyuu/include/hikyuu/indicator/Indicator.h +24 -0
- hikyuu/include/hikyuu/indicator/Indicator2InImp.h +1 -0
- hikyuu/include/hikyuu/indicator/build_in.h +2 -0
- hikyuu/include/hikyuu/indicator/crt/ATR.h +2 -13
- hikyuu/include/hikyuu/indicator/crt/KALMAN.h +30 -0
- hikyuu/include/hikyuu/indicator/crt/TR.h +32 -0
- hikyuu/include/hikyuu/indicator/imp/IAtr.h +3 -1
- hikyuu/include/hikyuu/indicator/imp/IKalman.h +27 -0
- hikyuu/include/hikyuu/indicator/imp/ITr.h +35 -0
- hikyuu/include/hikyuu/python/convert_any.h +299 -0
- hikyuu/include/hikyuu/trade_manage/PositionRecord.h +8 -2
- hikyuu/include/hikyuu/trade_sys/allocatefunds/crt/AF_MultiFactor.h +1 -1
- hikyuu/include/hikyuu/trade_sys/allocatefunds/imp/MultiFactorAllocaterFunds.h +3 -0
- hikyuu/include/hikyuu/trade_sys/condition/ConditionBase.h +4 -1
- hikyuu/include/hikyuu/trade_sys/condition/imp/{SubCondition.h → logic/SubCondition.h} +1 -1
- hikyuu/include/hikyuu/trade_sys/environment/EnvironmentBase.h +20 -6
- hikyuu/include/hikyuu/trade_sys/environment/build_in.h +1 -0
- hikyuu/include/hikyuu/trade_sys/environment/crt/EV_Logic.h +35 -0
- hikyuu/include/hikyuu/trade_sys/environment/imp/logic/AddEnvironment.h +42 -0
- hikyuu/include/hikyuu/trade_sys/environment/imp/logic/AndEnvironment.h +42 -0
- hikyuu/include/hikyuu/trade_sys/environment/imp/logic/DivEnvironment.h +42 -0
- hikyuu/include/hikyuu/trade_sys/environment/imp/logic/MultiEnvironment.h +42 -0
- hikyuu/include/hikyuu/trade_sys/environment/imp/logic/OrEnvironment.h +42 -0
- hikyuu/include/hikyuu/trade_sys/environment/imp/logic/SubEnvironment.h +42 -0
- hikyuu/include/hikyuu/trade_sys/environment/imp/logic/__init__.py +1 -0
- hikyuu/include/hikyuu/trade_sys/portfolio/Portfolio.h +0 -4
- hikyuu/include/hikyuu/trade_sys/signal/SignalBase.h +1 -7
- hikyuu/include/hikyuu/trade_sys/signal/crt/SG_Logic.h +94 -4
- hikyuu/include/hikyuu/trade_sys/signal/crt/SG_OneSide.h +10 -0
- hikyuu/include/hikyuu/trade_sys/signal/imp/logic/AndSignal.h +19 -0
- hikyuu/include/hikyuu/trade_sys/signal/imp/logic/OperatorSignal.h +3 -1
- hikyuu/include/hikyuu/trade_sys/signal/imp/logic/OperatorValueSignal.h +1 -0
- hikyuu/include/hikyuu/trade_sys/signal/imp/logic/OrSignal.h +19 -0
- hikyuu/include/hikyuu/version.h +4 -4
- hikyuu/indicator/indicator.py +1 -0
- hikyuu/trade_manage/__init__.pyi +506 -495
- hikyuu/trade_manage/broker.pyi +3 -3
- hikyuu/trade_manage/broker_easytrader.pyi +1 -1
- hikyuu/trade_manage/trade.pyi +506 -495
- hikyuu/trade_sys/trade_sys.py +4 -3
- hikyuu/util/__init__.pyi +2 -2
- hikyuu/util/singleton.pyi +1 -1
- {hikyuu-2.5.1.dist-info → hikyuu-2.5.3.dist-info}/METADATA +3 -2
- {hikyuu-2.5.1.dist-info → hikyuu-2.5.3.dist-info}/RECORD +89 -65
- {hikyuu-2.5.1.dist-info → hikyuu-2.5.3.dist-info}/top_level.txt +1 -0
- {hikyuu-2.5.1.dist-info → hikyuu-2.5.3.dist-info}/LICENSE +0 -0
- {hikyuu-2.5.1.dist-info → hikyuu-2.5.3.dist-info}/WHEEL +0 -0
- {hikyuu-2.5.1.dist-info → hikyuu-2.5.3.dist-info}/entry_points.txt +0 -0
hikyuu/hub.py
CHANGED
|
@@ -11,6 +11,7 @@ from sqlalchemy.orm import sessionmaker, scoped_session, declarative_base
|
|
|
11
11
|
from sqlalchemy import (create_engine, Sequence, Column, Integer, String, and_, UniqueConstraint)
|
|
12
12
|
from hikyuu.util.singleton import SingletonType
|
|
13
13
|
from hikyuu.util.check import checkif
|
|
14
|
+
from hikyuu.util import hku_info
|
|
14
15
|
import os
|
|
15
16
|
import stat
|
|
16
17
|
import errno
|
|
@@ -19,7 +20,9 @@ import shutil
|
|
|
19
20
|
import pathlib
|
|
20
21
|
import logging
|
|
21
22
|
import importlib
|
|
22
|
-
|
|
23
|
+
import inspect
|
|
24
|
+
import sqlalchemy
|
|
25
|
+
from functools import lru_cache
|
|
23
26
|
|
|
24
27
|
# 引入 git 前需设置环境变量,否则某些情况下会报错失败
|
|
25
28
|
os.environ['GIT_PYTHON_REFRESH'] = 'quiet'
|
|
@@ -79,6 +82,10 @@ class PartModel(Base):
|
|
|
79
82
|
version = Column(String) # 版本
|
|
80
83
|
doc = Column(String) # 帮助说明
|
|
81
84
|
module_name = Column(String) # 实际策略导入模块名
|
|
85
|
+
label = Column(String) # 标签
|
|
86
|
+
__table_args__ = (
|
|
87
|
+
UniqueConstraint('name', name='uq_part_model_name'),
|
|
88
|
+
)
|
|
82
89
|
|
|
83
90
|
def __str__(self):
|
|
84
91
|
return 'PartModel(id={}, hub_name={}, part={}, name={}, author={}, module_name={})'.format(
|
|
@@ -173,6 +180,25 @@ class HubManager(metaclass=SingletonType):
|
|
|
173
180
|
|
|
174
181
|
# 创建仓库数据库
|
|
175
182
|
engine = create_engine("sqlite:///{}/.hikyuu/hub.db".format(usr_dir))
|
|
183
|
+
|
|
184
|
+
inspector = sqlalchemy.inspect(engine)
|
|
185
|
+
if inspector.has_table(PartModel.__tablename__):
|
|
186
|
+
columns = inspector.get_columns(PartModel.__tablename__)
|
|
187
|
+
column_exists = any(column['name'] == 'label' for column in columns)
|
|
188
|
+
if not column_exists:
|
|
189
|
+
add_column_sql = sqlalchemy.text(
|
|
190
|
+
f"ALTER TABLE {PartModel.__tablename__} ADD COLUMN label TEXT;")
|
|
191
|
+
with engine.connect() as connection:
|
|
192
|
+
connection.execute(add_column_sql)
|
|
193
|
+
|
|
194
|
+
indexes = inspector.get_indexes(PartModel.__tablename__)
|
|
195
|
+
index_exists = any(index['name'] == "uq_part_model_name" for index in indexes)
|
|
196
|
+
if not index_exists:
|
|
197
|
+
create_index_sql = sqlalchemy.text(
|
|
198
|
+
f"CREATE INDEX uq_part_model_name ON {PartModel.__tablename__} (name);")
|
|
199
|
+
with engine.connect() as connection:
|
|
200
|
+
connection.execute(create_index_sql)
|
|
201
|
+
|
|
176
202
|
Base.metadata.create_all(engine)
|
|
177
203
|
self._scoped_Session = scoped_session(sessionmaker(autocommit=False, autoflush=False, bind=engine))
|
|
178
204
|
self._session = None
|
|
@@ -365,8 +391,8 @@ class HubManager(metaclass=SingletonType):
|
|
|
365
391
|
except ModuleNotFoundError:
|
|
366
392
|
self.logger.error('{} 缺失 part.py 文件, 位置:"{}"!'.format(module_name, entry.path))
|
|
367
393
|
continue
|
|
368
|
-
except:
|
|
369
|
-
self.logger.error('{} 无法导入该文件: {}'.format(module_name, entry.path))
|
|
394
|
+
except Exception as e:
|
|
395
|
+
self.logger.error('{} 无法导入该文件: {}! {}'.format(module_name, entry.path, str(e)))
|
|
370
396
|
continue
|
|
371
397
|
|
|
372
398
|
module_vars = vars(part_module)
|
|
@@ -386,7 +412,8 @@ class HubManager(metaclass=SingletonType):
|
|
|
386
412
|
module_name=module_name,
|
|
387
413
|
author=part_module.author.strip() if 'author' in module_vars else 'None',
|
|
388
414
|
version=part_module.version.strip() if 'version' in module_vars else 'None',
|
|
389
|
-
doc=part_module.part.__doc__.strip() if part_module.part.__doc__ else "None"
|
|
415
|
+
doc=part_module.part.__doc__.strip() if part_module.part.__doc__ else "None",
|
|
416
|
+
label=part_module.label.strip() if 'label' in module_vars else 'None',
|
|
390
417
|
)
|
|
391
418
|
self._session.add(part_model)
|
|
392
419
|
except Exception as e:
|
|
@@ -426,6 +453,30 @@ class HubManager(metaclass=SingletonType):
|
|
|
426
453
|
pass
|
|
427
454
|
return part
|
|
428
455
|
|
|
456
|
+
@dbsession
|
|
457
|
+
def get_part_module(self, name):
|
|
458
|
+
"""获取指定策略部件
|
|
459
|
+
|
|
460
|
+
:param str name: 策略部件名称
|
|
461
|
+
:param kwargs: 其他部件相关参数
|
|
462
|
+
"""
|
|
463
|
+
name_parts = name.split('.')
|
|
464
|
+
checkif(
|
|
465
|
+
len(name_parts) < 2
|
|
466
|
+
or (name_parts[-2] not in ('af', 'cn', 'ev', 'mf', 'mm', 'pg', 'se', 'sg', 'sp', 'st', 'pf', 'sys', 'ind', 'other')),
|
|
467
|
+
name, PartNameError
|
|
468
|
+
)
|
|
469
|
+
|
|
470
|
+
# 未指定仓库名,则默认使用 'default' 仓库
|
|
471
|
+
part_name = 'default.{}'.format(name) if len(name_parts) == 2 else name
|
|
472
|
+
part_model = self._session.query(PartModel).filter_by(name=part_name).first()
|
|
473
|
+
checkif(part_model is None, part_name, PartNotFoundError, cause='仓库中不存在')
|
|
474
|
+
try:
|
|
475
|
+
part_module = importlib.import_module(part_model.module_name)
|
|
476
|
+
except ModuleNotFoundError:
|
|
477
|
+
raise PartNotFoundError(part_name, '请检查部件对应路径是否存在')
|
|
478
|
+
return part_module
|
|
479
|
+
|
|
429
480
|
@dbsession
|
|
430
481
|
def get_part_info(self, name):
|
|
431
482
|
"""获取策略部件信息
|
|
@@ -434,11 +485,25 @@ class HubManager(metaclass=SingletonType):
|
|
|
434
485
|
"""
|
|
435
486
|
part_model = self._session.query(PartModel).filter_by(name=name).first()
|
|
436
487
|
checkif(part_model is None, name, PartNotFoundError, cause='仓库中不存在')
|
|
488
|
+
try:
|
|
489
|
+
part_module = importlib.import_module(part_model.module_name)
|
|
490
|
+
except ModuleNotFoundError:
|
|
491
|
+
raise PartNotFoundError(name, '请检查部件对应路径是否存在')
|
|
492
|
+
signature = inspect.signature(part_module.part)
|
|
493
|
+
func_name = f'\npart("{name}",'
|
|
494
|
+
for param_name, param in signature.parameters.items():
|
|
495
|
+
if param.default is param.empty:
|
|
496
|
+
func_name += f"{param_name}, "
|
|
497
|
+
else:
|
|
498
|
+
default_value = param.default
|
|
499
|
+
func_name += f"{param_name}={default_value}, "
|
|
500
|
+
func_name += ")\n"
|
|
501
|
+
func_name += part_module.part.__doc__
|
|
437
502
|
return {
|
|
438
503
|
'name': name,
|
|
439
504
|
'author': part_model.author,
|
|
440
505
|
'version': part_model.version,
|
|
441
|
-
'doc':
|
|
506
|
+
'doc': func_name # part_module.part.__doc__,
|
|
442
507
|
}
|
|
443
508
|
|
|
444
509
|
def print_part_info(self, name):
|
|
@@ -450,10 +515,7 @@ class HubManager(metaclass=SingletonType):
|
|
|
450
515
|
print('+---------+------------------------------------------------')
|
|
451
516
|
print('| version | ', info['version'])
|
|
452
517
|
print('+---------+------------------------------------------------')
|
|
453
|
-
# print('\n')
|
|
454
518
|
print(info['doc'])
|
|
455
|
-
# print('\n')
|
|
456
|
-
# print('----------------------------------------------------------')
|
|
457
519
|
|
|
458
520
|
@dbsession
|
|
459
521
|
def get_hub_path(self, name):
|
|
@@ -500,6 +562,37 @@ class HubManager(metaclass=SingletonType):
|
|
|
500
562
|
checkif(hub_model is None, local_base, HubNotFoundError)
|
|
501
563
|
return hub_model.name
|
|
502
564
|
|
|
565
|
+
@dbsession
|
|
566
|
+
def search_part(self, name: str = None, hub: str = None, part_type: str = None, label=None):
|
|
567
|
+
"""搜索部件
|
|
568
|
+
:param str name: 部件名称
|
|
569
|
+
:param str hub: 仓库名
|
|
570
|
+
:param str part_type: 部件类型
|
|
571
|
+
:param str label: 标签
|
|
572
|
+
:return: 部件名称列表
|
|
573
|
+
:rtype: list
|
|
574
|
+
"""
|
|
575
|
+
parts = None
|
|
576
|
+
if name is not None:
|
|
577
|
+
parts = self._session.query(PartModel).filter(PartModel.name.like(f'%{name}%'))
|
|
578
|
+
if hub is not None:
|
|
579
|
+
if parts is None:
|
|
580
|
+
parts = self._session.query(PartModel).fileter(PartModel.hub_name.like(f'%{hub}%'))
|
|
581
|
+
else:
|
|
582
|
+
parts = parts.filter(PartModel.hub_name.like(f'%{hub}%'))
|
|
583
|
+
if part_type is not None:
|
|
584
|
+
if parts is None:
|
|
585
|
+
parts = self._session.query(PartModel).filter(PartModel.part.like(f'%{part_type}%'))
|
|
586
|
+
else:
|
|
587
|
+
parts = parts.filter(PartModel.part.like(f'%{part_type}%'))
|
|
588
|
+
if label is not None:
|
|
589
|
+
if parts is None:
|
|
590
|
+
parts = self._session.query(PartModel).filter(PartModel.label.like(f'%{label}%'))
|
|
591
|
+
else:
|
|
592
|
+
parts = parts.filter(PartModel.label.like(f'%{label}%'))
|
|
593
|
+
records = parts.all() if parts is not None else []
|
|
594
|
+
return [record.name for record in records]
|
|
595
|
+
|
|
503
596
|
|
|
504
597
|
def add_remote_hub(name, url, branch='main'):
|
|
505
598
|
"""增加远程策略仓库
|
|
@@ -552,7 +645,29 @@ def get_part(name, *args, **kwargs):
|
|
|
552
645
|
:param args: 其他部件相关参数
|
|
553
646
|
:param kwargs: 其他部件相关参数
|
|
554
647
|
"""
|
|
555
|
-
|
|
648
|
+
@lru_cache
|
|
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
|
|
660
|
+
|
|
661
|
+
|
|
662
|
+
def get_part_list(name_list):
|
|
663
|
+
"""
|
|
664
|
+
获取指定策略部件列表
|
|
665
|
+
|
|
666
|
+
:param list name_list: 部件名称列表
|
|
667
|
+
:return: 部件列表
|
|
668
|
+
:rtype: list
|
|
669
|
+
"""
|
|
670
|
+
return [get_part(name) for name in name_list]
|
|
556
671
|
|
|
557
672
|
|
|
558
673
|
def get_hub_path(name):
|
|
@@ -575,6 +690,9 @@ def print_part_info(name):
|
|
|
575
690
|
HubManager().print_part_info(name)
|
|
576
691
|
|
|
577
692
|
|
|
693
|
+
help_part = print_part_info
|
|
694
|
+
|
|
695
|
+
|
|
578
696
|
def get_hub_name_list():
|
|
579
697
|
"""返回仓库名称列表"""
|
|
580
698
|
return HubManager().get_hub_name_list()
|
|
@@ -588,6 +706,16 @@ def get_part_name_list(hub=None, part_type=None):
|
|
|
588
706
|
return HubManager().get_part_name_list(hub, part_type)
|
|
589
707
|
|
|
590
708
|
|
|
709
|
+
def get_part_module(part_name: str):
|
|
710
|
+
"""获取部件模块
|
|
711
|
+
:param str part_name: 部件名称
|
|
712
|
+
:return: 部件模块
|
|
713
|
+
:rtype: module
|
|
714
|
+
"""
|
|
715
|
+
return HubManager().get_part_module(part_name)
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
@lru_cache
|
|
591
719
|
def get_current_hub(filename):
|
|
592
720
|
"""用于在仓库part.py中获取当前所在的仓库名。
|
|
593
721
|
示例: get_current_hub(__file__)
|
|
@@ -595,6 +723,19 @@ def get_current_hub(filename):
|
|
|
595
723
|
return HubManager().get_current_hub(filename)
|
|
596
724
|
|
|
597
725
|
|
|
726
|
+
def search_part(name: str = None, hub: str = None, part_type: str = None, label: str = None):
|
|
727
|
+
"""搜索部件
|
|
728
|
+
|
|
729
|
+
:param str name: 部件名称
|
|
730
|
+
:param str hub: 仓库名
|
|
731
|
+
:param str part_type: 部件类型
|
|
732
|
+
:param str label: 标签
|
|
733
|
+
:return: 部件名称列表
|
|
734
|
+
:rtype: list
|
|
735
|
+
"""
|
|
736
|
+
return HubManager().search_part(name, hub, part_type, label)
|
|
737
|
+
|
|
738
|
+
|
|
598
739
|
# 初始化仓库
|
|
599
740
|
try:
|
|
600
741
|
HubManager().setup_hub()
|
|
@@ -607,13 +748,17 @@ __all__ = [
|
|
|
607
748
|
'update_hub',
|
|
608
749
|
'remove_hub',
|
|
609
750
|
'build_hub',
|
|
751
|
+
'help_part',
|
|
610
752
|
'get_part',
|
|
753
|
+
'get_part_list',
|
|
611
754
|
'get_hub_path',
|
|
612
755
|
'get_part_info',
|
|
756
|
+
'get_part_module',
|
|
613
757
|
'print_part_info',
|
|
614
758
|
'get_hub_name_list',
|
|
615
759
|
'get_part_name_list',
|
|
616
760
|
'get_current_hub',
|
|
761
|
+
'search_part',
|
|
617
762
|
]
|
|
618
763
|
|
|
619
764
|
if __name__ == "__main__":
|
hikyuu/hub.pyi
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
|
-
from configparser import ConfigParser
|
|
3
2
|
import errno as errno
|
|
3
|
+
from functools import lru_cache
|
|
4
4
|
import git as git
|
|
5
5
|
from hikyuu.util.check import checkif
|
|
6
|
+
from hikyuu.util.mylog import hku_info
|
|
6
7
|
from hikyuu.util.singleton import SingletonType
|
|
7
8
|
import importlib as importlib
|
|
9
|
+
import inspect as inspect
|
|
8
10
|
import logging as logging
|
|
9
11
|
import os as os
|
|
10
12
|
import pathlib as pathlib
|
|
11
13
|
import shutil as shutil
|
|
14
|
+
import sqlalchemy as sqlalchemy
|
|
12
15
|
from sqlalchemy.engine.create import create_engine
|
|
13
16
|
from sqlalchemy.orm.decl_api import Base
|
|
14
17
|
from sqlalchemy.orm.decl_api import declarative_base
|
|
15
|
-
import sqlalchemy.orm.instrumentation
|
|
16
|
-
import sqlalchemy.orm.mapper
|
|
17
18
|
from sqlalchemy.orm.scoping import scoped_session
|
|
18
19
|
from sqlalchemy.orm.session import sessionmaker
|
|
19
20
|
from sqlalchemy.sql._elements_constructors import and_
|
|
20
|
-
import sqlalchemy.sql.schema
|
|
21
21
|
from sqlalchemy.sql.schema import Column
|
|
22
22
|
from sqlalchemy.sql.schema import Sequence
|
|
23
23
|
from sqlalchemy.sql.schema import UniqueConstraint
|
|
@@ -26,13 +26,13 @@ from sqlalchemy.sql.sqltypes import String
|
|
|
26
26
|
import stat as stat
|
|
27
27
|
import sys as sys
|
|
28
28
|
import typing
|
|
29
|
-
__all__: list = ['add_remote_hub', 'add_local_hub', 'update_hub', 'remove_hub', 'build_hub', 'get_part', 'get_hub_path', 'get_part_info', 'print_part_info', 'get_hub_name_list', 'get_part_name_list', 'get_current_hub']
|
|
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 0x26f9bde2d90; 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 26f9bdf0950>
|
|
36
36
|
def __init__(self, **kwargs):
|
|
37
37
|
"""
|
|
38
38
|
A simple constructor that allows initialization from kwargs.
|
|
@@ -79,6 +79,9 @@ class HubManager:
|
|
|
79
79
|
def get_part_info(*args, **kwargs):
|
|
80
80
|
...
|
|
81
81
|
@staticmethod
|
|
82
|
+
def get_part_module(*args, **kwargs):
|
|
83
|
+
...
|
|
84
|
+
@staticmethod
|
|
82
85
|
def get_part_name_list(*args, **kwargs):
|
|
83
86
|
...
|
|
84
87
|
@staticmethod
|
|
@@ -88,6 +91,9 @@ class HubManager:
|
|
|
88
91
|
def remove_hub(*args, **kwargs):
|
|
89
92
|
...
|
|
90
93
|
@staticmethod
|
|
94
|
+
def search_part(*args, **kwargs):
|
|
95
|
+
...
|
|
96
|
+
@staticmethod
|
|
91
97
|
def setup_hub(*args, **kwargs):
|
|
92
98
|
...
|
|
93
99
|
@staticmethod
|
|
@@ -100,11 +106,11 @@ class HubManager:
|
|
|
100
106
|
def print_part_info(self, name):
|
|
101
107
|
...
|
|
102
108
|
class HubModel(sqlalchemy.orm.decl_api.Base):
|
|
103
|
-
__mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at
|
|
109
|
+
__mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at 0x26f9be26430; HubModel>
|
|
104
110
|
__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)
|
|
105
111
|
__table_args__: typing.ClassVar[tuple] # value = (UniqueConstraint(Column('name', String(), table=<hub_repo>)))
|
|
106
112
|
__tablename__: typing.ClassVar[str] = 'hub_repo'
|
|
107
|
-
_sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.HubModel'> at
|
|
113
|
+
_sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.HubModel'> at 26f9be1e720>
|
|
108
114
|
def __init__(self, **kwargs):
|
|
109
115
|
"""
|
|
110
116
|
A simple constructor that allows initialization from kwargs.
|
|
@@ -137,10 +143,11 @@ class ModuleConflictError(Exception):
|
|
|
137
143
|
def __str__(self):
|
|
138
144
|
...
|
|
139
145
|
class PartModel(sqlalchemy.orm.decl_api.Base):
|
|
140
|
-
__mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at
|
|
141
|
-
__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>), schema=None)
|
|
146
|
+
__mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at 0x26f9be26dc0; PartModel>
|
|
147
|
+
__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
|
+
__table_args__: typing.ClassVar[tuple] # value = (UniqueConstraint(Column('name', String(), table=<hub_part>)))
|
|
142
149
|
__tablename__: typing.ClassVar[str] = 'hub_part'
|
|
143
|
-
_sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.PartModel'> at
|
|
150
|
+
_sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.PartModel'> at 26f9be2c220>
|
|
144
151
|
def __init__(self, **kwargs):
|
|
145
152
|
"""
|
|
146
153
|
A simple constructor that allows initialization from kwargs.
|
|
@@ -194,7 +201,7 @@ def build_hub(name, cmd = 'buildall'):
|
|
|
194
201
|
"""
|
|
195
202
|
def dbsession(func):
|
|
196
203
|
...
|
|
197
|
-
def get_current_hub(
|
|
204
|
+
def get_current_hub(*args, **kwargs):
|
|
198
205
|
"""
|
|
199
206
|
用于在仓库part.py中获取当前所在的仓库名。
|
|
200
207
|
示例: get_current_hub(__file__)
|
|
@@ -226,6 +233,24 @@ def get_part_info(name):
|
|
|
226
233
|
|
|
227
234
|
:param str name: 部件名称
|
|
228
235
|
|
|
236
|
+
"""
|
|
237
|
+
def get_part_list(name_list):
|
|
238
|
+
"""
|
|
239
|
+
|
|
240
|
+
获取指定策略部件列表
|
|
241
|
+
|
|
242
|
+
:param list name_list: 部件名称列表
|
|
243
|
+
:return: 部件列表
|
|
244
|
+
:rtype: list
|
|
245
|
+
|
|
246
|
+
"""
|
|
247
|
+
def get_part_module(part_name: str):
|
|
248
|
+
"""
|
|
249
|
+
获取部件模块
|
|
250
|
+
:param str part_name: 部件名称
|
|
251
|
+
:return: 部件模块
|
|
252
|
+
:rtype: module
|
|
253
|
+
|
|
229
254
|
"""
|
|
230
255
|
def get_part_name_list(hub = None, part_type = None):
|
|
231
256
|
"""
|
|
@@ -244,6 +269,18 @@ def remove_hub(name):
|
|
|
244
269
|
|
|
245
270
|
:param str name: 仓库名称
|
|
246
271
|
|
|
272
|
+
"""
|
|
273
|
+
def search_part(name: str = None, hub: str = None, part_type: str = None, label: str = None):
|
|
274
|
+
"""
|
|
275
|
+
搜索部件
|
|
276
|
+
|
|
277
|
+
:param str name: 部件名称
|
|
278
|
+
:param str hub: 仓库名
|
|
279
|
+
:param str part_type: 部件类型
|
|
280
|
+
:param str label: 标签
|
|
281
|
+
:return: 部件名称列表
|
|
282
|
+
:rtype: list
|
|
283
|
+
|
|
247
284
|
"""
|
|
248
285
|
def update_hub(name):
|
|
249
286
|
"""
|
|
@@ -252,3 +289,4 @@ def update_hub(name):
|
|
|
252
289
|
:param str name: 仓库名称
|
|
253
290
|
|
|
254
291
|
"""
|
|
292
|
+
help_part = print_part_info
|
hikyuu/include/hikyuu/DataType.h
CHANGED
|
@@ -149,8 +149,7 @@ using std::isinf;
|
|
|
149
149
|
using std::isnan;
|
|
150
150
|
|
|
151
151
|
inline bool iszero(price_t num) {
|
|
152
|
-
|
|
153
|
-
return std::abs(num) < epsilon;
|
|
152
|
+
return std::abs(num) < std::numeric_limits<price_t>::epsilon();
|
|
154
153
|
}
|
|
155
154
|
|
|
156
155
|
using fmt::format;
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Author: fasiondog
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
#pragma once
|
|
8
9
|
#ifndef STOCKMANAGER_H_
|
|
9
10
|
#define STOCKMANAGER_H_
|
|
10
11
|
|
|
@@ -278,7 +279,7 @@ private:
|
|
|
278
279
|
static StockManager* m_sm;
|
|
279
280
|
std::atomic_bool m_initializing;
|
|
280
281
|
std::atomic_bool m_data_ready; // 用于指示是否所有数据准备完毕
|
|
281
|
-
std::thread::id m_thread_id;
|
|
282
|
+
std::thread::id m_thread_id; // 记录线程id,用于判断Stratege是以独立进程方式还是线程方式运行
|
|
282
283
|
string m_tmpdir;
|
|
283
284
|
string m_datadir;
|
|
284
285
|
BaseInfoDriverPtr m_baseInfoDriver;
|
|
@@ -24,7 +24,6 @@ public:
|
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* 构造函数
|
|
27
|
-
* @note 未指定 ktypelist 时,默认按预加载参数加载全部
|
|
28
27
|
* @param stockCodeList 指定的证券代码列表,如:如:{"sz000001", "sz000002"}
|
|
29
28
|
*/
|
|
30
29
|
explicit StrategyContext(const vector<string>& stockCodeList);
|
|
@@ -32,11 +31,14 @@ public:
|
|
|
32
31
|
/**
|
|
33
32
|
* 构造函数
|
|
34
33
|
* @note 证券列表中如果包含 ("ALL") 则表示全部证券;
|
|
35
|
-
* 指定K线类型列表同时影响着K
|
|
34
|
+
* 1. 指定K线类型列表同时影响着K线数据的优先加载顺序,靠前的将优先加载。
|
|
35
|
+
* 2. 未指定 ktypelist 或 preloadNum 时,将使用全局配置文件参数
|
|
36
36
|
* @param stockCodeList 指定的证券代码列表,如:{"sh000001", "sz000001"}
|
|
37
37
|
* @param ktypeList 指定的 K线数据列表,如:{"day", "min"}
|
|
38
|
+
* @param preloadNum 指定的预加载数量,如:{{"min_max", 100}, {"day_max", 200}}
|
|
38
39
|
*/
|
|
39
|
-
StrategyContext(const vector<string>& stockCodeList, const vector<KQuery::KType>& ktypeList
|
|
40
|
+
StrategyContext(const vector<string>& stockCodeList, const vector<KQuery::KType>& ktypeList,
|
|
41
|
+
const unordered_map<string, int>& preloadNum = {});
|
|
40
42
|
|
|
41
43
|
// 自定义移动构造与赋值会引起 python 中无法正常退出
|
|
42
44
|
// StrategyContext(const StrategyContext&) = default;
|
|
@@ -75,6 +77,12 @@ public:
|
|
|
75
77
|
return m_ktypeList;
|
|
76
78
|
}
|
|
77
79
|
|
|
80
|
+
void setPreloadNum(const unordered_map<string, int>& preloadNum);
|
|
81
|
+
|
|
82
|
+
const unordered_map<string, int>& getPreloadNum() const noexcept {
|
|
83
|
+
return m_preloadNum;
|
|
84
|
+
}
|
|
85
|
+
|
|
78
86
|
/**
|
|
79
87
|
* 隐含的默认必须被加载的证券列表
|
|
80
88
|
* @note 影响交易日历判断、和某些常被作为默认比较基准的证券,通常被作为某些函数的默认值
|
|
@@ -100,6 +108,7 @@ private:
|
|
|
100
108
|
vector<string> m_mustLoad{"sh000001", "sh000300"}; // 默认必须加载的 stock
|
|
101
109
|
vector<string> m_stockCodeList;
|
|
102
110
|
vector<KQuery::KType> m_ktypeList;
|
|
111
|
+
unordered_map<string, int> m_preloadNum;
|
|
103
112
|
};
|
|
104
113
|
|
|
105
114
|
HKU_API std::ostream& operator<<(std::ostream& os, const StrategyContext& context);
|
|
@@ -198,6 +198,8 @@ public:
|
|
|
198
198
|
return !m_imp && m_imp == other.m_imp;
|
|
199
199
|
}
|
|
200
200
|
|
|
201
|
+
string str() const;
|
|
202
|
+
|
|
201
203
|
protected:
|
|
202
204
|
IndicatorImpPtr m_imp;
|
|
203
205
|
|
|
@@ -383,6 +385,13 @@ HKU_API Indicator operator|(Indicator::value_t, const Indicator&);
|
|
|
383
385
|
*/
|
|
384
386
|
Indicator HKU_API WEAVE(const Indicator& ind1, const Indicator& ind2);
|
|
385
387
|
|
|
388
|
+
template <typename... Args>
|
|
389
|
+
inline Indicator WEAVE(const Indicator& ind1, const Indicator& ind2, const Args&... others) {
|
|
390
|
+
HKU_CHECK(sizeof...(others) <= 4, "WEAVE() only support 6 Indicator!");
|
|
391
|
+
Indicator tmp = WEAVE(ind1, ind2);
|
|
392
|
+
return WEAVE(std::move(tmp), others...);
|
|
393
|
+
}
|
|
394
|
+
|
|
386
395
|
/**
|
|
387
396
|
* 条件函数, 根据条件求不同的值。
|
|
388
397
|
* @details
|
|
@@ -402,6 +411,21 @@ Indicator HKU_API IF(const Indicator& x, Indicator::value_t a, Indicator::value_
|
|
|
402
411
|
|
|
403
412
|
} /* namespace hku */
|
|
404
413
|
|
|
414
|
+
namespace std {
|
|
415
|
+
template <>
|
|
416
|
+
class hash<hku::Indicator> {
|
|
417
|
+
public:
|
|
418
|
+
size_t operator()(hku::Indicator const& ind) const noexcept {
|
|
419
|
+
auto imp = ind.getImp();
|
|
420
|
+
return imp.get() ? std::hash<hku::IndicatorImpPtr>()(imp) : 0;
|
|
421
|
+
}
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
inline string to_string(const hku::Indicator& ind) {
|
|
425
|
+
return ind.str();
|
|
426
|
+
}
|
|
427
|
+
} // namespace std
|
|
428
|
+
|
|
405
429
|
#if FMT_VERSION >= 90000
|
|
406
430
|
template <>
|
|
407
431
|
struct fmt::formatter<hku::Indicator> : ostream_formatter {};
|
|
@@ -47,6 +47,7 @@ private: \
|
|
|
47
47
|
friend class boost::serialization::access; \
|
|
48
48
|
template <class Archive> \
|
|
49
49
|
void serialize(Archive& ar, const unsigned int version) { \
|
|
50
|
+
ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(IndicatorImp); \
|
|
50
51
|
ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(Indicator2InImp); \
|
|
51
52
|
}
|
|
52
53
|
#else
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
#include "crt/ISNA.h"
|
|
67
67
|
#include "crt/JUMPUP.h"
|
|
68
68
|
#include "crt/JUMPDOWN.h"
|
|
69
|
+
#include "crt/KALMAN.h"
|
|
69
70
|
#include "crt/LAST.h"
|
|
70
71
|
#include "crt/LASTVALUE.h"
|
|
71
72
|
#include "crt/LIUTONGPAN.h"
|
|
@@ -115,6 +116,7 @@
|
|
|
115
116
|
#include "crt/TIME.h"
|
|
116
117
|
#include "crt/TIMELINE.h"
|
|
117
118
|
#include "crt/TIMELINEVOL.h"
|
|
119
|
+
#include "crt/TR.h"
|
|
118
120
|
#include "crt/TURNOVER.h"
|
|
119
121
|
#include "crt/UPNDAY.h"
|
|
120
122
|
#include "crt/VAR.h"
|
|
@@ -14,12 +14,11 @@
|
|
|
14
14
|
namespace hku {
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* 平均真实波幅(Average True Range)
|
|
17
|
+
* 平均真实波幅(Average True Range), TR 的简单平均值
|
|
18
18
|
* @param n 计算均值的周期窗口,必须为大于1的整数
|
|
19
19
|
* @ingroup Indicator
|
|
20
20
|
*/
|
|
21
21
|
Indicator HKU_API ATR(int n = 14);
|
|
22
|
-
Indicator HKU_API ATR(const IndParam& n);
|
|
23
22
|
|
|
24
23
|
/**
|
|
25
24
|
* 平均真实波幅(Average True Range)
|
|
@@ -27,17 +26,7 @@ Indicator HKU_API ATR(const IndParam& n);
|
|
|
27
26
|
* @param n 计算均值的周期窗口,必须为大于1的整数
|
|
28
27
|
* @ingroup Indicator
|
|
29
28
|
*/
|
|
30
|
-
|
|
31
|
-
return ATR(n)(data);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
inline Indicator HKU_API ATR(const Indicator& data, const IndParam& n) {
|
|
35
|
-
return ATR(n)(data);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
inline Indicator HKU_API ATR(const Indicator& data, const Indicator& n) {
|
|
39
|
-
return ATR(IndParam(n))(data);
|
|
40
|
-
}
|
|
29
|
+
Indicator HKU_API ATR(const KData& kdata, int n = 14);
|
|
41
30
|
|
|
42
31
|
} // namespace hku
|
|
43
32
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 hikyuu.org
|
|
3
|
+
*
|
|
4
|
+
* Created on: 2025-03-02
|
|
5
|
+
* Author: fasiondog
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
#ifndef INDICATOR_CRT_KALMAN_H_
|
|
10
|
+
#define INDICATOR_CRT_KALMAN_H_
|
|
11
|
+
|
|
12
|
+
#include "CVAL.h"
|
|
13
|
+
|
|
14
|
+
namespace hku {
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 卡尔曼滤波
|
|
18
|
+
* @param q 噪声方差
|
|
19
|
+
* @param r 测量噪声方差
|
|
20
|
+
* @ingroup Indicator
|
|
21
|
+
*/
|
|
22
|
+
Indicator HKU_API KALMAN(double q = 0.01, double r = 0.1);
|
|
23
|
+
|
|
24
|
+
inline Indicator KALMAN(const Indicator& ind, double q = 0.01, double r = 0.1) {
|
|
25
|
+
return KALMAN(q, r)(ind);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
} // namespace hku
|
|
29
|
+
|
|
30
|
+
#endif /* INDICATOR_CRT_KALMAN_H_ */
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* TRG.h
|
|
3
|
+
*
|
|
4
|
+
* Created on: 2019年3月6日
|
|
5
|
+
* Author: fasiondog
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
#ifndef INDICATOR_CRT_TR_H_
|
|
10
|
+
#define INDICATOR_CRT_TR_H_
|
|
11
|
+
|
|
12
|
+
#include "../Indicator.h"
|
|
13
|
+
|
|
14
|
+
namespace hku {
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @brief 真实波动幅度(TR)
|
|
18
|
+
* @details
|
|
19
|
+
* <pre>
|
|
20
|
+
* 真实波动幅度(TR)是以下三个值中的最大值:
|
|
21
|
+
* 1. 当前周期最高价(H)与最低价(L)之差
|
|
22
|
+
* 2. 当前周期最高价与前一周期收盘价(PC)之差的绝对值
|
|
23
|
+
* 3. 当前周期最低价与前一周期收盘价之差的绝对值
|
|
24
|
+
* </pre>
|
|
25
|
+
* @ingroup Indicator
|
|
26
|
+
*/
|
|
27
|
+
Indicator HKU_API TR();
|
|
28
|
+
Indicator HKU_API TR(const KData&);
|
|
29
|
+
|
|
30
|
+
} // namespace hku
|
|
31
|
+
|
|
32
|
+
#endif /* INDICATOR_CRT_TR_H_ */
|