hikyuu 2.6.2__py3-none-win_amd64.whl → 2.6.5__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.
Files changed (136) hide show
  1. hikyuu/__init__.py +1 -1
  2. hikyuu/__init__.pyi +28 -13
  3. hikyuu/analysis/__init__.pyi +20 -0
  4. hikyuu/analysis/analysis.pyi +21 -1
  5. hikyuu/core.pyi +22 -2
  6. hikyuu/cpp/core310.pyd +0 -0
  7. hikyuu/cpp/core310.pyi +499 -50
  8. hikyuu/cpp/core311.pyd +0 -0
  9. hikyuu/cpp/core311.pyi +499 -50
  10. hikyuu/cpp/core312.pyd +0 -0
  11. hikyuu/cpp/core312.pyi +499 -50
  12. hikyuu/cpp/core313.pyd +0 -0
  13. hikyuu/cpp/core313.pyi +499 -50
  14. hikyuu/cpp/core39.pyd +0 -0
  15. hikyuu/cpp/core39.pyi +499 -50
  16. hikyuu/cpp/hikyuu.dll +0 -0
  17. hikyuu/cpp/hikyuu.lib +0 -0
  18. hikyuu/data/common.py +1 -1
  19. hikyuu/data/common_mysql.py +19 -0
  20. hikyuu/data/common_pytdx.py +2 -0
  21. hikyuu/data/common_sqlite3.py +1 -0
  22. hikyuu/data/hku_config_template.py +14 -0
  23. hikyuu/data/mysql_upgrade/0028.sql +95 -0
  24. hikyuu/data/pytdx_to_h5.py +53 -13
  25. hikyuu/data/pytdx_to_mysql.py +42 -9
  26. hikyuu/data/pytdx_to_taos.py +736 -0
  27. hikyuu/data/sqlite_upgrade/0028.sql +97 -0
  28. hikyuu/draw/__init__.pyi +1 -1
  29. hikyuu/draw/drawplot/__init__.pyi +1 -1
  30. hikyuu/draw/drawplot/bokeh_draw.pyi +24 -9
  31. hikyuu/draw/drawplot/echarts_draw.pyi +24 -9
  32. hikyuu/draw/drawplot/matplotlib_draw.py +26 -4
  33. hikyuu/draw/drawplot/matplotlib_draw.pyi +24 -9
  34. hikyuu/draw/kaufman.py +2 -2
  35. hikyuu/draw/kaufman.pyi +2 -2
  36. hikyuu/examples/notebook/001-overview.ipynb +65 -100
  37. hikyuu/examples/notebook/004-IndicatorOverview.ipynb +34 -32
  38. hikyuu/examples/notebook/007-SystemDetails.ipynb +64 -50
  39. hikyuu/examples/notebook/010-Portfolio.ipynb +120 -124
  40. hikyuu/extend.py +1 -1
  41. hikyuu/extend.pyi +24 -9
  42. hikyuu/fetcher/stock/zh_block_em.py +349 -5
  43. hikyuu/fetcher/stock/zh_stock_a_pytdx.py +2 -1
  44. hikyuu/gui/HikyuuTDX.py +47 -24
  45. hikyuu/gui/data/ImportBlockInfoTask.py +1 -1
  46. hikyuu/gui/data/ImportHistoryFinanceTask.py +48 -44
  47. hikyuu/gui/data/ImportPytdxTimeToH5Task.py +3 -1
  48. hikyuu/gui/data/ImportPytdxToH5Task.py +4 -2
  49. hikyuu/gui/data/ImportPytdxTransToH5Task.py +3 -1
  50. hikyuu/gui/data/ImportWeightToSqliteTask.py +2 -1
  51. hikyuu/gui/data/ImportZhBond10Task.py +1 -1
  52. hikyuu/gui/data/MainWindow.py +123 -106
  53. hikyuu/gui/data/UsePytdxImportToH5Thread.py +7 -3
  54. hikyuu/gui/data/UseQmtImportToH5Thread.py +1 -0
  55. hikyuu/gui/data/UseTdxImportToH5Thread.py +2 -1
  56. hikyuu/hub.pyi +6 -6
  57. hikyuu/include/hikyuu/Block.h +20 -0
  58. hikyuu/include/hikyuu/KQuery.h +8 -0
  59. hikyuu/include/hikyuu/MarketInfo.h +6 -0
  60. hikyuu/include/hikyuu/Stock.h +1 -1
  61. hikyuu/include/hikyuu/StockManager.h +6 -0
  62. hikyuu/include/hikyuu/data_driver/BaseInfoDriver.h +35 -0
  63. hikyuu/include/hikyuu/indicator/Indicator.h +5 -0
  64. hikyuu/include/hikyuu/indicator/IndicatorImp.h +8 -3
  65. hikyuu/include/hikyuu/indicator/build_in.h +1 -0
  66. hikyuu/include/hikyuu/indicator/crt/BARSLASTCOUNT.h +33 -0
  67. hikyuu/include/hikyuu/indicator/crt/INSUM.h +5 -10
  68. hikyuu/include/hikyuu/indicator/crt/RSI.h +2 -18
  69. hikyuu/include/hikyuu/indicator/imp/IBarsLastCount.h +27 -0
  70. hikyuu/include/hikyuu/plugin/backtest.h +3 -2
  71. hikyuu/include/hikyuu/plugin/device.h +6 -3
  72. hikyuu/include/hikyuu/plugin/extind.h +150 -0
  73. hikyuu/include/hikyuu/plugin/interface/BackTestPluginInterface.h +2 -1
  74. hikyuu/include/hikyuu/plugin/interface/DevicePluginInterface.h +1 -0
  75. hikyuu/include/hikyuu/plugin/interface/ExtendIndicatorsPluginInterface.h +26 -0
  76. hikyuu/include/hikyuu/plugin/interface/TMReportPluginInterface.h +80 -0
  77. hikyuu/include/hikyuu/plugin/interface/plugins.h +4 -0
  78. hikyuu/include/hikyuu/strategy/BrokerTradeManager.h +7 -5
  79. hikyuu/include/hikyuu/strategy/Strategy.h +22 -9
  80. hikyuu/include/hikyuu/trade_manage/OrderBrokerBase.h +11 -4
  81. hikyuu/include/hikyuu/trade_manage/Performance.h +17 -9
  82. hikyuu/include/hikyuu/trade_manage/PositionExtInfo.h +92 -0
  83. hikyuu/include/hikyuu/trade_manage/PositionRecord.h +7 -1
  84. hikyuu/include/hikyuu/trade_manage/TradeManager.h +8 -5
  85. hikyuu/include/hikyuu/trade_manage/TradeManagerBase.h +66 -5
  86. hikyuu/include/hikyuu/trade_manage/TradeRecord.h +9 -1
  87. hikyuu/include/hikyuu/trade_sys/multifactor/MultiFactorBase.h +8 -5
  88. hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_EqualWeight.h +4 -1
  89. hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_ICIRWeight.h +4 -1
  90. hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_ICWeight.h +4 -1
  91. hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_Weight.h +4 -1
  92. hikyuu/include/hikyuu/trade_sys/multifactor/imp/EqualWeightMultiFactor.h +2 -1
  93. hikyuu/include/hikyuu/trade_sys/multifactor/imp/ICIRMultiFactor.h +2 -1
  94. hikyuu/include/hikyuu/trade_sys/multifactor/imp/ICMultiFactor.h +2 -1
  95. hikyuu/include/hikyuu/trade_sys/multifactor/imp/WeightMultiFactor.h +1 -1
  96. hikyuu/include/hikyuu/trade_sys/selector/crt/SE_Optimal.h +8 -0
  97. hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/OptimalEvaluateSelector.h +28 -0
  98. hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/OptimalSelectorBase.h +1 -0
  99. hikyuu/include/hikyuu/trade_sys/system/TradeRequest.h +7 -4
  100. hikyuu/include/hikyuu/trade_sys/system/imp/WalkForwardTradeManager.h +17 -13
  101. hikyuu/include/hikyuu/utilities/DllLoader.h +226 -0
  102. hikyuu/include/hikyuu/utilities/datetime/Datetime.h +20 -0
  103. hikyuu/include/hikyuu/utilities/datetime/TimeDelta.h +6 -0
  104. hikyuu/include/hikyuu/utilities/plugin/PluginLoader.h +10 -10
  105. hikyuu/include/hikyuu/utilities/thread/{MQStealThreadPool.h → GlobalMQStealThreadPool.h} +12 -12
  106. hikyuu/include/hikyuu/utilities/thread/GlobalMQThreadPool.h +271 -0
  107. hikyuu/include/hikyuu/utilities/thread/{StealThreadPool.h → GlobalStealThreadPool.h} +11 -10
  108. hikyuu/include/hikyuu/utilities/thread/GlobalThreadPool.h +224 -0
  109. hikyuu/include/hikyuu/utilities/thread/InterruptFlag.h +16 -0
  110. hikyuu/include/hikyuu/utilities/thread/MQThreadPool.h +40 -77
  111. hikyuu/include/hikyuu/utilities/thread/ThreadPool.h +31 -59
  112. hikyuu/include/hikyuu/utilities/thread/ThreadSafeQueue.h +4 -0
  113. hikyuu/include/hikyuu/utilities/thread/algorithm.h +9 -9
  114. hikyuu/include/hikyuu/utilities/thread/thread.h +4 -0
  115. hikyuu/include/hikyuu/version.h +4 -4
  116. hikyuu/plugin/backtest.dll +0 -0
  117. hikyuu/plugin/dataserver.dll +0 -0
  118. hikyuu/plugin/device.dll +0 -0
  119. hikyuu/plugin/extind.dll +0 -0
  120. hikyuu/plugin/import2hdf5.dll +0 -0
  121. hikyuu/plugin/tmreport.dll +0 -0
  122. hikyuu/trade_manage/__init__.pyi +23 -8
  123. hikyuu/trade_manage/broker.py +8 -8
  124. hikyuu/trade_manage/broker.pyi +4 -4
  125. hikyuu/trade_manage/broker_easytrader.py +3 -3
  126. hikyuu/trade_manage/broker_easytrader.pyi +2 -2
  127. hikyuu/trade_manage/broker_mail.py +2 -2
  128. hikyuu/trade_manage/broker_mail.pyi +2 -2
  129. hikyuu/trade_manage/trade.pyi +23 -8
  130. hikyuu/util/singleton.pyi +1 -1
  131. {hikyuu-2.6.2.dist-info → hikyuu-2.6.5.dist-info}/METADATA +4 -3
  132. {hikyuu-2.6.2.dist-info → hikyuu-2.6.5.dist-info}/RECORD +136 -121
  133. {hikyuu-2.6.2.dist-info → hikyuu-2.6.5.dist-info}/LICENSE +0 -0
  134. {hikyuu-2.6.2.dist-info → hikyuu-2.6.5.dist-info}/WHEEL +0 -0
  135. {hikyuu-2.6.2.dist-info → hikyuu-2.6.5.dist-info}/entry_points.txt +0 -0
  136. {hikyuu-2.6.2.dist-info → hikyuu-2.6.5.dist-info}/top_level.txt +0 -0
@@ -18,7 +18,8 @@ class ICMultiFactor : public MultiFactorBase {
18
18
  public:
19
19
  ICMultiFactor();
20
20
  ICMultiFactor(const IndicatorList& inds, const StockList& stks, const KQuery& query,
21
- const Stock& ref_stk, int ic_n, int ic_rolling_n, bool spearman);
21
+ const Stock& ref_stk, int ic_n, int ic_rolling_n, bool spearman, int mode,
22
+ bool save_all_factors);
22
23
  virtual ~ICMultiFactor() = default;
23
24
 
24
25
  virtual void _checkParam(const string& name) const override;
@@ -21,7 +21,7 @@ public:
21
21
  WeightMultiFactor();
22
22
  WeightMultiFactor(const vector<Indicator>& inds, const PriceList& weights,
23
23
  const StockList& stks, const KQuery& query, const Stock& ref_stk, int ic_n,
24
- bool spearman);
24
+ bool spearman, int mode, bool save_all_factors);
25
25
  virtual ~WeightMultiFactor() = default;
26
26
 
27
27
  private:
@@ -23,4 +23,12 @@ SEPtr HKU_API SE_MaxFundsOptimal();
23
23
  */
24
24
  SEPtr HKU_API SE_PerformanceOptimal(const string& key = "帐户平均年收益率%", int mode = 0);
25
25
 
26
+ /**
27
+ * 使用自定义评估函数进行寻优的选择器
28
+ * @param evaluate
29
+ * @return SEPtr
30
+ */
31
+ SEPtr HKU_API
32
+ SE_EvaluateOptimal(std::function<double(const SystemPtr&, const Datetime&)>&& evaluate);
33
+
26
34
  } // namespace hku
@@ -0,0 +1,28 @@
1
+ /*
2
+ * Copyright (c) 2024 hikyuu.org
3
+ *
4
+ * Created on: 2024-09-22
5
+ * Author: fasiondog
6
+ */
7
+
8
+ #pragma once
9
+
10
+ #include "OptimalSelectorBase.h"
11
+
12
+ namespace hku {
13
+
14
+ class OptimalEvaluateSelector : public OptimalSelectorBase {
15
+ OPTIMAL_SELECTOR_IMP(OptimalEvaluateSelector)
16
+ OPTIMAL_SELECTOR_NO_PRIVATE_MEMBER_SERIALIZATION
17
+
18
+ public:
19
+ OptimalEvaluateSelector();
20
+ OptimalEvaluateSelector(std::function<double(const SystemPtr&, const Datetime&)>&& evaluate);
21
+
22
+ virtual ~OptimalEvaluateSelector();
23
+
24
+ private:
25
+ std::function<double(const SystemPtr&, const Datetime&)> m_evaluate;
26
+ };
27
+
28
+ } // namespace hku
@@ -43,6 +43,7 @@ public:
43
43
  // 以便继承子类只需要实现 _clone 和 该接口即可
44
44
  // 该接口实现系统绩效评估,getSelected 时将取评估结果最大的系统
45
45
  // 使用 std::function 的话,在 C++ 中无法序列化,所以使用继承
46
+ // 返回 Null<double> 时,将不被评估选中
46
47
  virtual double evaluate(const SYSPtr& sys, const Datetime& endDate) noexcept {
47
48
  return Null<double>();
48
49
  }
@@ -28,11 +28,12 @@ public:
28
28
  Datetime datetime;
29
29
  price_t stoploss{0.0};
30
30
  price_t goal{0.0};
31
- double number{0.0}; // 计划的买入/卖出数量,使用发出请求时刻的收盘价,
32
- // 用于避免实际买入时需用重新计算数量时,人工执行速度较慢
33
- // 可通过系统参数进行设置,是否使用
31
+ double number{0.0}; // 计划的买入/卖出数量,使用发出请求时刻的收盘价,
32
+ // 用于避免实际买入时需用重新计算数量时,人工执行速度较慢
33
+ // 可通过系统参数进行设置,是否使用
34
34
  SystemPart from{PART_INVALID}; // 记录SystemBase::Part
35
- int count{0}; // 因操作失败,连续延迟的次数
35
+ string remark;
36
+ int count{0}; // 因操作失败,连续延迟的次数
36
37
  KRecord krecord;
37
38
 
38
39
  //============================================
@@ -54,6 +55,7 @@ private:
54
55
  ar& BOOST_SERIALIZATION_NVP(number);
55
56
  string from_name(getSystemPartName(from));
56
57
  ar& bs::make_nvp<string>("from", from_name);
58
+ ar& BOOST_SERIALIZATION_NVP(remark);
57
59
  ar& BOOST_SERIALIZATION_NVP(count);
58
60
  ar& BOOST_SERIALIZATION_NVP(krecord);
59
61
  }
@@ -74,6 +76,7 @@ private:
74
76
  string from_name;
75
77
  ar& bs::make_nvp<string>("from", from_name);
76
78
  from = getSystemPartEnum(from_name);
79
+ ar& BOOST_SERIALIZATION_NVP(remark);
77
80
  ar& BOOST_SERIALIZATION_NVP(count);
78
81
  ar& BOOST_SERIALIZATION_NVP(krecord);
79
82
  }
@@ -262,9 +262,10 @@ public:
262
262
  */
263
263
  virtual TradeRecord buy(const Datetime& datetime, const Stock& stock, price_t realPrice,
264
264
  double number, price_t stoploss = 0.0, price_t goalPrice = 0.0,
265
- price_t planPrice = 0.0, SystemPart from = PART_INVALID) override {
265
+ price_t planPrice = 0.0, SystemPart from = PART_INVALID,
266
+ const string& remark = "") override {
266
267
  return (datetime >= m_run_start) ? m_tm->buy(datetime, stock, realPrice, number, stoploss,
267
- goalPrice, planPrice, from)
268
+ goalPrice, planPrice, from, remark)
268
269
  : TradeRecord();
269
270
  }
270
271
 
@@ -283,9 +284,9 @@ public:
283
284
  virtual TradeRecord sell(const Datetime& datetime, const Stock& stock, price_t realPrice,
284
285
  double number = MAX_DOUBLE, price_t stoploss = 0.0,
285
286
  price_t goalPrice = 0.0, price_t planPrice = 0.0,
286
- SystemPart from = PART_INVALID) override {
287
+ SystemPart from = PART_INVALID, const string& remark = "") override {
287
288
  return (datetime >= m_run_start) ? m_tm->sell(datetime, stock, realPrice, number, stoploss,
288
- goalPrice, planPrice, from)
289
+ goalPrice, planPrice, from, remark)
289
290
  : TradeRecord();
290
291
  }
291
292
 
@@ -303,11 +304,12 @@ public:
303
304
  */
304
305
  virtual TradeRecord sellShort(const Datetime& datetime, const Stock& stock, price_t realPrice,
305
306
  double number, price_t stoploss = 0.0, price_t goalPrice = 0.0,
306
- price_t planPrice = 0.0,
307
- SystemPart from = PART_INVALID) override {
308
- return (datetime >= m_run_start) ? m_tm->sellShort(datetime, stock, realPrice, number,
309
- stoploss, goalPrice, planPrice, from)
310
- : TradeRecord();
307
+ price_t planPrice = 0.0, SystemPart from = PART_INVALID,
308
+ const string& remark = "") override {
309
+ return (datetime >= m_run_start)
310
+ ? m_tm->sellShort(datetime, stock, realPrice, number, stoploss, goalPrice,
311
+ planPrice, from, remark)
312
+ : TradeRecord();
311
313
  }
312
314
 
313
315
  /**
@@ -325,10 +327,12 @@ public:
325
327
  virtual TradeRecord buyShort(const Datetime& datetime, const Stock& stock, price_t realPrice,
326
328
  double number = MAX_DOUBLE, price_t stoploss = 0.0,
327
329
  price_t goalPrice = 0.0, price_t planPrice = 0.0,
328
- SystemPart from = PART_INVALID) override {
329
- return (datetime >= m_run_start) ? m_tm->buyShort(datetime, stock, realPrice, number,
330
- stoploss, goalPrice, planPrice, from)
331
- : TradeRecord();
330
+ SystemPart from = PART_INVALID,
331
+ const string& remark = "") override {
332
+ return (datetime >= m_run_start)
333
+ ? m_tm->buyShort(datetime, stock, realPrice, number, stoploss, goalPrice,
334
+ planPrice, from, remark)
335
+ : TradeRecord();
332
336
  }
333
337
 
334
338
  /**
@@ -0,0 +1,226 @@
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_DLL_LOADER_H_
10
+ #define HKU_UTILS_DLL_LOADER_H_
11
+
12
+ #include <string>
13
+ #include <vector>
14
+ #include <cstdlib>
15
+ #include "hikyuu/utilities/config.h"
16
+ #include "hikyuu/utilities/osdef.h"
17
+ #include "hikyuu/utilities/os.h"
18
+ #include "hikyuu/utilities/Log.h"
19
+ #include "hikyuu/utilities/arithmetic.h"
20
+
21
+ #if HKU_OS_WINDOWS
22
+ #include <windows.h>
23
+ #else
24
+ #include <dlfcn.h>
25
+ #endif
26
+
27
+ namespace hku {
28
+
29
+ class DllLoader {
30
+ public:
31
+ DllLoader() {
32
+ initDefaultSearchPath();
33
+ }
34
+
35
+ explicit DllLoader(const std::vector<std::string>& path) {
36
+ if (!path.empty()) {
37
+ m_search_paths.resize(path.size());
38
+ std::copy(path.begin(), path.end(), m_search_paths.begin());
39
+ } else {
40
+ HKU_WARN("DllLoader: empty search path! Use default search path!");
41
+ initDefaultSearchPath();
42
+ }
43
+ }
44
+
45
+ DllLoader(const DllLoader&) = delete;
46
+ DllLoader& operator=(const DllLoader&) = delete;
47
+
48
+ DllLoader(DllLoader&& rhs)
49
+ : m_handle(rhs.m_handle), m_search_paths(std::move(rhs.m_search_paths)) {
50
+ rhs.m_handle = nullptr;
51
+ }
52
+
53
+ DllLoader& operator=(DllLoader&& rhs) {
54
+ if (this == &rhs) {
55
+ m_handle = rhs.m_handle;
56
+ m_search_paths = std::move(rhs.m_search_paths);
57
+ rhs.m_handle = nullptr;
58
+ }
59
+ return *this;
60
+ }
61
+
62
+ virtual ~DllLoader() {
63
+ unload();
64
+ }
65
+
66
+ bool load(const std::string& dllname) noexcept {
67
+ std::string filename = search(dllname);
68
+ HKU_WARN_IF_RETURN(filename.empty(), false, "Not found dll: {}!", dllname);
69
+
70
+ #if HKU_OS_WINDOWS
71
+ m_handle = LoadLibrary(HKU_PATH(filename).c_str());
72
+ #else
73
+ m_handle = dlopen(filename.c_str(), RTLD_LAZY);
74
+ #endif
75
+ HKU_WARN_IF_RETURN(!m_handle, false, "load dll({}) failed!", filename);
76
+ return true;
77
+ }
78
+
79
+ void unload() noexcept {
80
+ if (m_handle) {
81
+ #if HKU_OS_WINDOWS
82
+ FreeLibrary(m_handle);
83
+ #else
84
+ dlclose(m_handle);
85
+ #endif
86
+ }
87
+ }
88
+
89
+ std::string search(const std::string& dllname) const noexcept {
90
+ #if HKU_OS_WINDOWS
91
+ std::string dll = fmt::format("{}.dll", dllname);
92
+ #elif HKU_OS_OSX
93
+ std::string dll = fmt::format("lib{}.dylib", dllname);
94
+ #else
95
+ std::string dll = fmt::format("lib{}.so", dllname);
96
+ #endif
97
+ for (const auto& path : m_search_paths) {
98
+ auto filename = fmt::format("{}/{}", path, dll);
99
+ if (existFile(filename)) {
100
+ return filename;
101
+ }
102
+ }
103
+
104
+ return std::string();
105
+ }
106
+
107
+ void* getSymbol(const char* symbol) noexcept {
108
+ #if HKU_OS_WINDOWS
109
+ void* func = GetProcAddress(m_handle, symbol);
110
+ #else
111
+ void* func = dlsym(m_handle, symbol);
112
+ #endif
113
+ return func;
114
+ }
115
+
116
+ private:
117
+ void initDefaultSearchPath() noexcept {
118
+ m_search_paths.emplace_back(".");
119
+
120
+ std::string userdir = getUserDir();
121
+ if (!userdir.empty()) {
122
+ m_search_paths.emplace_back(userdir + "/lib");
123
+ }
124
+
125
+ #if HKU_OS_WINDOWS
126
+ m_search_paths.emplace_back("C:/Windows/System32");
127
+ m_search_paths.emplace_back("C:/Windows/SysWOW64");
128
+ m_search_paths.emplace_back("C:/Windows");
129
+ const char* path = getenv("PATH");
130
+ if (path) {
131
+ std::string pathstr(path);
132
+ auto items = split(pathstr, ";");
133
+ for (auto& item : items) {
134
+ std::string nitem(item);
135
+ trim(nitem);
136
+ if (!item.empty()) {
137
+ m_search_paths.emplace_back(nitem);
138
+ }
139
+ }
140
+ }
141
+
142
+ #elif HKU_OS_OSX
143
+ const char* path = getenv("DYLD_IMAGE_SUFFIX");
144
+ if (path) {
145
+ std::string pathstr(path);
146
+ auto items = split(pathstr, ";");
147
+ for (auto& item : items) {
148
+ std::string nitem(item);
149
+ trim(nitem);
150
+ if (!item.empty()) {
151
+ m_search_paths.emplace_back(nitem);
152
+ }
153
+ }
154
+ }
155
+ path = getenv("DYLD_FRAMEWORK_PATH");
156
+ if (path) {
157
+ std::string pathstr(path);
158
+ auto items = split(pathstr, ";");
159
+ for (auto& item : items) {
160
+ std::string nitem(item);
161
+ trim(nitem);
162
+ if (!item.empty()) {
163
+ m_search_paths.emplace_back(nitem);
164
+ }
165
+ }
166
+ }
167
+ path = getenv("DYLD_LIBRARY_PATH");
168
+ if (path) {
169
+ std::string pathstr(path);
170
+ auto items = split(pathstr, ";");
171
+ for (auto& item : items) {
172
+ std::string nitem(item);
173
+ trim(nitem);
174
+ if (!item.empty()) {
175
+ m_search_paths.emplace_back(nitem);
176
+ }
177
+ }
178
+ }
179
+ m_search_paths.emplace_back("/Library/Frameworks");
180
+ m_search_paths.emplace_back("/Network/Library/Frameworks");
181
+ m_search_paths.emplace_back("/System/Library/Frameworks");
182
+ m_search_paths.emplace_back("/usr/local/lib");
183
+ m_search_paths.emplace_back("/usr/lib");
184
+ m_search_paths.emplace_back("/lib");
185
+
186
+ #else
187
+ const char* path = getenv("LD_LIBRARY_PATH");
188
+ if (path) {
189
+ std::string pathstr(path);
190
+ auto items = split(pathstr, ";");
191
+ for (auto& item : items) {
192
+ std::string nitem(item);
193
+ trim(nitem);
194
+ if (!item.empty()) {
195
+ m_search_paths.emplace_back(nitem);
196
+ }
197
+ }
198
+ }
199
+ m_search_paths.emplace_back("/usr/local/lib");
200
+ m_search_paths.emplace_back("/usr/lib");
201
+ m_search_paths.emplace_back("/lib");
202
+ if (HKU_ARCH_X64) {
203
+ m_search_paths.emplace_back("/usr/lib/x86_64-linux-gnu");
204
+ } else if (HKU_ARCH_ARM64) {
205
+ m_search_paths.emplace_back("/usr/lib/aarch64-linux-gnu");
206
+ } else if (HKU_ARCH_X86) {
207
+ m_search_paths.emplace_back("/usr/lib/i386-linux-gnu");
208
+ } else if (HKU_ARCH_ARM) {
209
+ m_search_paths.emplace_back("/usr/lib/arm-linux-gnueabihf");
210
+ }
211
+ #endif
212
+ }
213
+
214
+ private:
215
+ #if HKU_OS_WINDOWS
216
+ HMODULE m_handle{nullptr};
217
+ #else
218
+ void* m_handle{nullptr};
219
+ #endif
220
+
221
+ std::vector<std::string> m_search_paths;
222
+ };
223
+
224
+ } // namespace hku
225
+
226
+ #endif /* HKU_UTILS_DLL_LOADER_H_ */
@@ -62,6 +62,20 @@ public:
62
62
  */
63
63
  static Datetime fromHex(uint64_t time);
64
64
 
65
+ /**
66
+ * @brief 从时间戳(微秒)创建Datetime对象
67
+ * @param timestamp 微妙级别的时间戳(从1970年1月1日0时0分0秒开始)
68
+ * @return Datetime
69
+ */
70
+ static Datetime fromTimestamp(int64_t timestamp);
71
+
72
+ /**
73
+ * @brief 从时间戳(微秒)创建Datetime对象,并加上本地UTC时间偏差
74
+ * @param timestamp 微妙级别的时间戳(从1970年1月1日0时0分0秒开始)
75
+ * @return Datetime
76
+ */
77
+ static Datetime fromTimestampUTC(int64_t timestamp);
78
+
65
79
  public:
66
80
  /** 默认构造函数,Null<Datetime> */
67
81
  Datetime();
@@ -178,6 +192,12 @@ public:
178
192
  /** 距离最小日期过去的微秒数 */
179
193
  uint64_t ticks() const noexcept;
180
194
 
195
+ /** 时间戳,距离1970-01-01 00:00:00的微秒数 */
196
+ int64_t timestamp() const noexcept;
197
+
198
+ /** 时间戳,距离1970-01-01 00:00:00的微秒数, 并扣除本地 UTC 偏差时间 */
199
+ int64_t timestampUTC() const noexcept;
200
+
181
201
  /**
182
202
  * 转化为字符串,供打印阅读,格式:
183
203
  * <pre>
@@ -316,6 +316,12 @@ inline TimeDelta Microseconds(int64_t microsecs) {
316
316
  return TimeDelta::fromTicks(microsecs);
317
317
  }
318
318
 
319
+ /**
320
+ * 获取当前 UTC 时间偏移
321
+ * @return TimeDelta
322
+ */
323
+ TimeDelta HKU_UTILS_API UTCOffset();
324
+
319
325
  } /* namespace hku */
320
326
 
321
327
  namespace std {
@@ -71,6 +71,16 @@ public:
71
71
  return true;
72
72
  }
73
73
 
74
+ std::string getFileName(const std::string& pluginname) const noexcept {
75
+ #if HKU_OS_WINDOWS
76
+ return fmt::format("{}/{}.dll", m_path, pluginname);
77
+ #elif HKU_OS_LINUX
78
+ return fmt::format("{}/lib{}.so", m_path, pluginname);
79
+ #elif HKU_OS_OSX
80
+ return fmt::format("{}/lib{}.dylib", m_path, pluginname);
81
+ #endif
82
+ }
83
+
74
84
  private:
75
85
  void unload() noexcept {
76
86
  m_plugin.reset();
@@ -92,16 +102,6 @@ private:
92
102
  return func;
93
103
  }
94
104
 
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
- }
104
-
105
105
  private:
106
106
  #if HKU_OS_WINDOWS
107
107
  HMODULE m_handle{nullptr};
@@ -1,5 +1,5 @@
1
1
  /*
2
- * StealMQStealThreadPool.h
2
+ * StealGlobalMQStealThreadPool.h
3
3
  *
4
4
  * Copyright (c) 2019 hikyuu.org
5
5
  *
@@ -30,25 +30,25 @@ namespace hku {
30
30
 
31
31
  /**
32
32
  * @brief 无集中队列多队列偷取任务池
33
- * @ingroup MQStealThreadPool
33
+ * @ingroup GlobalMQStealThreadPool
34
34
  */
35
35
  #ifdef _MSC_VER
36
- class MQStealThreadPool {
36
+ class GlobalMQStealThreadPool {
37
37
  #else
38
- class HKU_UTILS_API MQStealThreadPool {
38
+ class HKU_UTILS_API GlobalMQStealThreadPool {
39
39
  #endif
40
40
  public:
41
41
  /**
42
42
  * 默认构造函数,创建和当前系统CPU数一致的线程数
43
43
  */
44
- MQStealThreadPool() : MQStealThreadPool(std::thread::hardware_concurrency()) {}
44
+ GlobalMQStealThreadPool() : GlobalMQStealThreadPool(std::thread::hardware_concurrency()) {}
45
45
 
46
46
  /**
47
47
  * 构造函数,创建指定数量的线程
48
48
  * @param n 指定的线程数
49
49
  * @param until_empty 任务队列为空时,自动停止运行
50
50
  */
51
- explicit MQStealThreadPool(size_t n, bool until_empty = true)
51
+ explicit GlobalMQStealThreadPool(size_t n, bool until_empty = true)
52
52
  : m_done(false), m_worker_num(n), m_runnging_until_empty(until_empty) {
53
53
  try {
54
54
  m_interrupt_flags.resize(m_worker_num, nullptr);
@@ -58,7 +58,7 @@ public:
58
58
  }
59
59
  // 初始完毕所有线程资源后再启动线程
60
60
  for (int i = 0; i < m_worker_num; i++) {
61
- m_threads.emplace_back(&MQStealThreadPool::worker_thread, this, i);
61
+ m_threads.emplace_back(&GlobalMQStealThreadPool::worker_thread, this, i);
62
62
  }
63
63
  } catch (...) {
64
64
  m_done = true;
@@ -69,7 +69,7 @@ public:
69
69
  /**
70
70
  * 析构函数,等待并阻塞至线程池内所有任务完成
71
71
  */
72
- ~MQStealThreadPool() {
72
+ ~GlobalMQStealThreadPool() {
73
73
  if (!m_done) {
74
74
  join();
75
75
  }
@@ -106,7 +106,8 @@ public:
106
106
  template <typename FunctionType>
107
107
  auto submit(FunctionType f) {
108
108
  if (m_thread_need_stop.isSet() || m_done) {
109
- throw std::logic_error("You can't submit a task to the stopped MQStealThreadPool!");
109
+ throw std::logic_error(
110
+ "You can't submit a task to the stopped GlobalMQStealThreadPool!");
110
111
  }
111
112
 
112
113
  typedef typename std::invoke_result<FunctionType>::type result_type;
@@ -256,13 +257,12 @@ private:
256
257
  void worker_thread(int index) {
257
258
  m_index = index;
258
259
  m_interrupt_flags[index] = &m_thread_need_stop;
259
- m_local_work_queue = m_queues[m_index].get();
260
+ m_local_work_queue = m_queues[index].get();
260
261
  while (!m_thread_need_stop.isSet() && !m_done) {
261
262
  run_pending_task();
262
263
  }
263
- m_interrupt_flags[m_index] = nullptr;
264
+ m_interrupt_flags[index] = nullptr;
264
265
  m_local_work_queue = nullptr;
265
- // printf("%zu thread (%lld) finished!\n", m_index, std::this_thread::get_id());
266
266
  }
267
267
 
268
268
  void run_pending_task() {