hikyuu 2.1.2__cp310-none-win_amd64.whl → 2.1.4__cp310-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/core310.pyd +0 -0
- hikyuu/cpp/hikyuu.dll +0 -0
- hikyuu/data/em_block_to_mysql.py +45 -31
- hikyuu/data/em_block_to_sqlite.py +48 -33
- hikyuu/data/mysql_upgrade/0019.sql +6 -0
- hikyuu/data/mysql_upgrade/0020.sql +4 -0
- hikyuu/data/mysql_upgrade/0021.sql +4 -0
- hikyuu/data/pytdx_to_h5.py +21 -15
- hikyuu/data/pytdx_to_mysql.py +20 -2
- hikyuu/data/pytdx_weight_to_mysql.py +1 -1
- hikyuu/data/pytdx_weight_to_sqlite.py +1 -1
- hikyuu/data/sqlite_upgrade/0020.sql +4 -0
- hikyuu/data/sqlite_upgrade/0021.sql +6 -0
- hikyuu/data/sqlite_upgrade/0022.sql +6 -0
- hikyuu/fetcher/stock/zh_stock_a_pytdx.py +56 -8
- hikyuu/fetcher/stock/zh_stock_a_qmt.py +49 -40
- hikyuu/fetcher/stock/zh_stock_a_sina_qq.py +15 -5
- hikyuu/gui/HikyuuTDX.py +1 -1
- hikyuu/gui/data/ImportWeightToSqliteTask.py +18 -27
- hikyuu/gui/data/UsePytdxImportToH5Thread.py +17 -6
- hikyuu/gui/data/UseTdxImportToH5Thread.py +30 -6
- hikyuu/gui/spot_server.py +3 -1
- hikyuu/include/hikyuu/KQuery.h +5 -2
- hikyuu/include/hikyuu/KRecord.h +1 -1
- hikyuu/include/hikyuu/Stock.h +1 -1
- hikyuu/include/hikyuu/StockManager.h +26 -20
- hikyuu/include/hikyuu/StrategyContext.h +66 -25
- hikyuu/include/hikyuu/data_driver/BaseInfoDriver.h +1 -0
- hikyuu/include/hikyuu/doc.h +1 -1
- hikyuu/include/hikyuu/global/GlobalSpotAgent.h +5 -2
- hikyuu/include/hikyuu/global/agent/SpotAgent.h +28 -6
- hikyuu/include/hikyuu/hikyuu.h +13 -0
- hikyuu/include/hikyuu/indicator/crt/AMA.h +1 -1
- hikyuu/include/hikyuu/indicator/crt/CORR.h +1 -1
- hikyuu/include/hikyuu/indicator/crt/ICIR.h +1 -0
- hikyuu/include/hikyuu/indicator/crt/SMA.h +1 -1
- hikyuu/include/hikyuu/indicator/crt/SPEARMAN.h +1 -1
- hikyuu/include/hikyuu/strategy/BrokerTradeManager.h +1 -2
- hikyuu/include/hikyuu/strategy/RunPortfolioInStrategy.h +1 -1
- hikyuu/include/hikyuu/strategy/Strategy.h +18 -4
- hikyuu/include/hikyuu/trade_manage/OrderBrokerBase.h +3 -0
- hikyuu/include/hikyuu/trade_manage/TradeManagerBase.h +1 -2
- hikyuu/include/hikyuu/trade_sys/allocatefunds/AllocateFundsBase.h +0 -1
- hikyuu/include/hikyuu/trade_sys/condition/ConditionBase.h +1 -0
- hikyuu/include/hikyuu/trade_sys/portfolio/Portfolio.h +1 -0
- hikyuu/include/hikyuu/trade_sys/selector/imp/FixedSelector.h +1 -1
- hikyuu/include/hikyuu/trade_sys/selector/imp/OperatorSelector.h +11 -2
- hikyuu/include/hikyuu/trade_sys/selector/imp/OperatorValueSelector.h +19 -2
- hikyuu/include/hikyuu/utilities/Parameter.h +1 -1
- hikyuu/include/hikyuu/utilities/TimerManager.h +2 -2
- hikyuu/include/hikyuu/utilities/arithmetic.h +4 -4
- hikyuu/include/hikyuu/utilities/base64.h +1 -2
- hikyuu/include/hikyuu/utilities/config.h +1 -1
- hikyuu/include/hikyuu/utilities/mo/moFileReader.h +2 -2
- hikyuu/include/hikyuu/utilities/node/NodeMessage.h +1 -3
- hikyuu/include/hikyuu/utilities/thread/MQStealThreadPool.h +6 -7
- hikyuu/include/hikyuu/version.h +4 -4
- hikyuu/interactive.py +55 -131
- {hikyuu-2.1.2.dist-info → hikyuu-2.1.4.dist-info}/METADATA +1 -1
- {hikyuu-2.1.2.dist-info → hikyuu-2.1.4.dist-info}/RECORD +64 -60
- hikyuu/include/hikyuu/global/GlobalTaskGroup.h +0 -44
- hikyuu/puppet.py +0 -297
- {hikyuu-2.1.2.dist-info → hikyuu-2.1.4.dist-info}/LICENSE +0 -0
- {hikyuu-2.1.2.dist-info → hikyuu-2.1.4.dist-info}/WHEEL +0 -0
- {hikyuu-2.1.2.dist-info → hikyuu-2.1.4.dist-info}/entry_points.txt +0 -0
- {hikyuu-2.1.2.dist-info → hikyuu-2.1.4.dist-info}/top_level.txt +0 -0
|
@@ -17,7 +17,7 @@ namespace hku {
|
|
|
17
17
|
* @param n 滚动窗口(大于2 或 等于0),等于0时,代表 n 实际使用 ind 的长度
|
|
18
18
|
* @ingroup Indicator
|
|
19
19
|
*/
|
|
20
|
-
Indicator HKU_API SPEARMAN(int n = 0);
|
|
21
20
|
Indicator HKU_API SPEARMAN(const Indicator& ind1, const Indicator& ind2, int n = 0);
|
|
21
|
+
Indicator HKU_API SPEARMAN(int n = 0);
|
|
22
22
|
|
|
23
23
|
} // namespace hku
|
|
@@ -181,10 +181,9 @@ public:
|
|
|
181
181
|
|
|
182
182
|
/**
|
|
183
183
|
* 获取指定证券的空头持仓记录
|
|
184
|
-
* @param date 指定日期
|
|
185
184
|
* @param stock 指定的证券
|
|
186
185
|
*/
|
|
187
|
-
virtual PositionRecord getShortPosition(const Stock&) const {
|
|
186
|
+
virtual PositionRecord getShortPosition(const Stock& stock) const {
|
|
188
187
|
HKU_WARN("The subclass does not implement this method");
|
|
189
188
|
return PositionRecord();
|
|
190
189
|
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
namespace hku {
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
* @ingroup
|
|
22
|
+
* @ingroup Strategy
|
|
23
23
|
* @{
|
|
24
24
|
*/
|
|
25
25
|
|
|
@@ -28,6 +28,7 @@ namespace hku {
|
|
|
28
28
|
*/
|
|
29
29
|
class HKU_API Strategy {
|
|
30
30
|
CLASS_LOGGER_IMP(Strategy)
|
|
31
|
+
PARAMETER_SUPPORT_WITH_CHECK
|
|
31
32
|
|
|
32
33
|
public:
|
|
33
34
|
Strategy();
|
|
@@ -37,6 +38,9 @@ public:
|
|
|
37
38
|
explicit Strategy(const StrategyContext& context, const string& name = "Strategy",
|
|
38
39
|
const string& config_file = "");
|
|
39
40
|
|
|
41
|
+
Strategy(const Strategy&) = delete;
|
|
42
|
+
Strategy& operator=(const Strategy&) = delete;
|
|
43
|
+
|
|
40
44
|
virtual ~Strategy();
|
|
41
45
|
|
|
42
46
|
const string& name() const {
|
|
@@ -73,8 +77,7 @@ public:
|
|
|
73
77
|
/**
|
|
74
78
|
* 正确数据发生变化调用,即接收到相应行情数据变更
|
|
75
79
|
* @note 通常用于调试。且只要收到行情采集消息就会触发,不受开、闭市时间限制
|
|
76
|
-
* @param
|
|
77
|
-
* @param spot 接收到的具体数据
|
|
80
|
+
* @param changeFunc 回调函数
|
|
78
81
|
*/
|
|
79
82
|
void onChange(std::function<void(const Stock&, const SpotRecord& spot)>&& changeFunc);
|
|
80
83
|
|
|
@@ -82,13 +85,14 @@ public:
|
|
|
82
85
|
* 一批行情数据接受完毕后通知
|
|
83
86
|
* @note 通常仅用于调试打印,该批行情数据中不一定含有上下文中包含的 stock
|
|
84
87
|
* 且只要收到行情采集消息就会触发,不受开、闭市时间限制。
|
|
88
|
+
* @param recievedFucn 回调函数
|
|
85
89
|
*/
|
|
86
90
|
void onReceivedSpot(std::function<void(const Datetime&)>&& recievedFucn);
|
|
87
91
|
|
|
88
92
|
/**
|
|
89
93
|
* 启动策略执行,必须在已注册相关处理函数后执行
|
|
90
94
|
*/
|
|
91
|
-
void start();
|
|
95
|
+
void start(bool autoRecieveSpot = true);
|
|
92
96
|
|
|
93
97
|
private:
|
|
94
98
|
string m_name;
|
|
@@ -106,6 +110,7 @@ private:
|
|
|
106
110
|
TimeDelta m_run_daily_at_delta;
|
|
107
111
|
|
|
108
112
|
private:
|
|
113
|
+
void _initParam();
|
|
109
114
|
void _init();
|
|
110
115
|
void _receivedSpot(const SpotRecord& spot);
|
|
111
116
|
void _runDaily();
|
|
@@ -170,5 +175,14 @@ void HKU_API runInStrategy(const SYSPtr& sys, const Stock& stk, const KQuery& qu
|
|
|
170
175
|
void HKU_API runInStrategy(const PFPtr& pf, const KQuery& query, int adjust_cycle,
|
|
171
176
|
const OrderBrokerPtr& broker, const TradeCostPtr& costfunc);
|
|
172
177
|
|
|
178
|
+
/**
|
|
179
|
+
* 从 hikyuu 数据缓存服务器拉取更新最新的缓存数据
|
|
180
|
+
* @param addr 缓存服务地址,如: tcp://192.168.1.1:9201
|
|
181
|
+
* @param stklist 待更新的股票列表
|
|
182
|
+
* @param ktype 指定更新的K线类型
|
|
183
|
+
*/
|
|
184
|
+
void HKU_API getDataFromBufferServer(const std::string& addr, const StockList& stklist,
|
|
185
|
+
const KQuery::KType& ktype);
|
|
186
|
+
|
|
173
187
|
/** @} */
|
|
174
188
|
} // namespace hku
|
|
@@ -134,6 +134,9 @@ public:
|
|
|
134
134
|
* @param code 证券代码
|
|
135
135
|
* @param price 卖出价格
|
|
136
136
|
* @param num 卖出数量
|
|
137
|
+
* @param stoploss 新预期的止损价
|
|
138
|
+
* @param goalPrice 新预期的目标价位
|
|
139
|
+
* @param from 系统部件来源
|
|
137
140
|
*/
|
|
138
141
|
virtual void _sell(Datetime datetime, const string& market, const string& code, price_t price,
|
|
139
142
|
double num, price_t stoploss, price_t goalPrice, SystemPart from) = 0;
|
|
@@ -442,10 +442,9 @@ public:
|
|
|
442
442
|
|
|
443
443
|
/**
|
|
444
444
|
* 获取指定证券的空头持仓记录
|
|
445
|
-
* @param date 指定日期
|
|
446
445
|
* @param stock 指定的证券
|
|
447
446
|
*/
|
|
448
|
-
virtual PositionRecord getShortPosition(const Stock&) const {
|
|
447
|
+
virtual PositionRecord getShortPosition(const Stock& stock) const {
|
|
449
448
|
HKU_WARN("The subclass does not implement this method");
|
|
450
449
|
return PositionRecord();
|
|
451
450
|
}
|
|
@@ -47,7 +47,6 @@ public:
|
|
|
47
47
|
* @param date 指定日期
|
|
48
48
|
* @param se_list 系统实例选择器选出的系统实例
|
|
49
49
|
* @param running_list 当前运行中的系统实例
|
|
50
|
-
* @param ignore_list 忽略不进行调仓的运行中系统
|
|
51
50
|
* @return 需延迟执行卖出操作的系统列表,其中权重为相应需卖出的数量
|
|
52
51
|
*/
|
|
53
52
|
SystemWeightList adjustFunds(const Datetime& date, const SystemWeightList& se_list,
|
|
@@ -14,7 +14,7 @@ namespace hku {
|
|
|
14
14
|
class HKU_API OperatorSelector : public SelectorBase {
|
|
15
15
|
public:
|
|
16
16
|
OperatorSelector();
|
|
17
|
-
OperatorSelector(const string& name);
|
|
17
|
+
explicit OperatorSelector(const string& name);
|
|
18
18
|
OperatorSelector(const string& name, const SelectorPtr& se1, const SelectorPtr& se2);
|
|
19
19
|
virtual ~OperatorSelector();
|
|
20
20
|
|
|
@@ -43,6 +43,7 @@ protected:
|
|
|
43
43
|
protected:
|
|
44
44
|
static void sortSystemWeightList(SystemWeightList& swlist);
|
|
45
45
|
|
|
46
|
+
void build();
|
|
46
47
|
void cloneRebuild(const SelectorPtr& se1, const SelectorPtr& se2);
|
|
47
48
|
|
|
48
49
|
protected:
|
|
@@ -63,11 +64,19 @@ private:
|
|
|
63
64
|
#if HKU_SUPPORT_SERIALIZATION
|
|
64
65
|
friend class boost::serialization::access;
|
|
65
66
|
template <class Archive>
|
|
66
|
-
void
|
|
67
|
+
void save(Archive& ar, const unsigned int version) const {
|
|
67
68
|
ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(SelectorBase);
|
|
68
69
|
ar& BOOST_SERIALIZATION_NVP(m_se1);
|
|
69
70
|
ar& BOOST_SERIALIZATION_NVP(m_se2);
|
|
70
71
|
}
|
|
72
|
+
|
|
73
|
+
template <class Archive>
|
|
74
|
+
void load(Archive& ar, const unsigned int version) {
|
|
75
|
+
ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(SelectorBase);
|
|
76
|
+
ar& BOOST_SERIALIZATION_NVP(m_se1);
|
|
77
|
+
ar& BOOST_SERIALIZATION_NVP(m_se2);
|
|
78
|
+
build();
|
|
79
|
+
}
|
|
71
80
|
#endif
|
|
72
81
|
};
|
|
73
82
|
|
|
@@ -14,7 +14,7 @@ namespace hku {
|
|
|
14
14
|
class HKU_API OperatorValueSelector : public SelectorBase {
|
|
15
15
|
public:
|
|
16
16
|
OperatorValueSelector();
|
|
17
|
-
OperatorValueSelector(const string& name);
|
|
17
|
+
explicit OperatorValueSelector(const string& name);
|
|
18
18
|
OperatorValueSelector(const string& name, const SelectorPtr& se, double value);
|
|
19
19
|
virtual ~OperatorValueSelector();
|
|
20
20
|
|
|
@@ -36,12 +36,29 @@ private:
|
|
|
36
36
|
//============================================
|
|
37
37
|
#if HKU_SUPPORT_SERIALIZATION
|
|
38
38
|
friend class boost::serialization::access;
|
|
39
|
+
// template <class Archive>
|
|
40
|
+
// void serialize(Archive& ar, const unsigned int version) {
|
|
41
|
+
// ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(SelectorBase);
|
|
42
|
+
// ar& BOOST_SERIALIZATION_NVP(m_se);
|
|
43
|
+
// ar& BOOST_SERIALIZATION_NVP(m_value);
|
|
44
|
+
// }
|
|
39
45
|
template <class Archive>
|
|
40
|
-
void
|
|
46
|
+
void save(Archive& ar, const unsigned int version) const {
|
|
41
47
|
ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(SelectorBase);
|
|
42
48
|
ar& BOOST_SERIALIZATION_NVP(m_se);
|
|
43
49
|
ar& BOOST_SERIALIZATION_NVP(m_value);
|
|
44
50
|
}
|
|
51
|
+
|
|
52
|
+
template <class Archive>
|
|
53
|
+
void load(Archive& ar, const unsigned int version) {
|
|
54
|
+
ar& BOOST_SERIALIZATION_BASE_OBJECT_NVP(SelectorBase);
|
|
55
|
+
ar& BOOST_SERIALIZATION_NVP(m_se);
|
|
56
|
+
ar& BOOST_SERIALIZATION_NVP(m_value);
|
|
57
|
+
if (m_se) {
|
|
58
|
+
m_pro_sys_list = m_se->getProtoSystemList();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
45
62
|
#endif
|
|
46
63
|
};
|
|
47
64
|
|
|
@@ -365,7 +365,7 @@ public: \
|
|
|
365
365
|
* 子类需要实现重载以下虚函数接口:
|
|
366
366
|
* virtual void _checkParam(const string& name) const
|
|
367
367
|
* 基类需要实现以下接口:
|
|
368
|
-
* void baseCheckParam(const string& name)
|
|
368
|
+
* void baseCheckParam(const string& name) const
|
|
369
369
|
* void paramChanged()
|
|
370
370
|
* 另:python 中一般不需要引出 paramChanged/checkParam/_checkParam,python
|
|
371
371
|
* 类继承时可以自己在初始化时进行检查
|
|
@@ -196,7 +196,7 @@ public:
|
|
|
196
196
|
* @param start_time 允许运行的起始时间
|
|
197
197
|
* @param end_time 允许运行的结束时间
|
|
198
198
|
* @param repeat_num 重复次数,必须大于0,等于std::numeric_limits<int>::max()时表示无限循环
|
|
199
|
-
* @param
|
|
199
|
+
* @param duration 间隔时间,需大于 TimeDelta(0)
|
|
200
200
|
* @param f 待执行的延迟任务
|
|
201
201
|
* @param args 任务具体参数
|
|
202
202
|
* @return timer id
|
|
@@ -226,7 +226,7 @@ public:
|
|
|
226
226
|
* @tparam F 任务类型
|
|
227
227
|
* @tparam Args 任务参数
|
|
228
228
|
* @param repeat_num 重复次数,必须大于0,等于std::numeric_limits<int>::max()时表示无限循环
|
|
229
|
-
* @param
|
|
229
|
+
* @param duration 间隔时间,需大于 TimeDelta(0)
|
|
230
230
|
* @param f 待执行的延迟任务
|
|
231
231
|
* @param args 任务具体参数
|
|
232
232
|
* @return timer id
|
|
@@ -316,7 +316,7 @@ inline std::vector<std::string> split(const std::string &str, const std::string
|
|
|
316
316
|
|
|
317
317
|
/**
|
|
318
318
|
* byte 转 16 进制字符串, 如 "abcd" 转换为 "61626364"
|
|
319
|
-
* @param
|
|
319
|
+
* @param bytes 输入的 byte 数组
|
|
320
320
|
* @param in_len byte 数组长度
|
|
321
321
|
*/
|
|
322
322
|
inline std::string byteToHexStr(const char *bytes, size_t in_len) {
|
|
@@ -345,7 +345,7 @@ inline std::string byteToHexStr(const char *bytes, size_t in_len) {
|
|
|
345
345
|
|
|
346
346
|
/**
|
|
347
347
|
* byte 转 16 进制字符串, 如 "abcd" 转换为 "61626364"
|
|
348
|
-
* @param
|
|
348
|
+
* @param bytes std::string 格式的输入
|
|
349
349
|
*/
|
|
350
350
|
inline std::string byteToHexStr(const std::string &bytes) {
|
|
351
351
|
return byteToHexStr(bytes.c_str(), bytes.size());
|
|
@@ -353,7 +353,7 @@ inline std::string byteToHexStr(const std::string &bytes) {
|
|
|
353
353
|
|
|
354
354
|
/**
|
|
355
355
|
* byte 转 16 进制字符串, 如 "abcd" 转换为 "0x61 0x62 0x63 0x64"
|
|
356
|
-
* @param
|
|
356
|
+
* @param bytes 输入的 byte 数组
|
|
357
357
|
* @param in_len byte 数组长度
|
|
358
358
|
*/
|
|
359
359
|
inline std::string byteToHexStrForPrint(const char *bytes, size_t in_len) {
|
|
@@ -389,7 +389,7 @@ inline std::string byteToHexStrForPrint(const char *bytes, size_t in_len) {
|
|
|
389
389
|
|
|
390
390
|
/**
|
|
391
391
|
* byte 转 16 进制字符串, 如 "abcd" 转换为 "61626364"
|
|
392
|
-
* @param
|
|
392
|
+
* @param bytes 输入的 byte 数组
|
|
393
393
|
*/
|
|
394
394
|
inline std::string byteToHexStrForPrint(const std::string &bytes) {
|
|
395
395
|
return byteToHexStrForPrint(bytes.c_str(), bytes.size());
|
|
@@ -27,8 +27,7 @@ std::string HKU_UTILS_API base64_encode(unsigned char const* bytes_to_encode, si
|
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* 字符串编码为 base64
|
|
30
|
-
* @param
|
|
31
|
-
* @param in_len 待计算的字节长度
|
|
30
|
+
* @param src 输入字符串
|
|
32
31
|
* @note 通过 func(unsigned char *, unsigned int) 函数实现,而不是直接只提供 string_view
|
|
33
32
|
* 版本的原因是:c++17 string_view 处理 nullptr 时,程序会直接挂掉,无异常
|
|
34
33
|
*/
|
|
@@ -342,7 +342,7 @@ public:
|
|
|
342
342
|
};
|
|
343
343
|
|
|
344
344
|
/** \brief Reads a .mo-file
|
|
345
|
-
* \param[in]
|
|
345
|
+
* \param[in] data The path to the file to load.
|
|
346
346
|
* \return SUCCESS on success or one of the other error-codes in eErrorCode on error.
|
|
347
347
|
*
|
|
348
348
|
* This is the core-feature. This method loads the .mo-file and stores
|
|
@@ -357,7 +357,7 @@ public:
|
|
|
357
357
|
}
|
|
358
358
|
|
|
359
359
|
/** \brief Reads a .mo-file
|
|
360
|
-
* \param[in]
|
|
360
|
+
* \param[in] filename The path to the file to load.
|
|
361
361
|
* \return SUCCESS on success or one of the other error-codes in eErrorCode on error.
|
|
362
362
|
*
|
|
363
363
|
* This is the core-feature. This method loads the .mo-file and stores
|
|
@@ -37,8 +37,6 @@ namespace hku {
|
|
|
37
37
|
* 对消息进行解码,消息类型和消息体必须匹配
|
|
38
38
|
* @tparam T 消息体类型
|
|
39
39
|
* @param msg 消息
|
|
40
|
-
* @param out 解码输出的消息
|
|
41
|
-
* @exception yas::io_exception 消息解码失败
|
|
42
40
|
* @exception NodeErrorCode 消息类型不匹配
|
|
43
41
|
*/
|
|
44
42
|
inline json decodeMsg(nng_msg *msg) {
|
|
@@ -68,7 +66,7 @@ inline void encodeMsg(nng_msg *msg, const json &in) {
|
|
|
68
66
|
|
|
69
67
|
/**
|
|
70
68
|
* 构造错误消息响应
|
|
71
|
-
* @param msg[out] 消息
|
|
69
|
+
* @param msg [out] 消息
|
|
72
70
|
* @param errcode 错误码
|
|
73
71
|
* @param errmsg 错误消息
|
|
74
72
|
*/
|
|
@@ -47,10 +47,9 @@ public:
|
|
|
47
47
|
* 构造函数,创建指定数量的线程
|
|
48
48
|
* @param n 指定的线程数
|
|
49
49
|
* @param until_empty 任务队列为空时,自动停止运行
|
|
50
|
-
* @param exit_thread_callback 工作线程结束时回调函数
|
|
51
50
|
*/
|
|
52
|
-
explicit MQStealThreadPool(size_t n, bool
|
|
53
|
-
: m_done(false), m_worker_num(n),
|
|
51
|
+
explicit MQStealThreadPool(size_t n, bool until_empty = true)
|
|
52
|
+
: m_done(false), m_worker_num(n), m_runnging_until_empty(until_empty) {
|
|
54
53
|
try {
|
|
55
54
|
m_interrupt_flags.resize(m_worker_num, nullptr);
|
|
56
55
|
for (size_t i = 0; i < m_worker_num; i++) {
|
|
@@ -189,7 +188,7 @@ public:
|
|
|
189
188
|
}
|
|
190
189
|
|
|
191
190
|
// 指示各工作线程在未获取到工作任务时,停止运行
|
|
192
|
-
if (
|
|
191
|
+
if (m_runnging_until_empty) {
|
|
193
192
|
while (true) {
|
|
194
193
|
bool can_quit = true;
|
|
195
194
|
for (size_t i = 0; i < m_worker_num; i++) {
|
|
@@ -234,9 +233,9 @@ public:
|
|
|
234
233
|
|
|
235
234
|
private:
|
|
236
235
|
typedef FuncWrapper task_type;
|
|
237
|
-
std::atomic_bool m_done;
|
|
238
|
-
size_t m_worker_num;
|
|
239
|
-
bool
|
|
236
|
+
std::atomic_bool m_done; // 线程池全局需终止指示
|
|
237
|
+
size_t m_worker_num; // 工作线程数量
|
|
238
|
+
bool m_runnging_until_empty; // 运行直到队列空时停止
|
|
240
239
|
|
|
241
240
|
std::vector<std::unique_ptr<MQStealQueue<task_type>>> m_queues; // 线程任务队列
|
|
242
241
|
std::vector<InterruptFlag*> m_interrupt_flags; // 线程终止标志
|
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.1.
|
|
15
|
+
#define HKU_VERSION "2.1.4"
|
|
16
16
|
#define HKU_VERSION_MAJOR 2
|
|
17
17
|
#define HKU_VERSION_MINOR 1
|
|
18
|
-
#define HKU_VERSION_ALTER
|
|
19
|
-
#define HKU_VERSION_BUILD
|
|
18
|
+
#define HKU_VERSION_ALTER 4
|
|
19
|
+
#define HKU_VERSION_BUILD 202409041745
|
|
20
20
|
#define HKU_VERSION_MODE "RELEASE"
|
|
21
|
-
#define HKU_VERSION_GIT "2.1.
|
|
21
|
+
#define HKU_VERSION_GIT "2.1.4 release.9013b86e (RELEASE)"
|
|
22
22
|
// clang-format on
|
|
23
23
|
|
|
24
24
|
#endif /* HKU_VERSION_H */
|
hikyuu/interactive.py
CHANGED
|
@@ -50,22 +50,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
50
50
|
SOFTWARE.
|
|
51
51
|
"""
|
|
52
52
|
|
|
53
|
-
import urllib
|
|
54
|
-
import sys
|
|
55
53
|
import os
|
|
56
54
|
import configparser
|
|
57
55
|
|
|
58
56
|
from hikyuu.data.hku_config_template import generate_default_config
|
|
59
57
|
from hikyuu import *
|
|
60
58
|
|
|
61
|
-
# ==============================================================================
|
|
62
|
-
# 引入扯线木偶
|
|
63
|
-
# ==============================================================================
|
|
64
|
-
# Puppet是一套以同花顺交易客户端为核心的完整的闭环实盘交易系统框架。
|
|
65
|
-
# 来自:"睿瞳深邃(https://github.com/Raytone-D" 感谢睿瞳深邃的大度共享 :-)
|
|
66
|
-
# 可以用:tm.regBroker(crtRB(Puppet())) 的方式注册进tm实例,实现实盘下单
|
|
67
|
-
if sys.platform == 'win32':
|
|
68
|
-
from .puppet import *
|
|
69
59
|
|
|
70
60
|
# ==============================================================================
|
|
71
61
|
#
|
|
@@ -83,8 +73,6 @@ ini.read(config_file, encoding='utf-8')
|
|
|
83
73
|
hku_param = Parameter()
|
|
84
74
|
hku_param["tmpdir"] = ini.get('hikyuu', 'tmpdir')
|
|
85
75
|
hku_param["datadir"] = ini.get('hikyuu', 'datadir')
|
|
86
|
-
if ini.has_option('hikyuu', 'logger'):
|
|
87
|
-
hku_param["logger"] = ini['hikyuu']['logger']
|
|
88
76
|
if ini.has_option('hikyuu', 'quotation_server'):
|
|
89
77
|
hku_param["quotation_server"] = ini['hikyuu']['quotation_server']
|
|
90
78
|
|
|
@@ -114,11 +102,33 @@ for p in kdata_config:
|
|
|
114
102
|
continue
|
|
115
103
|
kdata_param[p] = ini.get('kdata', p)
|
|
116
104
|
|
|
117
|
-
|
|
105
|
+
context = StrategyContext(["all"])
|
|
106
|
+
if 'HKU_STOCK_LIST' in os.environ:
|
|
107
|
+
context.stock_list = os.environ['HKU_STOCK_LIST'].split(";")
|
|
108
|
+
if 'HKU_KTYPE_LIST' in os.environ:
|
|
109
|
+
context.ktype_list = os.environ['HKU_KTYPE_LIST'].split(";")
|
|
110
|
+
if 'HKU_LOAD_HISTORY_FINANCE' in os.environ:
|
|
111
|
+
load_str = os.environ['HKU_LOAD_HISTORY_FINANCE'].upper()
|
|
112
|
+
load_finance = load_str in ("1", "TRUE")
|
|
113
|
+
hku_param.set("load_history_finance", load_finance)
|
|
114
|
+
if 'HKU_LOAD_STOCK_WEIGHT' in os.environ:
|
|
115
|
+
load_str = os.environ['HKU_LOAD_STOCK_WEIGHT'].upper()
|
|
116
|
+
load_stk_weight = load_str in ("1", "TRUE")
|
|
117
|
+
hku_param.set("load_stock_weight", load_stk_weight)
|
|
118
|
+
|
|
119
|
+
sm.init(base_param, block_param, kdata_param, preload_param, hku_param, context)
|
|
118
120
|
# set_log_level(LOG_LEVEL.INFO)
|
|
119
121
|
|
|
122
|
+
start_spot = False
|
|
123
|
+
if 'HKU_START_SPOT' in os.environ:
|
|
124
|
+
spot_str = os.environ['HKU_START_SPOT'].upper()
|
|
125
|
+
start_spot = spot_str in ('1', 'TRUE')
|
|
126
|
+
spot_worker_num = 1
|
|
127
|
+
if 'HKU_SPOT_WORKER_NUM' in os.environ:
|
|
128
|
+
spot_worker_num = int(os.environ['HKU_SPOT_WORKER_NUM'])
|
|
129
|
+
|
|
120
130
|
# 启动行情接收代理
|
|
121
|
-
start_spot_agent(False)
|
|
131
|
+
start_spot_agent(False, spot_worker_num)
|
|
122
132
|
|
|
123
133
|
# ==============================================================================
|
|
124
134
|
#
|
|
@@ -255,129 +265,43 @@ def select(cond, start=Datetime(201801010000), end=Datetime.now(), print_out=Tru
|
|
|
255
265
|
# ==============================================================================
|
|
256
266
|
|
|
257
267
|
|
|
258
|
-
def
|
|
259
|
-
try:
|
|
260
|
-
if len(tmpstr) > 3 and tmpstr[:2] == 'v_':
|
|
261
|
-
a = tmpstr.split('~')
|
|
262
|
-
if len(a) < 9:
|
|
263
|
-
return
|
|
264
|
-
|
|
265
|
-
open, close, high, low = float(a[5]), float(a[3]), float(a[33]), float(a[34])
|
|
266
|
-
transamount = float(a[36])
|
|
267
|
-
transcount = float(a[37])
|
|
268
|
-
|
|
269
|
-
d = Datetime(int(a[30][:8] + '0000'))
|
|
270
|
-
temp = (open, high, low, close)
|
|
271
|
-
if 0 in temp:
|
|
272
|
-
return
|
|
273
|
-
|
|
274
|
-
stockstr = a[0].split('=')
|
|
275
|
-
stock = sm[stockstr[0][-8:]]
|
|
276
|
-
|
|
277
|
-
record = KRecord()
|
|
278
|
-
record.datetime = d
|
|
279
|
-
record.open = open
|
|
280
|
-
record.high = high
|
|
281
|
-
record.low = low
|
|
282
|
-
record.close = close
|
|
283
|
-
record.amount = transamount
|
|
284
|
-
record.volume = transcount / 100
|
|
285
|
-
|
|
286
|
-
stock.realtime_update(record)
|
|
287
|
-
|
|
288
|
-
except Exception as e:
|
|
289
|
-
print(tmpstr)
|
|
290
|
-
print(e)
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
def realtimePartUpdate_from_qq(queryStr):
|
|
294
|
-
result = urllib.request.urlopen(queryStr).read()
|
|
295
|
-
try:
|
|
296
|
-
result = result.decode('gbk')
|
|
297
|
-
except Exception as e:
|
|
298
|
-
print(result)
|
|
299
|
-
print(e)
|
|
300
|
-
return
|
|
301
|
-
|
|
302
|
-
result = result.split('\n')
|
|
303
|
-
for tmpstr in result:
|
|
304
|
-
UpdateOneRealtimeRecord_from_qq(tmpstr)
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
def realtime_update_from_website(source, stk_list=None):
|
|
308
|
-
if source == 'qq':
|
|
309
|
-
queryStr = "http://qt.gtimg.cn/q="
|
|
310
|
-
update_func = realtimePartUpdate_from_qq
|
|
311
|
-
max_size = 60
|
|
312
|
-
else:
|
|
313
|
-
print('Not support!')
|
|
314
|
-
return
|
|
315
|
-
|
|
316
|
-
count = 0
|
|
317
|
-
# urls = []
|
|
318
|
-
tmpstr = queryStr
|
|
319
|
-
if stk_list is None:
|
|
320
|
-
stk_list = sm
|
|
321
|
-
for stock in stk_list:
|
|
322
|
-
if stock.valid and stock.type in (
|
|
323
|
-
constant.STOCKTYPE_A, constant.STOCKTYPE_INDEX, constant.STOCKTYPE_ETF, constant.STOCKTYPE_GEM, constant.STOCKTYPE_A_BJ,
|
|
324
|
-
):
|
|
325
|
-
tmpstr += ("%s,") % (stock.market_code.lower())
|
|
326
|
-
count = count + 1
|
|
327
|
-
if count >= max_size:
|
|
328
|
-
# urls.append(tmpstr)
|
|
329
|
-
update_func(tmpstr)
|
|
330
|
-
count = 0
|
|
331
|
-
tmpstr = queryStr
|
|
332
|
-
|
|
333
|
-
if tmpstr != queryStr:
|
|
334
|
-
# urls.append(tmpstr)
|
|
335
|
-
update_func(tmpstr)
|
|
336
|
-
|
|
337
|
-
# 不用并行,防止过快,ip被网站屏蔽
|
|
338
|
-
# from multiprocessing import Pool
|
|
339
|
-
# from multiprocessing.dummy import Pool as ThreadPool
|
|
340
|
-
# pool = ThreadPool()
|
|
341
|
-
# if source == 'sina':
|
|
342
|
-
# pool.map(realtimePartUpdate_from_sina, urls)
|
|
343
|
-
# else:
|
|
344
|
-
# pool.map(realtimePartUpdate_from_qq, urls)
|
|
345
|
-
# pool.close()
|
|
346
|
-
# pool.join()
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
def realtime_update_from_qmt(stk_list=None):
|
|
350
|
-
from xtquant import xtdata
|
|
268
|
+
def realtime_update_inner(source='qq', stk_list=None):
|
|
351
269
|
if stk_list is None:
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
record.high = data['high']
|
|
363
|
-
record.low = data['low']
|
|
364
|
-
record.close = data['lastPrice']
|
|
365
|
-
record.volume = data['volume'] * 0.1
|
|
366
|
-
record.amount = data['amount'] * 0.001
|
|
367
|
-
stock.realtime_update(record)
|
|
368
|
-
except Exception as e:
|
|
369
|
-
hku_error(str(e))
|
|
370
|
-
except:
|
|
371
|
-
pass
|
|
372
|
-
|
|
270
|
+
if source == 'qmt':
|
|
271
|
+
stk_list = [s for s in sm if s.valid and s.type in (
|
|
272
|
+
constant.STOCKTYPE_A, constant.STOCKTYPE_INDEX, constant.STOCKTYPE_ETF,
|
|
273
|
+
constant.STOCKTYPE_GEM, constant.STOCKTYPE_START, constant.STOCKTYPE_A_BJ)]
|
|
274
|
+
else:
|
|
275
|
+
stk_list = [
|
|
276
|
+
stk.market_code.lower() for stk in sm if stk.valid and stk.type in
|
|
277
|
+
(constant.STOCKTYPE_A, constant.STOCKTYPE_INDEX, constant.STOCKTYPE_GEM,
|
|
278
|
+
constant.STOCKTYPE_START, constant.STOCKTYPE_A_BJ)
|
|
279
|
+
]
|
|
373
280
|
|
|
374
|
-
def realtime_update_inner(source='qq', stk_list=None):
|
|
375
281
|
if source == 'qq':
|
|
376
|
-
|
|
282
|
+
from hikyuu.fetcher.stock.zh_stock_a_sina_qq import get_spot
|
|
283
|
+
stk_list = [s.market_code.lower() for s in stk_list]
|
|
284
|
+
records = get_spot(stk_list, 'qq')
|
|
377
285
|
elif source == 'qmt':
|
|
378
|
-
|
|
286
|
+
from hikyuu.fetcher.stock.zh_stock_a_qmt import get_spot
|
|
287
|
+
records = get_spot(stk_list)
|
|
379
288
|
else:
|
|
380
289
|
hku_error(f'Not support website source: {source}!')
|
|
290
|
+
return
|
|
291
|
+
|
|
292
|
+
for r in records:
|
|
293
|
+
stk = sm[f'{r["market"]}{r["code"]}']
|
|
294
|
+
if stk.is_null():
|
|
295
|
+
continue
|
|
296
|
+
k = KRecord()
|
|
297
|
+
k.datetime = Datetime(r['datetime']).start_of_day()
|
|
298
|
+
k.open = r['open']
|
|
299
|
+
k.high = r['high']
|
|
300
|
+
k.low = r['low']
|
|
301
|
+
k.close = r['close']
|
|
302
|
+
k.volume = r['volume']
|
|
303
|
+
k.amount = r['amount']
|
|
304
|
+
stk.realtime_update(k)
|
|
381
305
|
|
|
382
306
|
|
|
383
307
|
def realtime_update_wrap():
|