hikyuu 2.1.2__cp39-none-win_amd64.whl → 2.1.4__cp39-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 (67) hide show
  1. hikyuu/cpp/core39.pyd +0 -0
  2. hikyuu/cpp/hikyuu.dll +0 -0
  3. hikyuu/cpp/sqlite3.dll +0 -0
  4. hikyuu/data/em_block_to_mysql.py +45 -31
  5. hikyuu/data/em_block_to_sqlite.py +48 -33
  6. hikyuu/data/mysql_upgrade/0019.sql +6 -0
  7. hikyuu/data/mysql_upgrade/0020.sql +4 -0
  8. hikyuu/data/mysql_upgrade/0021.sql +4 -0
  9. hikyuu/data/pytdx_to_h5.py +21 -15
  10. hikyuu/data/pytdx_to_mysql.py +20 -2
  11. hikyuu/data/pytdx_weight_to_mysql.py +1 -1
  12. hikyuu/data/pytdx_weight_to_sqlite.py +1 -1
  13. hikyuu/data/sqlite_upgrade/0020.sql +4 -0
  14. hikyuu/data/sqlite_upgrade/0021.sql +6 -0
  15. hikyuu/data/sqlite_upgrade/0022.sql +6 -0
  16. hikyuu/fetcher/stock/zh_stock_a_pytdx.py +56 -8
  17. hikyuu/fetcher/stock/zh_stock_a_qmt.py +49 -40
  18. hikyuu/fetcher/stock/zh_stock_a_sina_qq.py +15 -5
  19. hikyuu/gui/HikyuuTDX.py +1 -1
  20. hikyuu/gui/data/ImportWeightToSqliteTask.py +18 -27
  21. hikyuu/gui/data/UsePytdxImportToH5Thread.py +17 -6
  22. hikyuu/gui/data/UseTdxImportToH5Thread.py +30 -6
  23. hikyuu/gui/spot_server.py +3 -1
  24. hikyuu/include/hikyuu/KQuery.h +5 -2
  25. hikyuu/include/hikyuu/KRecord.h +1 -1
  26. hikyuu/include/hikyuu/Stock.h +1 -1
  27. hikyuu/include/hikyuu/StockManager.h +26 -20
  28. hikyuu/include/hikyuu/StrategyContext.h +66 -25
  29. hikyuu/include/hikyuu/data_driver/BaseInfoDriver.h +1 -0
  30. hikyuu/include/hikyuu/doc.h +1 -1
  31. hikyuu/include/hikyuu/global/GlobalSpotAgent.h +5 -2
  32. hikyuu/include/hikyuu/global/agent/SpotAgent.h +28 -6
  33. hikyuu/include/hikyuu/hikyuu.h +13 -0
  34. hikyuu/include/hikyuu/indicator/crt/AMA.h +1 -1
  35. hikyuu/include/hikyuu/indicator/crt/CORR.h +1 -1
  36. hikyuu/include/hikyuu/indicator/crt/ICIR.h +1 -0
  37. hikyuu/include/hikyuu/indicator/crt/SMA.h +1 -1
  38. hikyuu/include/hikyuu/indicator/crt/SPEARMAN.h +1 -1
  39. hikyuu/include/hikyuu/strategy/BrokerTradeManager.h +1 -2
  40. hikyuu/include/hikyuu/strategy/RunPortfolioInStrategy.h +1 -1
  41. hikyuu/include/hikyuu/strategy/Strategy.h +18 -4
  42. hikyuu/include/hikyuu/trade_manage/OrderBrokerBase.h +3 -0
  43. hikyuu/include/hikyuu/trade_manage/TradeManagerBase.h +1 -2
  44. hikyuu/include/hikyuu/trade_sys/allocatefunds/AllocateFundsBase.h +0 -1
  45. hikyuu/include/hikyuu/trade_sys/condition/ConditionBase.h +1 -0
  46. hikyuu/include/hikyuu/trade_sys/portfolio/Portfolio.h +1 -0
  47. hikyuu/include/hikyuu/trade_sys/selector/imp/FixedSelector.h +1 -1
  48. hikyuu/include/hikyuu/trade_sys/selector/imp/OperatorSelector.h +11 -2
  49. hikyuu/include/hikyuu/trade_sys/selector/imp/OperatorValueSelector.h +19 -2
  50. hikyuu/include/hikyuu/utilities/Parameter.h +1 -1
  51. hikyuu/include/hikyuu/utilities/TimerManager.h +2 -2
  52. hikyuu/include/hikyuu/utilities/arithmetic.h +4 -4
  53. hikyuu/include/hikyuu/utilities/base64.h +1 -2
  54. hikyuu/include/hikyuu/utilities/config.h +1 -1
  55. hikyuu/include/hikyuu/utilities/mo/moFileReader.h +2 -2
  56. hikyuu/include/hikyuu/utilities/node/NodeMessage.h +1 -3
  57. hikyuu/include/hikyuu/utilities/thread/MQStealThreadPool.h +6 -7
  58. hikyuu/include/hikyuu/version.h +4 -4
  59. hikyuu/interactive.py +55 -131
  60. {hikyuu-2.1.2.dist-info → hikyuu-2.1.4.dist-info}/METADATA +1 -1
  61. {hikyuu-2.1.2.dist-info → hikyuu-2.1.4.dist-info}/RECORD +65 -61
  62. hikyuu/include/hikyuu/global/GlobalTaskGroup.h +0 -44
  63. hikyuu/puppet.py +0 -297
  64. {hikyuu-2.1.2.dist-info → hikyuu-2.1.4.dist-info}/LICENSE +0 -0
  65. {hikyuu-2.1.2.dist-info → hikyuu-2.1.4.dist-info}/WHEEL +0 -0
  66. {hikyuu-2.1.2.dist-info → hikyuu-2.1.4.dist-info}/entry_points.txt +0 -0
  67. {hikyuu-2.1.2.dist-info → hikyuu-2.1.4.dist-info}/top_level.txt +0 -0
@@ -42,7 +42,7 @@ from hikyuu.util.check import hku_catch, hku_check
42
42
 
43
43
 
44
44
  class ImportWeightToSqliteTask:
45
- def __init__(self, log_queue, queue, config, dest_dir):
45
+ def __init__(self, log_queue, queue, config, dest_dir, market, cmd, host, port):
46
46
  self.logger = logging.getLogger(self.__class__.__name__)
47
47
  self.log_queue = log_queue
48
48
  self.queue = queue
@@ -50,6 +50,10 @@ class ImportWeightToSqliteTask:
50
50
  self.dest_dir = dest_dir
51
51
  self.msg_name = 'IMPORT_WEIGHT'
52
52
  self.status = "no run"
53
+ self.market = market
54
+ self.cmd = cmd # "weight" | "finance"
55
+ self.host = host
56
+ self.port = port
53
57
 
54
58
  @hku_catch(trace=True)
55
59
  def __call__(self):
@@ -76,44 +80,31 @@ class ImportWeightToSqliteTask:
76
80
  self.logger.debug('use mysql import weight')
77
81
 
78
82
  except Exception as e:
79
- #self.queue.put([self.msg_name, str(e), -1, 0, total_count])
83
+ # self.queue.put([self.msg_name, str(e), -1, 0, total_count])
80
84
  self.queue.put([self.msg_name, 'INFO', str(e), 0, 0])
81
85
  self.queue.put([self.msg_name, '', 0, None, total_count])
82
86
  self.status = "failure"
83
87
  return
84
88
 
85
89
  try:
86
- hosts = search_best_tdx()
87
90
  api = TdxHq_API()
88
- hku_check(api.connect(hosts[0][2], hosts[0][3]), "failed connect pytdx {}:{}!", hosts[0][2], hosts[0][3])
89
-
90
- self.logger.info('正在导入权息数据')
91
- self.queue.put([self.msg_name, '正在导入权息数据...', 0, 0, 0])
92
-
93
- total_count = 0
94
- for market in g_market_list:
95
- count = pytdx_import_weight(api, connect, market)
96
- self.logger.info("导入 {} 权息记录数: {}".format(market, count))
97
- total_count += count
98
-
99
- self.queue.put([self.msg_name, '导入权息数据完毕!', 0, 0, total_count])
100
- self.logger.info('导入权息数据完毕')
101
-
102
- self.queue.put([self.msg_name, '下载通达信财务信息(上证)...', 0, 0, 0])
103
- x = pytdx_import_finance(connect, api, "SH")
104
-
105
- self.queue.put([self.msg_name, '下载通达信财务信息(深证)...', 0, 0, 0])
106
- x += pytdx_import_finance(connect, api, "SZ")
107
-
108
- self.queue.put([self.msg_name, '下载通达信财务信息(北证)...', 0, 0, 0])
109
- x += pytdx_import_finance(connect, api, "BJ")
110
- self.queue.put([self.msg_name, '导入通达信财务信息完毕!', 0, 0, x])
91
+ hku_check(api.connect(self.host, self.port), "failed connect pytdx {}:{}!", self.host, self.port)
92
+
93
+ if self.cmd == 'weight':
94
+ count = pytdx_import_weight(api, connect, self.market)
95
+ self.logger.info("导入 {} 权息记录数: {}".format(self.market, count))
96
+ self.queue.put([self.msg_name, '导入权息数据完毕!', 0, 0, f'{self.market} {total_count}'])
97
+ elif self.cmd == 'finance':
98
+ self.queue.put([self.msg_name, f'下载通达信当前财务信息({self.market})...', 0, 0, 0])
99
+ x = pytdx_import_finance(connect, api, self.market)
100
+ self.logger.info(f'导入 {self.market} 通达信当前财务信息数: {x}')
101
+ self.queue.put([self.msg_name, '导入通达信财务信息完毕!', 0, 0, f'{self.market} {x}'])
111
102
 
112
103
  api.disconnect()
113
104
 
114
105
  except Exception as e:
115
106
  self.logger.error(e)
116
- #self.queue.put([self.msg_name, str(e), -1, 0, total_count])
107
+ # self.queue.put([self.msg_name, str(e), -1, 0, total_count])
117
108
  self.queue.put([self.msg_name, 'INFO', str(e), 0, 0])
118
109
  finally:
119
110
  connect.commit()
@@ -84,14 +84,8 @@ class UsePytdxImportToH5Thread(QThread):
84
84
  def init_task(self):
85
85
  config = self.config
86
86
  dest_dir = config['hdf5']['dir']
87
- sqlite_file_name = dest_dir + "/stock.db"
88
87
 
89
88
  self.tasks = []
90
- if self.config.getboolean('weight', 'enable', fallback=False):
91
- self.tasks.append(
92
- ImportWeightToSqliteTask(self.log_queue, self.queue,
93
- self.config, dest_dir))
94
-
95
89
  if self.config.getboolean('finance', 'enable', fallback=True):
96
90
  self.tasks.append(
97
91
  ImportHistoryFinanceTask(self.log_queue, self.queue, self.config, dest_dir))
@@ -112,6 +106,8 @@ class UsePytdxImportToH5Thread(QThread):
112
106
  task_count += market_count
113
107
  if self.config.getboolean('ktype', 'time', fallback=False):
114
108
  task_count += market_count
109
+ if self.config.getboolean('weight', 'enable', fallback=False):
110
+ task_count += (market_count*2)
115
111
 
116
112
  self.logger.info('搜索通达信服务器')
117
113
  self.send_message(['INFO', '搜索通达信服务器'])
@@ -210,6 +206,19 @@ class UsePytdxImportToH5Thread(QThread):
210
206
  start_date.month * 1000000 + start_date.day * 10000))
211
207
  cur_host += 1
212
208
 
209
+ if self.config.getboolean('weight', 'enable', fallback=False):
210
+ for market in g_market_list:
211
+ self.tasks.append(
212
+ ImportWeightToSqliteTask(self.log_queue, self.queue,
213
+ self.config, dest_dir, market, 'weight', use_hosts[cur_host][0],
214
+ use_hosts[cur_host][1]))
215
+ cur_host += 1
216
+ self.tasks.append(
217
+ ImportWeightToSqliteTask(self.log_queue, self.queue,
218
+ self.config, dest_dir, market, 'finance', use_hosts[cur_host][0],
219
+ use_hosts[cur_host][1]))
220
+ cur_host += 1
221
+
213
222
  def run(self):
214
223
  try:
215
224
  self.init_task()
@@ -298,6 +307,8 @@ class UsePytdxImportToH5Thread(QThread):
298
307
  self.send_message([taskname, ktype])
299
308
  elif taskname == 'IMPORT_ZH_BOND10':
300
309
  self.send_message([taskname, ktype])
310
+ elif taskname == 'IMPORT_WEIGHT':
311
+ pass
301
312
  else:
302
313
  self.send_message([taskname, 'FINISHED'])
303
314
  continue
@@ -30,7 +30,10 @@ from hikyuu.gui.data.ImportTdxToH5Task import ImportTdxToH5Task
30
30
  from hikyuu.gui.data.ImportWeightToSqliteTask import ImportWeightToSqliteTask
31
31
  from hikyuu.gui.data.ImportHistoryFinanceTask import ImportHistoryFinanceTask
32
32
 
33
+ from pytdx.hq import TdxHq_API
34
+ from hikyuu.data.common import g_market_list
33
35
  from hikyuu.data.common_sqlite3 import create_database
36
+ from hikyuu.data.common_pytdx import search_best_tdx
34
37
  from hikyuu.data.tdx_to_h5 import tdx_import_stock_name_from_file
35
38
  from hikyuu.util import *
36
39
 
@@ -57,18 +60,39 @@ class UseTdxImportToH5Thread(QThread):
57
60
  self.quotations.append('stock')
58
61
  if self.config['quotation']['fund']:
59
62
  self.quotations.append('fund')
60
- #if self.config['quotation']['future']:
63
+ # if self.config['quotation']['future']:
61
64
  # self.quotations.append('future')
62
65
 
63
- #通达信盘后没有债券数据。另外,如果用Pytdx下载债券数据,
64
- #每个债券本身的数据很少但债券种类太多占用空间和时间太多,用途较少不再考虑导入
65
- #if self.config['quotation']['bond']:
66
+ # 通达信盘后没有债券数据。另外,如果用Pytdx下载债券数据,
67
+ # 每个债券本身的数据很少但债券种类太多占用空间和时间太多,用途较少不再考虑导入
68
+ # if self.config['quotation']['bond']:
66
69
  # self.quotations.append('bond')
67
70
 
71
+ hosts = search_best_tdx()
72
+ api = TdxHq_API()
73
+ hku_check(api.connect(hosts[0][2], hosts[0][3]), "failed connect pytdx {}:{}!", hosts[0][2], hosts[0][3])
74
+
68
75
  self.queue = Queue()
69
76
  self.tasks = []
77
+
78
+ cur_host = 0
70
79
  if self.config.getboolean('weight', 'enable', fallback=False):
71
- self.tasks.append(ImportWeightToSqliteTask(self.log_queue, self.queue, self.config, dest_dir))
80
+ for market in g_market_list:
81
+ self.tasks.append(
82
+ ImportWeightToSqliteTask(self.log_queue, self.queue,
83
+ self.config, dest_dir, market, 'weight', hosts[cur_host][2],
84
+ hosts[cur_host][3]))
85
+ cur_host += 1
86
+ if cur_host >= len(hosts):
87
+ cur_host = 0
88
+ self.tasks.append(
89
+ ImportWeightToSqliteTask(self.log_queue, self.queue,
90
+ self.config, dest_dir, market, 'finance', hosts[cur_host][2],
91
+ hosts[cur_host][3]))
92
+ cur_host += 1
93
+ if cur_host >= len(hosts):
94
+ cur_host = 0
95
+
72
96
  if self.config.getboolean('finance', 'enable', fallback=True):
73
97
  self.tasks.append(ImportHistoryFinanceTask(self.log_queue, self.queue, self.config, dest_dir))
74
98
  if self.config.getboolean('ktype', 'day', fallback=False):
@@ -115,7 +139,7 @@ class UseTdxImportToH5Thread(QThread):
115
139
  dest_dir = self.config['hdf5']['dir']
116
140
  hdf5_import_progress = {'SH': {'DAY': 0, '1MIN': 0, '5MIN': 0}, 'SZ': {'DAY': 0, '1MIN': 0, '5MIN': 0}}
117
141
 
118
- #正在导入代码表
142
+ # 正在导入代码表
119
143
  self.send_message(['START_IMPORT_CODE'])
120
144
 
121
145
  connect = sqlite3.connect(dest_dir + "/stock.db")
hikyuu/gui/spot_server.py CHANGED
@@ -271,7 +271,9 @@ def collect(server, use_proxy, source, seconds, phase1, phase2, ignore_weekend):
271
271
 
272
272
  sm = StockManager.instance()
273
273
  if source == 'qmt':
274
- stk_list = [s for s in sm if s.valid]
274
+ stk_list = [s for s in sm if s.valid and s.type in (
275
+ constant.STOCKTYPE_A, constant.STOCKTYPE_INDEX, constant.STOCKTYPE_ETF,
276
+ constant.STOCKTYPE_GEM, constant.STOCKTYPE_START, constant.STOCKTYPE_A_BJ)]
275
277
  else:
276
278
  stk_list = [
277
279
  stk.market_code.lower() for stk in sm if stk.valid and stk.type in
@@ -70,10 +70,13 @@ public:
70
70
  // static const string INVALID_KTYPE;
71
71
 
72
72
  /** 获取所有的 KType */
73
- static vector<string>& getAllKType();
73
+ static const vector<KType>& getAllKType();
74
74
 
75
75
  static int32_t getKTypeInMin(KType);
76
76
 
77
+ /** 判断是否为有效 ktype */
78
+ static bool isKType(const string& ktype);
79
+
77
80
  /**
78
81
  * 复权类型
79
82
  * @note 日线以上,如周线/月线不支持复权
@@ -93,7 +96,7 @@ public:
93
96
  m_end(Null<int64_t>()),
94
97
  m_queryType(INDEX),
95
98
  m_dataType(DAY),
96
- m_recoverType(NO_RECOVER){};
99
+ m_recoverType(NO_RECOVER) {};
97
100
 
98
101
  /**
99
102
  * K线查询,范围[start, end)
@@ -24,7 +24,7 @@ public:
24
24
  price_t highPrice; ///< 最高价
25
25
  price_t lowPrice; ///< 最低价
26
26
  price_t closePrice; ///< 收盘价
27
- price_t transAmount; ///< 成交金额(千元)
27
+ price_t transAmount; ///< 成交金额(万元)
28
28
  price_t transCount; ///< 成交量(手),日线以下为股数
29
29
 
30
30
  KRecord()
@@ -162,7 +162,7 @@ public:
162
162
  */
163
163
  bool getIndexRange(const KQuery& query, size_t& out_start, size_t& out_end) const;
164
164
 
165
- /** 获取指定索引的K线数据记录,未作越界检查 */
165
+ /** 获取指定索引的K线数据记录,pos 无效时返回 Null<KRecord> */
166
166
  KRecord getKRecord(size_t pos, const KQuery::KType& dataType = KQuery::DAY) const;
167
167
 
168
168
  /** 根据数据类型(日线/周线等),获取指定日期的KRecord */
@@ -10,8 +10,9 @@
10
10
 
11
11
  #include <mutex>
12
12
  #include <thread>
13
- #include "utilities/Parameter.h"
14
- #include "data_driver/DataDriverFactory.h"
13
+ #include "hikyuu/utilities/Parameter.h"
14
+ #include "hikyuu/utilities/thread/thread.h"
15
+ #include "hikyuu/data_driver/DataDriverFactory.h"
15
16
  #include "Block.h"
16
17
  #include "MarketInfo.h"
17
18
  #include "StockTypeInfo.h"
@@ -21,9 +22,6 @@ namespace hku {
21
22
 
22
23
  typedef vector<string> MarketList;
23
24
 
24
- Parameter default_preload_param();
25
- Parameter default_other_param();
26
-
27
25
  /**
28
26
  * 证券信息统一管理类
29
27
  * @ingroup StockManage
@@ -47,8 +45,8 @@ public:
47
45
  * @param context 策略上下文
48
46
  */
49
47
  void init(const Parameter& baseInfoParam, const Parameter& blockParam,
50
- const Parameter& kdataParam, const Parameter& preloadParam = default_preload_param(),
51
- const Parameter& hikyuuParam = default_other_param(),
48
+ const Parameter& kdataParam, const Parameter& preloadParam,
49
+ const Parameter& hikyuuParam,
52
50
  const StrategyContext& context = StrategyContext({"all"}));
53
51
 
54
52
  /** 重新加载 */
@@ -90,6 +88,9 @@ public:
90
88
  /** 获取证券数量 */
91
89
  size_t size() const;
92
90
 
91
+ /** 是否所有数据准备完毕 */
92
+ bool dataReady() const;
93
+
93
94
  /**
94
95
  * 根据"市场简称证券代码"获取对应的证券实例
95
96
  * @param querystr 格式:“市场简称证券代码”,如"sh000001"
@@ -218,6 +219,11 @@ public:
218
219
  return m_thread_id;
219
220
  }
220
221
 
222
+ /** 仅由程序退出使使用!!! */
223
+ ThreadPool* getLoadTaskGroup() {
224
+ return m_load_tg.get();
225
+ }
226
+
221
227
  public:
222
228
  typedef StockMapIterator const_iterator;
223
229
  const_iterator begin() const {
@@ -228,8 +234,8 @@ public:
228
234
  }
229
235
 
230
236
  private:
231
- /* 设置K线驱动 */
232
- void setKDataDriver(const KDataDriverConnectPoolPtr&);
237
+ /* 加载全部数据 */
238
+ void loadData();
233
239
 
234
240
  /* 加载 K线数据至缓存 */
235
241
  void loadAllKData();
@@ -255,15 +261,13 @@ private:
255
261
  /** 加载历史财经字段索引 */
256
262
  void loadHistoryFinanceField();
257
263
 
258
- /** 加载历史财务数据 */
259
- void loadHistoryFinance();
260
-
261
264
  private:
262
265
  StockManager();
263
266
 
264
267
  private:
265
268
  static StockManager* m_sm;
266
269
  std::atomic_bool m_initializing;
270
+ std::atomic_bool m_data_ready; // 用于指示是否所有数据准备完毕
267
271
  std::thread::id m_thread_id; // 记录线程id,用于判断Stratege是以独立进程方式还是线程方式运行
268
272
  string m_tmpdir;
269
273
  string m_datadir;
@@ -271,18 +275,18 @@ private:
271
275
  BlockInfoDriverPtr m_blockDriver;
272
276
 
273
277
  StockMapIterator::stock_map_t m_stockDict; // SH000001 -> stock
274
- std::mutex* m_stockDict_mutex;
278
+ std::shared_mutex* m_stockDict_mutex;
275
279
 
276
280
  typedef unordered_map<string, MarketInfo> MarketInfoMap;
277
281
  mutable MarketInfoMap m_marketInfoDict;
278
- std::mutex* m_marketInfoDict_mutex;
282
+ std::shared_mutex* m_marketInfoDict_mutex;
279
283
 
280
284
  typedef unordered_map<uint32_t, StockTypeInfo> StockTypeInfoMap;
281
285
  mutable StockTypeInfoMap m_stockTypeInfo;
282
- std::mutex* m_stockTypeInfo_mutex;
286
+ std::shared_mutex* m_stockTypeInfo_mutex;
283
287
 
284
288
  std::unordered_set<Datetime> m_holidays; // 节假日
285
- std::mutex* m_holidays_mutex;
289
+ std::shared_mutex* m_holidays_mutex;
286
290
 
287
291
  ZhBond10List m_zh_bond10; // 10年期中国国债收益率数据
288
292
 
@@ -295,18 +299,20 @@ private:
295
299
  Parameter m_preloadParam;
296
300
  Parameter m_hikyuuParam;
297
301
  StrategyContext m_context;
302
+
303
+ std::unique_ptr<ThreadPool> m_load_tg; // 异步数据加载辅助线程组
298
304
  };
299
305
 
300
306
  inline size_t StockManager::size() const {
301
307
  return m_stockDict.size();
302
308
  }
303
309
 
304
- inline Stock StockManager::operator[](const string& query) const {
305
- return getStock(query);
310
+ inline bool StockManager::dataReady() const {
311
+ return m_data_ready;
306
312
  }
307
313
 
308
- inline bool StockManager::isHoliday(const Datetime& d) const {
309
- return m_holidays.count(d);
314
+ inline Stock StockManager::operator[](const string& query) const {
315
+ return getStock(query);
310
316
  }
311
317
 
312
318
  inline const Parameter& StockManager::getBaseInfoDriverParameter() const {
@@ -12,55 +12,96 @@
12
12
 
13
13
  namespace hku {
14
14
 
15
+ /**
16
+ * 策略上下文,定义策略执行时包含的证券/K线级别信息
17
+ * @ingroup Strategy
18
+ *
19
+ */
15
20
  class HKU_API StrategyContext {
16
21
  public:
17
- StrategyContext() {}
18
- StrategyContext(const StrategyContext&) = default;
19
-
20
- explicit StrategyContext(const vector<string>& stockCodeList)
21
- : m_stockCodeList(stockCodeList) {}
22
- explicit StrategyContext(vector<string>&& stockCodeList)
23
- : m_stockCodeList(std::move(stockCodeList)) {}
24
-
25
- StrategyContext(const vector<string>& stockCodeList, const vector<KQuery::KType>& ktypeList)
26
- : m_stockCodeList(stockCodeList), m_ktypeList(ktypeList) {}
27
-
22
+ StrategyContext() = default;
28
23
  virtual ~StrategyContext() = default;
29
24
 
25
+ /**
26
+ * 构造函数
27
+ * @note 未指定 ktypelist 时,默认按预加载参数加载全部
28
+ * @param stockCodeList 指定的证券代码列表,如:如:{"sz000001", "sz000002"}
29
+ */
30
+ explicit StrategyContext(const vector<string>& stockCodeList);
31
+
32
+ /**
33
+ * 构造函数
34
+ * @note 证券列表中如果包含 ("ALL") 则表示全部证券;
35
+ * 指定K线类型列表同时影响着K线数据的优先加载顺序,靠前的将优先加载。同时受系统配置中预加载参数影响!
36
+ * @param stockCodeList 指定的证券代码列表,如:{"sh000001", "sz000001"}
37
+ * @param ktypeList 指定的 K线数据列表,如:{"day", "min"}
38
+ */
39
+ StrategyContext(const vector<string>& stockCodeList, const vector<KQuery::KType>& ktypeList);
40
+
41
+ // 自定义移动构造与赋值会引起 python 中无法正常退出
42
+ // StrategyContext(const StrategyContext&) = default;
43
+ // StrategyContext(StrategyContext&& rv) = delete;
44
+ // StrategyContext& operator=(const StrategyContext&) = default;
45
+ // StrategyContext& operator=(StrategyContext&&) = delete;
46
+
47
+ /**
48
+ * 是否为加载全部证券,只要 stockCodeList 包含 "ALL"(不区分大小写) ,即认为加载全部
49
+ * @return true
50
+ * @return false
51
+ */
30
52
  bool isAll() const noexcept;
31
53
 
32
- bool isValid() const noexcept;
54
+ bool empty() const noexcept {
55
+ return m_stockCodeList.empty();
56
+ }
33
57
 
34
58
  Datetime startDatetime() const noexcept {
35
59
  return m_startDatetime;
36
60
  }
37
61
 
38
- void startDatetime(const Datetime& d) {
39
- HKU_CHECK(!d.isNull(), "Don't use null datetime!");
40
- m_startDatetime = d;
41
- }
42
-
43
- void setStockCodeList(vector<string>&& stockList) {
44
- m_stockCodeList = std::move(stockList);
62
+ void setStockCodeList(const vector<string>& stockList) {
63
+ _removeDuplicateCode(stockList);
45
64
  }
46
65
 
47
- void setStockCodeList(const vector<string>& stockList);
48
-
49
- const vector<string>& getStockCodeList() const {
66
+ const vector<string>& getStockCodeList() const noexcept {
50
67
  return m_stockCodeList;
51
68
  }
52
69
 
53
- void setKTypeList(const vector<KQuery::KType>& ktypeList);
70
+ void setKTypeList(const vector<KQuery::KType>& ktypeList) {
71
+ _checkAndRemoveDuplicateKType(ktypeList);
72
+ }
54
73
 
55
- /** 该返回的 ktype 列表,已经按从小到大进行排序 */
56
- const vector<KQuery::KType>& getKTypeList() const {
74
+ const vector<KQuery::KType>& getKTypeList() const noexcept {
57
75
  return m_ktypeList;
58
76
  }
59
77
 
78
+ /**
79
+ * 隐含的默认必须被加载的证券列表
80
+ * @note 影响交易日历判断、和某些常被作为默认比较基准的证券,通常被作为某些函数的默认值
81
+ */
82
+ const vector<string>& getMustLoadStockCodeList() const noexcept {
83
+ return m_mustLoad;
84
+ }
85
+
86
+ /**
87
+ * 返回所有需要加载的证券列表(含指定的证券列表和默认包含必须加载的证券列表)
88
+ * @return vector<string>
89
+ */
90
+ vector<string> getAllNeedLoadStockCodeList() const noexcept;
91
+
92
+ string str() const;
93
+
94
+ private:
95
+ void _removeDuplicateCode(const vector<string>& stockCodeList);
96
+ void _checkAndRemoveDuplicateKType(const vector<KQuery::KType>& ktypeList);
97
+
60
98
  private:
61
99
  Datetime m_startDatetime{19901219};
100
+ vector<string> m_mustLoad{"sh000001", "sh000300"}; // 默认必须加载的 stock
62
101
  vector<string> m_stockCodeList;
63
102
  vector<KQuery::KType> m_ktypeList;
64
103
  };
65
104
 
105
+ HKU_API std::ostream& operator<<(std::ostream& os, const StrategyContext& context);
106
+
66
107
  } // namespace hku
@@ -123,6 +123,7 @@ public:
123
123
  * @param market 市场简称
124
124
  * @param code 证券代码
125
125
  * @param start 财务报告发布起始日期
126
+ * @param end 查询结束日期
126
127
  * @return vector<float> [[财务报告发布日期(ymd), 字段1, 字段2, ...], ...]
127
128
  */
128
129
  virtual vector<HistoryFinanceInfo> getHistoryFinance(const string& market, const string& code,
@@ -137,7 +137,7 @@
137
137
  * @details 合成多因子
138
138
  * @ingroup TradeSystem
139
139
  *
140
- * @defgroup Stratgy Strategy 策略运行时
140
+ * @defgroup Strategy Strategy 策略运行时
141
141
  * @details 策略运行时
142
142
  * @ingroup Hikyuu
143
143
  *
@@ -13,9 +13,12 @@ namespace hku {
13
13
  /**
14
14
  * 启动 Spot 数据接收代理,如果之前已经处于运行状态,将抛出异常
15
15
  * @param print 打印接收数据进展
16
+ * @param worker_num 接收数据后处理时的工作任务组线程数
17
+ * @param addr 服务端地址,为空表示使用 hikyuu 配置文件中的行情服务器地址
16
18
  * @ingroup Agent
17
19
  */
18
- void HKU_API startSpotAgent(bool print = true);
20
+ void HKU_API startSpotAgent(bool print = true, size_t worker_num = 1,
21
+ const string& addr = string());
19
22
 
20
23
  /**
21
24
  * 终止 Spot 数据接收代理
@@ -25,6 +28,6 @@ void HKU_API stopSpotAgent();
25
28
 
26
29
  SpotAgent* getGlobalSpotAgent();
27
30
 
28
- void releaseGlobalSpotAgent();
31
+ void HKU_API releaseGlobalSpotAgent();
29
32
 
30
33
  } // namespace hku
@@ -43,12 +43,31 @@ public:
43
43
  return !m_stop;
44
44
  }
45
45
 
46
+ void setWorkerNum(size_t worker_num) {
47
+ m_work_num = worker_num;
48
+ }
49
+
50
+ size_t getWorkerNum() const {
51
+ return m_work_num;
52
+ }
53
+
46
54
  /** 设置是否打印数据接收进展情况,主要用于在交互环境下关闭打印 */
47
55
  void setPrintFlag(bool print) {
48
- std::lock_guard<std::mutex> lock(m_mutex);
49
56
  m_print = print;
50
57
  }
51
58
 
59
+ bool getPrintFlag() const {
60
+ return m_print;
61
+ }
62
+
63
+ void setServerAddr(const string& addr) {
64
+ m_server_addr = addr;
65
+ }
66
+
67
+ const string& getServerAddr() const {
68
+ return m_server_addr;
69
+ }
70
+
52
71
  /**
53
72
  * 增加收到 Spot 数据时的处理函数
54
73
  * @note 仅能在停止状态时执行此操作,否则将抛出异常
@@ -106,15 +125,18 @@ private:
106
125
  enum STATUS m_status = WAITING; // 当前内部状态
107
126
  std::atomic_bool m_stop = true; // 结束代理工作标识
108
127
 
109
- int m_revTimeout = 100; // 连接数据服务超时时长(毫秒)
110
- size_t m_batch_count = 0; // 记录本次批次接收的数据数量
111
- std::thread m_receiveThread; // 数据接收线程
112
- ThreadPool m_tg; // 数据处理任务线程池
128
+ int m_revTimeout = 100; // 连接数据服务超时时长(毫秒)
129
+ size_t m_batch_count = 0; // 记录本次批次接收的数据数量
130
+ std::thread m_receiveThread; // 数据接收线程
131
+ std::unique_ptr<ThreadPool> m_tg; // 数据处理任务线程池
132
+ size_t m_work_num = 1; // 数据处理任务线程池线程数
113
133
  vector<std::future<void>> m_process_task_list;
114
134
 
135
+ bool m_print = true; // 是否打印连接信息
136
+ string m_server_addr; // 服务器地址
137
+
115
138
  // 下面属性被修改时需要加锁,以便可以使用多线程方式运行 strategy
116
139
  std::mutex m_mutex;
117
- bool m_print = true; // 是否打印接收进度,防止的交互模式的影响
118
140
  list<std::function<void(const SpotRecord&)>> m_processList; // 已注册的 spot 处理函数列表
119
141
  list<std::function<void(Datetime)>> m_postProcessList; // 已注册的批次后处理函数列表
120
142
  };
@@ -35,6 +35,19 @@ namespace hku {
35
35
  void HKU_API hikyuu_init(const string& config_file_name, bool ignore_preload = false,
36
36
  const StrategyContext& context = StrategyContext({"all"}));
37
37
 
38
+ /**
39
+ * @brief 尝试从 ini 文件获取配置参数
40
+ * @param config_file_name ini 文件名
41
+ * @param baseParam [out]
42
+ * @param blockParam [out]
43
+ * @param kdataParam [out]
44
+ * @param preloadParam [out]
45
+ * @param hkuParam [out]
46
+ */
47
+ void HKU_API getConfigFromIni(const string& config_file_name, Parameter& baseParam,
48
+ Parameter& blockParam, Parameter& kdataParam, Parameter& preloadParam,
49
+ Parameter& hkuParam);
50
+
38
51
  /** @} */
39
52
 
40
53
  } // namespace hku
@@ -32,7 +32,7 @@ Indicator HKU_API AMA(const IndParam& n, const IndParam& fast_n, const IndParam&
32
32
 
33
33
  /**
34
34
  * 佩里.J 考夫曼(Perry J.Kaufman)自适应移动平均,参见《精明交易者》(2006年 广东经济出版社)
35
- * @param indicator 待计算的数据
35
+ * @param ind 待计算的数据
36
36
  * @param n 计算均值的周期窗口,必须为大于2的整数,默认为10天
37
37
  * @param fast_n 对应快速周期N,默认为2
38
38
  * @param slow_n 对应慢速EMA线的N值,默认为30,不过当超过60左右该指标会收敛不会有太大的影响
@@ -18,7 +18,7 @@ namespace hku {
18
18
  * @param n 滚动窗口 (大于2或等于0),等于0时使用输入的ind实际长度。
19
19
  * @ingroup Indicator
20
20
  */
21
- Indicator HKU_API CORR(int n = 10);
22
21
  Indicator HKU_API CORR(const Indicator& ind1, const Indicator& ind2, int n = 10);
22
+ Indicator HKU_API CORR(int n = 10);
23
23
 
24
24
  } // namespace hku
@@ -16,6 +16,7 @@ namespace hku {
16
16
  * @brief 计算指定的因子相对于参考证券的 ICIR (实际为 RankIC)
17
17
  * @details IR:信息比率(Information Ratio,简称IR)=
18
18
  * IC的多周期均值/IC的标准方差,代表因子获取稳定Alpha的能力。
19
+ * @param ind 因子公式
19
20
  * @param stks 证券组合
20
21
  * @param query 查询条件
21
22
  * @param ref_stk 参照证券,默认 sh000300 沪深300
@@ -34,7 +34,7 @@ Indicator HKU_API SMA(const IndParam& n, const IndParam& m);
34
34
  * <pre>
35
35
  * 用法:若Y=SMA(X,N,M) 则 Y=[M*X+(N-M)*Y')/N,其中Y'表示上一周期Y值
36
36
  * </pre>
37
- * @param data 待计算的数据
37
+ * @param ind 待计算的数据
38
38
  * @param n 计算均值的周期窗口,必须为大于0的整数
39
39
  * @param m 系数
40
40
  * @ingroup Indicator