hikyuu 2.5.6__py3-none-win_amd64.whl → 2.6.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/__init__.py +33 -49
- hikyuu/__init__.pyi +530 -516
- hikyuu/analysis/__init__.pyi +498 -490
- hikyuu/analysis/analysis.pyi +499 -491
- hikyuu/core.pyi +500 -492
- hikyuu/cpp/__init__.pyi +2 -2
- hikyuu/cpp/boost_date_time-mt.dll +0 -0
- hikyuu/cpp/boost_serialization-mt.dll +0 -0
- hikyuu/cpp/boost_wserialization-mt.dll +0 -0
- hikyuu/cpp/core310.pyd +0 -0
- hikyuu/cpp/core310.pyi +187 -22
- hikyuu/cpp/core311.pyd +0 -0
- hikyuu/cpp/core311.pyi +187 -22
- hikyuu/cpp/core312.pyd +0 -0
- hikyuu/cpp/core312.pyi +187 -22
- hikyuu/cpp/core313.pyd +0 -0
- hikyuu/cpp/core313.pyi +186 -22
- hikyuu/cpp/core39.pyd +0 -0
- hikyuu/cpp/core39.pyi +187 -22
- hikyuu/cpp/hikyuu.dll +0 -0
- hikyuu/cpp/hikyuu.lib +0 -0
- hikyuu/draw/__init__.pyi +1 -1
- hikyuu/draw/drawplot/__init__.py +2 -0
- hikyuu/draw/drawplot/__init__.pyi +9 -8
- hikyuu/draw/drawplot/bokeh_draw.pyi +519 -506
- hikyuu/draw/drawplot/common.pyi +1 -1
- hikyuu/draw/drawplot/echarts_draw.pyi +521 -508
- hikyuu/draw/drawplot/matplotlib_draw.py +80 -0
- hikyuu/draw/drawplot/matplotlib_draw.pyi +540 -517
- hikyuu/draw/elder.pyi +11 -11
- hikyuu/draw/kaufman.pyi +18 -18
- hikyuu/draw/volume.pyi +10 -10
- hikyuu/examples/notebook/002-HowToGetStock.ipynb +1 -1
- hikyuu/examples/notebook/004-IndicatorOverview.ipynb +117 -52
- hikyuu/extend.pyi +507 -500
- hikyuu/gui/HikyuuTDX.py +85 -15
- hikyuu/gui/data/ImportQmtToH5Task.py +209 -0
- hikyuu/gui/data/ImportTdxToH5Task.py +8 -1
- hikyuu/gui/data/MainWindow.py +94 -13
- hikyuu/gui/data/UseQmtImportToH5Thread.py +316 -0
- hikyuu/gui/data/UseTdxImportToH5Thread.py +221 -65
- hikyuu/gui/dataserver.py +25 -0
- hikyuu/gui/images/star.png +0 -0
- hikyuu/gui/importdata.py +24 -11
- hikyuu/hub.pyi +6 -6
- hikyuu/include/hikyuu/KData.h +5 -0
- hikyuu/include/hikyuu/KDataImp.h +4 -0
- hikyuu/include/hikyuu/StockManager.h +23 -0
- hikyuu/include/hikyuu/data_driver/kdata/mysql/KRecordTable.h +41 -2
- hikyuu/include/hikyuu/global/agent/spot_generated.h +3 -3
- hikyuu/include/hikyuu/indicator/crt/COUNT.h +3 -3
- hikyuu/include/hikyuu/indicator/crt/DISCARD.h +1 -1
- hikyuu/include/hikyuu/indicator/crt/ISINF.h +1 -1
- hikyuu/include/hikyuu/indicator/crt/ISINFA.h +1 -1
- hikyuu/include/hikyuu/indicator/crt/ISNA.h +1 -1
- hikyuu/include/hikyuu/indicator/crt/LAST.h +2 -2
- hikyuu/include/hikyuu/indicator/crt/MAX.h +1 -1
- hikyuu/include/hikyuu/indicator/crt/MIN.h +1 -1
- hikyuu/include/hikyuu/indicator/crt/PRICELIST.h +1 -15
- hikyuu/include/hikyuu/indicator/crt/SUMBARS.h +1 -1
- hikyuu/include/hikyuu/plugin/KDataToHdf5Importer.h +33 -0
- hikyuu/include/hikyuu/plugin/__init__.py +1 -0
- hikyuu/include/hikyuu/plugin/backtest.h +37 -0
- hikyuu/include/hikyuu/plugin/dataserver.h +18 -0
- hikyuu/include/hikyuu/plugin/device.h +29 -0
- hikyuu/include/hikyuu/plugin/interface/BackTestPluginInterface.h +26 -0
- hikyuu/include/hikyuu/plugin/interface/DataServerPluginInterface.h +23 -0
- hikyuu/include/hikyuu/plugin/interface/DevicePluginInterface.h +25 -0
- hikyuu/include/hikyuu/plugin/interface/ImportKDataToHdf5PluginInterface.h +33 -0
- hikyuu/include/hikyuu/plugin/interface/__init__.py +1 -0
- hikyuu/include/hikyuu/plugin/interface/plugins.h +22 -0
- hikyuu/include/hikyuu/python/pybind_utils.h +8 -0
- hikyuu/include/hikyuu/strategy/BrokerTradeManager.h +2 -1
- hikyuu/include/hikyuu/strategy/RunPortfolioInStrategy.h +1 -0
- hikyuu/include/hikyuu/strategy/Strategy.h +93 -16
- hikyuu/include/hikyuu/trade_manage/TradeManagerBase.h +4 -2
- hikyuu/include/hikyuu/trade_sys/portfolio/Portfolio.h +2 -1
- hikyuu/include/hikyuu/trade_sys/selector/SelectorBase.h +12 -9
- hikyuu/include/hikyuu/trade_sys/selector/imp/MultiFactorSelector.h +1 -1
- hikyuu/include/hikyuu/trade_sys/selector/imp/logic/OperatorSelector.h +12 -12
- hikyuu/include/hikyuu/trade_sys/selector/imp/logic/OperatorValueSelector.h +2 -2
- hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/PerformanceOptimalSelector.h +1 -1
- hikyuu/include/hikyuu/trade_sys/system/System.h +12 -3
- hikyuu/include/hikyuu/trade_sys/system/imp/DelegateSystem.h +0 -1
- hikyuu/include/hikyuu/trade_sys/system/imp/WalkForwardSystem.h +0 -1
- hikyuu/include/hikyuu/trade_sys/system/imp/WalkForwardTradeManager.h +3 -2
- hikyuu/include/hikyuu/utilities/arithmetic.h +32 -22
- hikyuu/include/hikyuu/utilities/datetime/Datetime.h +1 -0
- hikyuu/include/hikyuu/utilities/plugin/PluginClient.h +2 -2
- hikyuu/include/hikyuu/utilities/plugin/PluginLoader.h +66 -13
- hikyuu/include/hikyuu/utilities/plugin/PluginManager.h +72 -0
- hikyuu/include/hikyuu/version.h +5 -5
- hikyuu/plugin/__init__.py +1 -0
- hikyuu/plugin/backtest.dll +0 -0
- hikyuu/plugin/dataserver.dll +0 -0
- hikyuu/plugin/device.dll +0 -0
- hikyuu/plugin/import2hdf5.dll +0 -0
- hikyuu/strategy/strategy_demo1.py +7 -8
- hikyuu/strategy/strategy_demo2.py +1 -1
- hikyuu/trade_manage/__init__.pyi +518 -505
- hikyuu/trade_manage/broker.pyi +3 -3
- hikyuu/trade_manage/broker_easytrader.pyi +1 -1
- hikyuu/trade_manage/trade.pyi +518 -505
- hikyuu/util/__init__.py +1 -0
- hikyuu/util/__init__.pyi +2 -1
- hikyuu/util/mylog.py +30 -3
- hikyuu/util/mylog.pyi +3 -1
- hikyuu/util/singleton.pyi +1 -1
- {hikyuu-2.5.6.dist-info → hikyuu-2.6.1.dist-info}/METADATA +6 -2
- {hikyuu-2.5.6.dist-info → hikyuu-2.6.1.dist-info}/RECORD +115 -97
- {hikyuu-2.5.6.dist-info → hikyuu-2.6.1.dist-info}/entry_points.txt +1 -0
- {hikyuu-2.5.6.dist-info → hikyuu-2.6.1.dist-info}/top_level.txt +4 -0
- hikyuu/cpp/core38.pyd +0 -0
- hikyuu/cpp/core38.pyi +0 -13173
- hikyuu/examples/notebook/011-PyechartsDrawplot.ipynb +0 -21821
- /hikyuu/gui/{hikyuu_small.png → images/hikyuu_small.png} +0 -0
- {hikyuu-2.5.6.dist-info → hikyuu-2.6.1.dist-info}/LICENSE +0 -0
- {hikyuu-2.5.6.dist-info → hikyuu-2.6.1.dist-info}/WHEEL +0 -0
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
10
10
|
#include <future>
|
|
11
|
+
#include <forward_list>
|
|
11
12
|
#include "hikyuu/DataType.h"
|
|
12
13
|
#include "hikyuu/StrategyContext.h"
|
|
13
14
|
#include "hikyuu/global/SpotRecord.h"
|
|
@@ -34,7 +35,8 @@ public:
|
|
|
34
35
|
Strategy();
|
|
35
36
|
explicit Strategy(const string& name, const string& config_file = "");
|
|
36
37
|
Strategy(const vector<string>& codeList, const vector<KQuery::KType>& ktypeList,
|
|
37
|
-
const string
|
|
38
|
+
const unordered_map<string, int>& preloadNum = {}, const string& name = "Strategy",
|
|
39
|
+
const string& config_file = "");
|
|
38
40
|
explicit Strategy(const StrategyContext& context, const string& name = "Strategy",
|
|
39
41
|
const string& config_file = "");
|
|
40
42
|
|
|
@@ -55,14 +57,16 @@ public:
|
|
|
55
57
|
return m_context;
|
|
56
58
|
}
|
|
57
59
|
|
|
60
|
+
bool running() const;
|
|
61
|
+
|
|
58
62
|
/**
|
|
59
63
|
* 每日开盘时间内,以 delta 为周期循环定时执行指定任务
|
|
60
64
|
* @param func 待执行的任务
|
|
61
65
|
* @param delta 间隔时间
|
|
62
|
-
* @param market
|
|
66
|
+
* @param market 指定的市场, 用于获取开/收盘时间
|
|
63
67
|
* @param ignoreMarket 是否忽略市场时间限制,如为 true,则为定时循环不受开闭市时间限制
|
|
64
68
|
*/
|
|
65
|
-
void runDaily(std::function<void()
|
|
69
|
+
void runDaily(const std::function<void(Strategy*)>& func, const TimeDelta& delta,
|
|
66
70
|
const std::string& market = "SH", bool ignoreMarket = false);
|
|
67
71
|
|
|
68
72
|
/**
|
|
@@ -71,7 +75,7 @@ public:
|
|
|
71
75
|
* @param delta 指定时刻
|
|
72
76
|
* @param ignoreHoliday 忽略节假日,即节假日不执行
|
|
73
77
|
*/
|
|
74
|
-
void runDailyAt(std::function<void()
|
|
78
|
+
void runDailyAt(const std::function<void(Strategy*)>& func, const TimeDelta& delta,
|
|
75
79
|
bool ignoreHoliday = true);
|
|
76
80
|
|
|
77
81
|
/**
|
|
@@ -79,7 +83,8 @@ public:
|
|
|
79
83
|
* @note 通常用于调试。且只要收到行情采集消息就会触发,不受开、闭市时间限制
|
|
80
84
|
* @param changeFunc 回调函数
|
|
81
85
|
*/
|
|
82
|
-
void onChange(
|
|
86
|
+
void onChange(
|
|
87
|
+
const std::function<void(Strategy*, const Stock&, const SpotRecord& spot)>& changeFunc);
|
|
83
88
|
|
|
84
89
|
/**
|
|
85
90
|
* 一批行情数据接受完毕后通知
|
|
@@ -87,36 +92,108 @@ public:
|
|
|
87
92
|
* 且只要收到行情采集消息就会触发,不受开、闭市时间限制。
|
|
88
93
|
* @param recievedFucn 回调函数
|
|
89
94
|
*/
|
|
90
|
-
void onReceivedSpot(std::function<void(const Datetime&)
|
|
95
|
+
void onReceivedSpot(const std::function<void(Strategy*, const Datetime&)>& recievedFucn);
|
|
91
96
|
|
|
92
97
|
/**
|
|
93
98
|
* 启动策略执行,必须在已注册相关处理函数后执行
|
|
94
99
|
*/
|
|
95
100
|
void start(bool autoRecieveSpot = true);
|
|
96
101
|
|
|
97
|
-
|
|
102
|
+
//==========================================================================
|
|
103
|
+
// 以下为策略运行时对外接口,建议使用这些接口代替同名其他功能函数,已保证回测和实盘一致
|
|
104
|
+
//==========================================================================
|
|
105
|
+
|
|
106
|
+
TradeManagerPtr getTM() const noexcept {
|
|
107
|
+
return m_tm;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
void setTM(const TradeManagerPtr& tm) noexcept {
|
|
111
|
+
m_tm = tm;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** 仅在回测状态下使用 */
|
|
115
|
+
SlippagePtr getSP() const noexcept {
|
|
116
|
+
return m_sp;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
void setSP(const SlippagePtr& slippage) noexcept {
|
|
120
|
+
m_sp = slippage;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
KData getLastKData(const Stock& stk, const Datetime& start_date, const KQuery::KType& ktype,
|
|
124
|
+
KQuery::RecoverType recover_type = KQuery::NO_RECOVER) const {
|
|
125
|
+
return getKData(stk, start_date, Null<Datetime>(), ktype, recover_type);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
KData getLastKData(const Stock& stk, size_t lastnum, const KQuery::KType& ktype,
|
|
129
|
+
KQuery::RecoverType recover_type = KQuery::NO_RECOVER) const;
|
|
130
|
+
|
|
131
|
+
virtual KData getKData(const Stock& stk, const Datetime& start_date, const Datetime& end_date,
|
|
132
|
+
const KQuery::KType& ktype,
|
|
133
|
+
KQuery::RecoverType recover_type = KQuery::NO_RECOVER) const;
|
|
134
|
+
virtual Datetime today() const {
|
|
135
|
+
return Datetime::today();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
virtual Datetime now() const {
|
|
139
|
+
return Datetime::now();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
virtual Datetime nextDatetime() const {
|
|
143
|
+
return Null<Datetime>();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
virtual TradeRecord buy(const Stock& stk, price_t price, double num, double stoploss = 0.0,
|
|
147
|
+
double goal_price = 0.0,
|
|
148
|
+
SystemPart part_from = SystemPart::PART_SIGNAL) {
|
|
149
|
+
HKU_ASSERT(m_tm);
|
|
150
|
+
return m_tm->buy(Datetime::now(), stk, price, num, stoploss, goal_price, price, part_from);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
virtual TradeRecord sell(const Stock& stk, price_t price, double num, price_t stoploss = 0.0,
|
|
154
|
+
price_t goal_price = 0.0,
|
|
155
|
+
SystemPart part_from = SystemPart::PART_SIGNAL) {
|
|
156
|
+
HKU_ASSERT(m_tm);
|
|
157
|
+
return m_tm->sell(Datetime::now(), stk, price, num, stoploss, goal_price, price, part_from);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
virtual bool isBacktesting() const {
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
protected:
|
|
98
165
|
string m_name;
|
|
99
166
|
string m_config_file;
|
|
100
167
|
StrategyContext m_context;
|
|
101
|
-
|
|
102
|
-
|
|
168
|
+
TradeManagerPtr m_tm;
|
|
169
|
+
SlippagePtr m_sp;
|
|
170
|
+
|
|
171
|
+
std::function<void(Strategy*, const Datetime&)> m_on_recieved_spot;
|
|
172
|
+
std::function<void(Strategy*, const Stock&, const SpotRecord& spot)> m_on_change;
|
|
173
|
+
|
|
174
|
+
struct RunDailyAt {
|
|
175
|
+
std::function<void()> func;
|
|
176
|
+
TimeDelta delta;
|
|
177
|
+
string market;
|
|
178
|
+
bool ignoreMarket{false};
|
|
179
|
+
};
|
|
180
|
+
std::forward_list<RunDailyAt> m_run_daily_at_list;
|
|
181
|
+
|
|
182
|
+
std::unordered_map<TimeDelta, std::function<void()>> m_run_daily_at_funcs;
|
|
103
183
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
string m_run_daily_market;
|
|
107
|
-
bool m_ignoreMarket{false};
|
|
184
|
+
protected:
|
|
185
|
+
static std::atomic_bool ms_keep_running;
|
|
108
186
|
|
|
109
|
-
|
|
187
|
+
protected:
|
|
188
|
+
void _init();
|
|
110
189
|
|
|
111
190
|
private:
|
|
112
191
|
void _initParam();
|
|
113
|
-
void _init();
|
|
114
192
|
void _receivedSpot(const SpotRecord& spot);
|
|
115
193
|
void _runDaily();
|
|
116
194
|
void _runDailyAt();
|
|
117
195
|
|
|
118
196
|
private:
|
|
119
|
-
static std::atomic_bool ms_keep_running;
|
|
120
197
|
static void sig_handler(int sig);
|
|
121
198
|
|
|
122
199
|
typedef FuncWrapper event_type;
|
|
@@ -697,8 +697,10 @@ public:
|
|
|
697
697
|
/**
|
|
698
698
|
* 从订单代理实例同步当前账户资产信息(包含资金、持仓等)
|
|
699
699
|
* @param broker 订单代理实例
|
|
700
|
+
* @param datetime 同步时,通常为当前时间(Null),也可以强制为指定的时间点
|
|
700
701
|
*/
|
|
701
|
-
virtual void fetchAssetInfoFromBroker(const OrderBrokerPtr& broker
|
|
702
|
+
virtual void fetchAssetInfoFromBroker(const OrderBrokerPtr& broker,
|
|
703
|
+
const Datetime& datetime = Null<Datetime>()) {
|
|
702
704
|
HKU_WARN("The subclass does not implement this method");
|
|
703
705
|
}
|
|
704
706
|
|
|
@@ -706,7 +708,7 @@ protected:
|
|
|
706
708
|
string m_name; // 账户名称
|
|
707
709
|
TradeCostPtr m_costfunc; // 成本算法
|
|
708
710
|
|
|
709
|
-
Datetime m_broker_last_datetime;
|
|
711
|
+
Datetime m_broker_last_datetime; // 订单代理最近一次执行操作的时刻,当前启动运行时间
|
|
710
712
|
list<OrderBrokerPtr> m_broker_list; // 订单代理列表
|
|
711
713
|
|
|
712
714
|
//============================================
|
|
@@ -116,7 +116,8 @@ private:
|
|
|
116
116
|
|
|
117
117
|
protected:
|
|
118
118
|
// 跟踪打印当前TM持仓情况
|
|
119
|
-
void
|
|
119
|
+
void traceMomentTMAfterRunAtOpen(const Datetime& date);
|
|
120
|
+
void traceMomentTMAfterRunAtClose(const Datetime& date);
|
|
120
121
|
|
|
121
122
|
protected:
|
|
122
123
|
string m_name;
|
|
@@ -87,6 +87,9 @@ public:
|
|
|
87
87
|
*/
|
|
88
88
|
const SystemList& getRealSystemList() const;
|
|
89
89
|
|
|
90
|
+
/** 获取指定时刻收盘时选中的标的 */
|
|
91
|
+
SystemWeightList getSelected(Datetime date);
|
|
92
|
+
|
|
90
93
|
/**
|
|
91
94
|
* @brief 复位
|
|
92
95
|
* @note 复位不会清除已有的原型系统
|
|
@@ -111,7 +114,7 @@ public:
|
|
|
111
114
|
virtual void _calculate() = 0;
|
|
112
115
|
|
|
113
116
|
/** 子类获取指定时刻收盘时选中的标的 */
|
|
114
|
-
virtual SystemWeightList
|
|
117
|
+
virtual SystemWeightList _getSelected(Datetime date) = 0;
|
|
115
118
|
|
|
116
119
|
virtual bool isMatchAF(const AFPtr& af) = 0;
|
|
117
120
|
|
|
@@ -141,7 +144,7 @@ protected:
|
|
|
141
144
|
KQuery m_query;
|
|
142
145
|
KQuery m_proto_query;
|
|
143
146
|
|
|
144
|
-
SystemList m_pro_sys_list;
|
|
147
|
+
SystemList m_pro_sys_list; // 原型系统列表
|
|
145
148
|
SystemList m_real_sys_list; // PF组合中实际运行的系统,有PF执行时设定,顺序与原型列表一一对应
|
|
146
149
|
|
|
147
150
|
//============================================
|
|
@@ -197,13 +200,13 @@ private: \
|
|
|
197
200
|
#define SELECTOR_NO_PRIVATE_MEMBER_SERIALIZATION
|
|
198
201
|
#endif
|
|
199
202
|
|
|
200
|
-
#define SELECTOR_IMP(classname)
|
|
201
|
-
public:
|
|
202
|
-
virtual SelectorPtr _clone() override {
|
|
203
|
-
return std::make_shared<classname>();
|
|
204
|
-
}
|
|
205
|
-
virtual SystemWeightList
|
|
206
|
-
virtual bool isMatchAF(const AFPtr& af) override;
|
|
203
|
+
#define SELECTOR_IMP(classname) \
|
|
204
|
+
public: \
|
|
205
|
+
virtual SelectorPtr _clone() override { \
|
|
206
|
+
return std::make_shared<classname>(); \
|
|
207
|
+
} \
|
|
208
|
+
virtual SystemWeightList _getSelected(Datetime date) override; \
|
|
209
|
+
virtual bool isMatchAF(const AFPtr& af) override; \
|
|
207
210
|
virtual void _calculate() override;
|
|
208
211
|
|
|
209
212
|
/**
|
|
@@ -21,7 +21,7 @@ public:
|
|
|
21
21
|
virtual void _checkParam(const string& name) const override;
|
|
22
22
|
virtual void _reset() override;
|
|
23
23
|
virtual SelectorPtr _clone() override;
|
|
24
|
-
virtual SystemWeightList
|
|
24
|
+
virtual SystemWeightList _getSelected(Datetime date) override;
|
|
25
25
|
virtual bool isMatchAF(const AFPtr& af) override;
|
|
26
26
|
virtual void _calculate() override;
|
|
27
27
|
|
|
@@ -22,7 +22,7 @@ public:
|
|
|
22
22
|
virtual SelectorPtr _clone() override;
|
|
23
23
|
virtual bool isMatchAF(const AFPtr& af) override;
|
|
24
24
|
virtual void _calculate() override;
|
|
25
|
-
virtual SystemWeightList
|
|
25
|
+
virtual SystemWeightList _getSelected(Datetime date) override {
|
|
26
26
|
return SystemWeightList();
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -80,17 +80,17 @@ private:
|
|
|
80
80
|
#endif
|
|
81
81
|
};
|
|
82
82
|
|
|
83
|
-
#define OPERATOR_SELECTOR_IMP(classname, name)
|
|
84
|
-
public:
|
|
85
|
-
classname() : OperatorSelector(name) {}
|
|
86
|
-
classname(const SelectorPtr& se1, const SelectorPtr& se2)
|
|
87
|
-
: OperatorSelector(name, se1, se2) {}
|
|
88
|
-
virtual ~classname() {}
|
|
89
|
-
|
|
90
|
-
virtual SystemWeightList
|
|
91
|
-
|
|
92
|
-
virtual SelectorPtr _clone() override {
|
|
93
|
-
HKU_THROW("OperatorSelector Could't support clone!");
|
|
83
|
+
#define OPERATOR_SELECTOR_IMP(classname, name) \
|
|
84
|
+
public: \
|
|
85
|
+
classname() : OperatorSelector(name) {} \
|
|
86
|
+
classname(const SelectorPtr& se1, const SelectorPtr& se2) \
|
|
87
|
+
: OperatorSelector(name, se1, se2) {} \
|
|
88
|
+
virtual ~classname() {} \
|
|
89
|
+
\
|
|
90
|
+
virtual SystemWeightList _getSelected(Datetime date) override; \
|
|
91
|
+
\
|
|
92
|
+
virtual SelectorPtr _clone() override { \
|
|
93
|
+
HKU_THROW("OperatorSelector Could't support clone!"); \
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
#if HKU_SUPPORT_SERIALIZATION
|
|
@@ -22,7 +22,7 @@ public:
|
|
|
22
22
|
virtual SelectorPtr _clone() override;
|
|
23
23
|
virtual bool isMatchAF(const AFPtr& af) override;
|
|
24
24
|
virtual void _calculate() override;
|
|
25
|
-
virtual SystemWeightList
|
|
25
|
+
virtual SystemWeightList _getSelected(Datetime date) override {
|
|
26
26
|
return SystemWeightList();
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -68,7 +68,7 @@ public:
|
|
|
68
68
|
classname(const SelectorPtr& se, double value) : OperatorValueSelector(name, se, value) {} \
|
|
69
69
|
virtual ~classname() {} \
|
|
70
70
|
\
|
|
71
|
-
virtual SystemWeightList
|
|
71
|
+
virtual SystemWeightList _getSelected(Datetime date) override; \
|
|
72
72
|
\
|
|
73
73
|
virtual SelectorPtr _clone() override { \
|
|
74
74
|
auto p = std::make_shared<classname>(); \
|
|
@@ -22,7 +22,7 @@ public:
|
|
|
22
22
|
virtual void _checkParam(const string& name) const override;
|
|
23
23
|
virtual void calculate(const SystemList& pf_realSysList, const KQuery& query) override;
|
|
24
24
|
|
|
25
|
-
virtual SystemWeightList
|
|
25
|
+
virtual SystemWeightList _getSelected(Datetime date) override;
|
|
26
26
|
virtual SelectorPtr _clone() override;
|
|
27
27
|
virtual void _reset() override;
|
|
28
28
|
|
|
@@ -251,11 +251,20 @@ public:
|
|
|
251
251
|
virtual void clearDelayBuyRequest();
|
|
252
252
|
|
|
253
253
|
// 当前是否存在延迟的操作请求,供Portfolio
|
|
254
|
-
|
|
254
|
+
bool haveDelaySellRequest() const {
|
|
255
|
+
return m_sellRequest.valid;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
bool haveDelayBuyRequest() const {
|
|
259
|
+
return m_buyRequest.valid;
|
|
260
|
+
}
|
|
255
261
|
|
|
256
262
|
// 处理延迟买入请求,仅供 PF 调用
|
|
257
263
|
virtual TradeRecord pfProcessDelaySellRequest(const Datetime& date);
|
|
258
264
|
|
|
265
|
+
// 处理延迟买入请求,仅供 PF 调用
|
|
266
|
+
virtual TradeRecord pfProcessDelayBuyRequest(const Datetime& date);
|
|
267
|
+
|
|
259
268
|
private:
|
|
260
269
|
bool _environmentIsValid(const Datetime& datetime);
|
|
261
270
|
bool _conditionIsValid(const Datetime& datetime);
|
|
@@ -329,8 +338,8 @@ protected:
|
|
|
329
338
|
bool m_pre_ev_valid;
|
|
330
339
|
bool m_pre_cn_valid;
|
|
331
340
|
|
|
332
|
-
int m_buy_days;
|
|
333
|
-
int m_sell_short_days;
|
|
341
|
+
int m_buy_days; // 每一次买入清零,计算一次加1,即买入后的天数
|
|
342
|
+
int m_sell_short_days; // 每一次卖空清零
|
|
334
343
|
TradeRecordList m_trade_list; // 保存实际执行的交易记录
|
|
335
344
|
price_t m_lastTakeProfit; // 上一次多头止损价,用于保证止赢价单调递增
|
|
336
345
|
price_t m_lastShortTakeProfit; // 上一次空头止赢价
|
|
@@ -28,7 +28,6 @@ public:
|
|
|
28
28
|
virtual TradeRecord sellForceOnOpen(const Datetime& date, double num, Part from) override;
|
|
29
29
|
virtual TradeRecord sellForceOnClose(const Datetime& date, double num, Part from) override;
|
|
30
30
|
virtual void clearDelayBuyRequest() override;
|
|
31
|
-
virtual bool haveDelaySellRequest() const override;
|
|
32
31
|
virtual TradeRecord pfProcessDelaySellRequest(const Datetime& date) override;
|
|
33
32
|
|
|
34
33
|
private:
|
|
@@ -36,7 +36,6 @@ public:
|
|
|
36
36
|
virtual TradeRecord sellForceOnOpen(const Datetime& date, double num, Part from) override;
|
|
37
37
|
virtual TradeRecord sellForceOnClose(const Datetime& date, double num, Part from) override;
|
|
38
38
|
virtual void clearDelayBuyRequest() override;
|
|
39
|
-
virtual bool haveDelaySellRequest() const override;
|
|
40
39
|
virtual TradeRecord pfProcessDelaySellRequest(const Datetime& date) override;
|
|
41
40
|
|
|
42
41
|
private:
|
|
@@ -437,8 +437,9 @@ public:
|
|
|
437
437
|
* 从订单代理实例同步当前账户资产信息(包含资金、持仓等)
|
|
438
438
|
* @param broker 订单代理实例
|
|
439
439
|
*/
|
|
440
|
-
virtual void fetchAssetInfoFromBroker(const OrderBrokerPtr& broker
|
|
441
|
-
|
|
440
|
+
virtual void fetchAssetInfoFromBroker(const OrderBrokerPtr& broker,
|
|
441
|
+
const Datetime& datetime = Null<Datetime>()) override {
|
|
442
|
+
m_tm->fetchAssetInfoFromBroker(broker, datetime);
|
|
442
443
|
}
|
|
443
444
|
|
|
444
445
|
private:
|
|
@@ -85,29 +85,39 @@ std::string HKU_UTILS_API gb_to_utf8(const std::string &szinput);
|
|
|
85
85
|
template <typename ValueT>
|
|
86
86
|
ValueT roundEx(ValueT number, int ndigits = 0) {
|
|
87
87
|
// 切换至:ROUND_HALF_EVEN 银行家舍入法
|
|
88
|
-
ValueT pow1, pow2, y, z;
|
|
89
|
-
ValueT x = number;
|
|
90
|
-
if (ndigits >= 0) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
} else {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
z = std::round(y);
|
|
101
|
-
if (std::fabs(y - z) == 0.5)
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (ndigits >= 0)
|
|
106
|
-
|
|
88
|
+
// ValueT pow1, pow2, y, z;
|
|
89
|
+
// ValueT x = number;
|
|
90
|
+
// if (ndigits >= 0) {
|
|
91
|
+
// pow1 = pow(ValueT(10.0), ValueT(ndigits));
|
|
92
|
+
// pow2 = 1.0;
|
|
93
|
+
// y = (x * pow1) * pow2;
|
|
94
|
+
// } else {
|
|
95
|
+
// pow1 = pow(ValueT(10.0), ValueT(-ndigits));
|
|
96
|
+
// pow2 = 1.0;
|
|
97
|
+
// y = x / pow1;
|
|
98
|
+
// }
|
|
99
|
+
|
|
100
|
+
// z = std::round(y);
|
|
101
|
+
// if (std::fabs(y - z) == 0.5)
|
|
102
|
+
// /* halfway between two integers; use round-half-even */
|
|
103
|
+
// z = 2.0 * std::round(y / 2.0);
|
|
104
|
+
|
|
105
|
+
// if (ndigits >= 0)
|
|
106
|
+
// z = (z / pow2) / pow1;
|
|
107
|
+
// else
|
|
108
|
+
// z *= pow1;
|
|
109
|
+
|
|
110
|
+
// 国内一般使用传统四舍五入法
|
|
111
|
+
if (ndigits < 0)
|
|
112
|
+
return number; // 无效位数直接返回原值
|
|
113
|
+
|
|
114
|
+
const double factor = std::pow(10.0, ndigits);
|
|
115
|
+
const double epsilon = 1e-10 * factor; // 动态调整epsilon避免精度误差
|
|
116
|
+
|
|
117
|
+
if (number >= 0)
|
|
118
|
+
return static_cast<ValueT>(std::floor(number * factor + 0.5 + epsilon) / factor);
|
|
107
119
|
else
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return z;
|
|
120
|
+
return static_cast<ValueT>(std::ceil(number * factor - 0.5 - epsilon) / factor);
|
|
111
121
|
}
|
|
112
122
|
|
|
113
123
|
/**
|
|
@@ -17,7 +17,7 @@ public:
|
|
|
17
17
|
PluginClient() = delete;
|
|
18
18
|
PluginClient(const std::string &path, const std::string &filename) {
|
|
19
19
|
m_loader = std::make_unique<PluginLoader>(path);
|
|
20
|
-
m_loader->load(filename);
|
|
20
|
+
HKU_CHECK(m_loader->load(filename), "load plugin failed! {}/{}", path, filename);
|
|
21
21
|
m_impl = m_loader->instance<InterfaceT>();
|
|
22
22
|
}
|
|
23
23
|
virtual ~PluginClient() = default;
|
|
@@ -46,7 +46,7 @@ public:
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
protected:
|
|
49
|
-
InterfaceT *m_impl;
|
|
49
|
+
InterfaceT *m_impl{nullptr};
|
|
50
50
|
|
|
51
51
|
protected:
|
|
52
52
|
std::unique_ptr<PluginLoader> m_loader;
|
|
@@ -14,29 +14,29 @@
|
|
|
14
14
|
#include <memory>
|
|
15
15
|
#include "hikyuu/utilities/config.h"
|
|
16
16
|
#include "hikyuu/utilities/osdef.h"
|
|
17
|
+
#include "hikyuu/utilities/os.h"
|
|
17
18
|
#include "hikyuu/utilities/Log.h"
|
|
18
19
|
#include "PluginBase.h"
|
|
19
20
|
|
|
20
21
|
#if HKU_OS_WINDOWS
|
|
21
22
|
#include <windows.h>
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
#ifndef HKU_UTILS_API
|
|
25
|
-
#define HKU_UTILS_API
|
|
23
|
+
#else
|
|
24
|
+
#include <dlfcn.h>
|
|
26
25
|
#endif
|
|
27
26
|
|
|
28
27
|
namespace hku {
|
|
29
28
|
|
|
30
|
-
class
|
|
29
|
+
class PluginLoader final {
|
|
31
30
|
public:
|
|
32
|
-
PluginLoader()
|
|
33
|
-
explicit PluginLoader(const std::string& path)
|
|
31
|
+
PluginLoader() : PluginLoader(".") {}
|
|
32
|
+
explicit PluginLoader(const std::string& path) : m_path(path) {}
|
|
33
|
+
|
|
34
34
|
PluginLoader(const PluginLoader&) = delete;
|
|
35
35
|
PluginLoader(PluginLoader&&) = delete;
|
|
36
36
|
|
|
37
|
-
~PluginLoader()
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
~PluginLoader() {
|
|
38
|
+
unload();
|
|
39
|
+
}
|
|
40
40
|
|
|
41
41
|
template <typename T>
|
|
42
42
|
T* instance() const noexcept {
|
|
@@ -44,10 +44,63 @@ public:
|
|
|
44
44
|
return dynamic_cast<T*>(m_plugin.get());
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
bool load(const std::string& pluginname) noexcept {
|
|
48
|
+
std::string filename = getFileName(pluginname);
|
|
49
|
+
HKU_WARN_IF_RETURN(!existFile(filename), false, "file({}) not exist!", filename);
|
|
50
|
+
|
|
51
|
+
#if HKU_OS_WINDOWS
|
|
52
|
+
m_handle = LoadLibrary(HKU_PATH(filename).c_str());
|
|
53
|
+
#else
|
|
54
|
+
m_handle = dlopen(filename.c_str(), RTLD_LAZY);
|
|
55
|
+
#endif
|
|
56
|
+
HKU_WARN_IF_RETURN(!m_handle, false, "load plugin({}) failed!", filename);
|
|
57
|
+
|
|
58
|
+
typedef PluginBase* (*CreateFunction)();
|
|
59
|
+
CreateFunction createFunction =
|
|
60
|
+
reinterpret_cast<CreateFunction>(getFunciton("createPlugin"));
|
|
61
|
+
HKU_WARN_IF_RETURN(!createFunction, false, "Failed to get plugin({}) handle!", filename);
|
|
62
|
+
|
|
63
|
+
m_plugin.reset(createFunction());
|
|
64
|
+
if (!m_plugin) {
|
|
65
|
+
HKU_ERROR("Failed to create plugin ({})!", filename);
|
|
66
|
+
unload();
|
|
67
|
+
m_plugin.reset();
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
|
|
47
74
|
private:
|
|
48
|
-
void unload() noexcept
|
|
49
|
-
|
|
50
|
-
|
|
75
|
+
void unload() noexcept {
|
|
76
|
+
m_plugin.reset();
|
|
77
|
+
if (m_handle) {
|
|
78
|
+
#if HKU_OS_WINDOWS
|
|
79
|
+
FreeLibrary(m_handle);
|
|
80
|
+
#else
|
|
81
|
+
dlclose(m_handle);
|
|
82
|
+
#endif
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
void* getFunciton(const char* symbol) noexcept {
|
|
87
|
+
#if HKU_OS_WINDOWS
|
|
88
|
+
void* func = GetProcAddress(m_handle, symbol);
|
|
89
|
+
#else
|
|
90
|
+
void* func = dlsym(m_handle, symbol);
|
|
91
|
+
#endif
|
|
92
|
+
return func;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
std::string getFileName(const std::string& pluginname) const noexcept {
|
|
96
|
+
#if HKU_OS_WINDOWS
|
|
97
|
+
return fmt::format("{}/{}.dll", m_path, pluginname);
|
|
98
|
+
#elif HKU_OS_LINUX
|
|
99
|
+
return fmt::format("{}/lib{}.so", m_path, pluginname);
|
|
100
|
+
#elif HKU_OS_OSX
|
|
101
|
+
return fmt::format("{}/lib{}.dylib", m_path, pluginname);
|
|
102
|
+
#endif
|
|
103
|
+
}
|
|
51
104
|
|
|
52
105
|
private:
|
|
53
106
|
#if HKU_OS_WINDOWS
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 hikyuu.org
|
|
3
|
+
*
|
|
4
|
+
* Created on: 2025-04-10
|
|
5
|
+
* Author: fasiondog
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <string>
|
|
11
|
+
#include <memory>
|
|
12
|
+
#include <unordered_map>
|
|
13
|
+
#include <mutex>
|
|
14
|
+
#include "hikyuu/utilities/Log.h"
|
|
15
|
+
#include "hikyuu/utilities/plugin/PluginLoader.h"
|
|
16
|
+
|
|
17
|
+
namespace hku {
|
|
18
|
+
|
|
19
|
+
class PluginManager final {
|
|
20
|
+
public:
|
|
21
|
+
PluginManager() : m_plugin_path(".") {};
|
|
22
|
+
explicit PluginManager(const std::string& plugin_path) : m_plugin_path(plugin_path) {}
|
|
23
|
+
|
|
24
|
+
~PluginManager() = default;
|
|
25
|
+
PluginManager(const PluginManager&) = delete;
|
|
26
|
+
PluginManager(PluginManager&&) = delete;
|
|
27
|
+
PluginManager& operator=(const PluginManager&) = delete;
|
|
28
|
+
PluginManager& operator=(PluginManager&&) = delete;
|
|
29
|
+
|
|
30
|
+
const std::string& pluginPath() const noexcept {
|
|
31
|
+
return m_plugin_path;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
void pluginPath(const std::string& plugin_path) noexcept {
|
|
35
|
+
HKU_TRACE_IF_RETURN(!m_plugins.empty(), void(),
|
|
36
|
+
"Existing loaded plugins, Ignore set plugin path: {}, ", plugin_path);
|
|
37
|
+
m_plugin_path = plugin_path;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
template <typename PluginInterfaceT>
|
|
41
|
+
PluginInterfaceT* getPlugin(const std::string& pluginname) noexcept;
|
|
42
|
+
|
|
43
|
+
private:
|
|
44
|
+
std::unordered_map<std::string, std::unique_ptr<PluginLoader>>::iterator load(
|
|
45
|
+
const std::string& pluginname) noexcept {
|
|
46
|
+
std::lock_guard<std::mutex> lock(m_mutex);
|
|
47
|
+
std::unique_ptr<PluginLoader> loader = std::make_unique<PluginLoader>(m_plugin_path);
|
|
48
|
+
if (loader->load(pluginname)) {
|
|
49
|
+
auto [it, success] = m_plugins.insert(std::make_pair(pluginname, std::move(loader)));
|
|
50
|
+
if (success) {
|
|
51
|
+
return it;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return m_plugins.end();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private:
|
|
58
|
+
std::string m_plugin_path;
|
|
59
|
+
std::unordered_map<std::string, std::unique_ptr<PluginLoader>> m_plugins;
|
|
60
|
+
std::mutex m_mutex;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
template <typename PluginInterfaceT>
|
|
64
|
+
PluginInterfaceT* PluginManager::getPlugin(const std::string& pluginname) noexcept {
|
|
65
|
+
auto it = m_plugins.find(pluginname);
|
|
66
|
+
if (it == m_plugins.end()) {
|
|
67
|
+
it = load(pluginname);
|
|
68
|
+
}
|
|
69
|
+
return it != m_plugins.end() ? it->second->instance<PluginInterfaceT>() : nullptr;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
} // namespace hku
|