hikyuu 2.1.4__cp38-none-win_amd64.whl → 2.2.0__cp38-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 (100) hide show
  1. hikyuu/analysis/analysis.py +20 -0
  2. hikyuu/cpp/boost_date_time-mt.dll +0 -0
  3. hikyuu/cpp/boost_serialization-mt.dll +0 -0
  4. hikyuu/cpp/boost_wserialization-mt.dll +0 -0
  5. hikyuu/cpp/core38.pyd +0 -0
  6. hikyuu/cpp/hikyuu.dll +0 -0
  7. hikyuu/cpp/sqlite3.dll +0 -0
  8. hikyuu/data/common.py +3 -3
  9. hikyuu/data/mysql_upgrade/0022.sql +5 -0
  10. hikyuu/data/mysql_upgrade/0023.sql +4 -0
  11. hikyuu/data/pytdx_weight_to_mysql.py +14 -15
  12. hikyuu/data/pytdx_weight_to_sqlite.py +14 -15
  13. hikyuu/data/sqlite_upgrade/0023.sql +7 -0
  14. hikyuu/data/sqlite_upgrade/0024.sql +22 -0
  15. hikyuu/fetcher/stock/zh_stock_a_pytdx.py +3 -3
  16. hikyuu/gui/HikyuuTDX.py +3 -2
  17. hikyuu/gui/data/ImportHistoryFinanceTask.py +7 -0
  18. hikyuu/gui/data/ImportWeightToSqliteTask.py +2 -2
  19. hikyuu/gui/data/MainWindow.py +1 -1
  20. hikyuu/gui/start_qmt.py +99 -13
  21. hikyuu/include/hikyuu/StockWeight.h +16 -10
  22. hikyuu/include/hikyuu/analysis/analysis_sys.h +42 -12
  23. hikyuu/include/hikyuu/data_driver/base_info/table/StockWeightTable.h +6 -4
  24. hikyuu/include/hikyuu/global/agent/SpotAgent.h +5 -6
  25. hikyuu/include/hikyuu/indicator/crt/DMA.h +1 -7
  26. hikyuu/include/hikyuu/indicator/crt/IC.h +7 -6
  27. hikyuu/include/hikyuu/indicator/crt/ICIR.h +7 -4
  28. hikyuu/include/hikyuu/indicator/imp/IDma.h +47 -0
  29. hikyuu/include/hikyuu/indicator/imp/IIc.h +1 -1
  30. hikyuu/include/hikyuu/serialization/StockWeight_serialization.h +5 -2
  31. hikyuu/include/hikyuu/strategy/BrokerTradeManager.h +27 -25
  32. hikyuu/include/hikyuu/strategy/Strategy.h +1 -2
  33. hikyuu/include/hikyuu/trade_manage/Performance.h +3 -0
  34. hikyuu/include/hikyuu/trade_manage/TradeManagerBase.h +16 -6
  35. hikyuu/include/hikyuu/trade_manage/TradeRecord.h +1 -1
  36. hikyuu/include/hikyuu/trade_sys/allocatefunds/AllocateFundsBase.h +0 -3
  37. hikyuu/include/hikyuu/trade_sys/condition/ConditionBase.h +2 -2
  38. hikyuu/include/hikyuu/trade_sys/condition/build_in.h +1 -0
  39. hikyuu/include/hikyuu/trade_sys/condition/crt/CN_Manual.h +20 -0
  40. hikyuu/include/hikyuu/trade_sys/condition/imp/ManualCondition.h +23 -0
  41. hikyuu/include/hikyuu/trade_sys/condition/imp/{AddCondition.h → logic/AddCondition.h} +1 -1
  42. hikyuu/include/hikyuu/trade_sys/condition/imp/{AndCondition.h → logic/AndCondition.h} +1 -1
  43. hikyuu/include/hikyuu/trade_sys/condition/imp/{DivCondition.h → logic/DivCondition.h} +1 -1
  44. hikyuu/include/hikyuu/trade_sys/condition/imp/{MultiCondition.h → logic/MultiCondition.h} +1 -1
  45. hikyuu/include/hikyuu/trade_sys/condition/imp/{OrCondition.h → logic/OrCondition.h} +1 -1
  46. hikyuu/include/hikyuu/trade_sys/condition/imp/logic/__init__.py +1 -0
  47. hikyuu/include/hikyuu/trade_sys/environment/EnvironmentBase.h +6 -6
  48. hikyuu/include/hikyuu/trade_sys/environment/build_in.h +1 -0
  49. hikyuu/include/hikyuu/trade_sys/environment/crt/EV_Manual.h +20 -0
  50. hikyuu/include/hikyuu/trade_sys/environment/imp/ManualEnvironment.h +23 -0
  51. hikyuu/include/hikyuu/trade_sys/multifactor/MultiFactorBase.h +1 -1
  52. hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_EqualWeight.h +3 -1
  53. hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_ICIRWeight.h +3 -2
  54. hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_ICWeight.h +4 -2
  55. hikyuu/include/hikyuu/trade_sys/multifactor/imp/EqualWeightMultiFactor.h +1 -1
  56. hikyuu/include/hikyuu/trade_sys/multifactor/imp/ICIRMultiFactor.h +1 -1
  57. hikyuu/include/hikyuu/trade_sys/multifactor/imp/ICMultiFactor.h +1 -1
  58. hikyuu/include/hikyuu/trade_sys/portfolio/Portfolio.h +2 -2
  59. hikyuu/include/hikyuu/trade_sys/selector/SelectorBase.h +3 -1
  60. hikyuu/include/hikyuu/trade_sys/selector/build_in.h +2 -1
  61. hikyuu/include/hikyuu/trade_sys/selector/crt/SE_MultiFactor.h +2 -1
  62. hikyuu/include/hikyuu/trade_sys/selector/crt/SE_Optimal.h +26 -0
  63. hikyuu/include/hikyuu/trade_sys/selector/imp/{OperatorSelector.h → logic/OperatorSelector.h} +1 -1
  64. hikyuu/include/hikyuu/trade_sys/selector/imp/{OperatorValueSelector.h → logic/OperatorValueSelector.h} +1 -1
  65. hikyuu/include/hikyuu/trade_sys/selector/imp/logic/__init__.py +1 -0
  66. hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/MaxFundsOptimalSelector.h +27 -0
  67. hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/OptimalSelectorBase.h +86 -0
  68. hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/PerformanceOptimalSelector.h +42 -0
  69. hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/__init__.py +1 -0
  70. hikyuu/include/hikyuu/trade_sys/signal/build_in.h +1 -0
  71. hikyuu/include/hikyuu/trade_sys/signal/crt/SG_Manual.h +20 -0
  72. hikyuu/include/hikyuu/trade_sys/signal/imp/ManualSignal.h +23 -0
  73. hikyuu/include/hikyuu/trade_sys/system/System.h +30 -13
  74. hikyuu/include/hikyuu/trade_sys/system/TradeRequest.h +19 -11
  75. hikyuu/include/hikyuu/trade_sys/system/build_in.h +1 -0
  76. hikyuu/include/hikyuu/trade_sys/system/crt/SYS_WalkForward.h +27 -0
  77. hikyuu/include/hikyuu/trade_sys/system/imp/DelegateSystem.h +51 -0
  78. hikyuu/include/hikyuu/trade_sys/system/imp/WalkForwardSystem.h +70 -0
  79. hikyuu/include/hikyuu/trade_sys/system/imp/WalkForwardTradeManager.h +465 -0
  80. hikyuu/include/hikyuu/utilities/base64.h +25 -31
  81. hikyuu/include/hikyuu/version.h +5 -5
  82. hikyuu/strategy/strategy_demo1.py +2 -1
  83. hikyuu/trade_sys/trade_sys.py +28 -9
  84. {hikyuu-2.1.4.dist-info → hikyuu-2.2.0.dist-info}/METADATA +1 -1
  85. {hikyuu-2.1.4.dist-info → hikyuu-2.2.0.dist-info}/RECORD +100 -78
  86. {hikyuu-2.1.4.dist-info → hikyuu-2.2.0.dist-info}/top_level.txt +3 -0
  87. /hikyuu/include/hikyuu/trade_sys/selector/crt/{SE_Operator.h → SE_Logic.h} +0 -0
  88. /hikyuu/include/hikyuu/trade_sys/selector/imp/{OperatorAddSelector.h → logic/OperatorAddSelector.h} +0 -0
  89. /hikyuu/include/hikyuu/trade_sys/selector/imp/{OperatorAddValueSelector.h → logic/OperatorAddValueSelector.h} +0 -0
  90. /hikyuu/include/hikyuu/trade_sys/selector/imp/{OperatorDivSelector.h → logic/OperatorDivSelector.h} +0 -0
  91. /hikyuu/include/hikyuu/trade_sys/selector/imp/{OperatorDivValueSelector.h → logic/OperatorDivValueSelector.h} +0 -0
  92. /hikyuu/include/hikyuu/trade_sys/selector/imp/{OperatorInvertDivValueSelector.h → logic/OperatorInvertDivValueSelector.h} +0 -0
  93. /hikyuu/include/hikyuu/trade_sys/selector/imp/{OperatorInvertSubValueSelector.h → logic/OperatorInvertSubValueSelector.h} +0 -0
  94. /hikyuu/include/hikyuu/trade_sys/selector/imp/{OperatorMulSelector.h → logic/OperatorMulSelector.h} +0 -0
  95. /hikyuu/include/hikyuu/trade_sys/selector/imp/{OperatorMulValueSelector.h → logic/OperatorMulValueSelector.h} +0 -0
  96. /hikyuu/include/hikyuu/trade_sys/selector/imp/{OperatorSubSelector.h → logic/OperatorSubSelector.h} +0 -0
  97. /hikyuu/include/hikyuu/trade_sys/selector/imp/{OperatorSubValueSelector.h → logic/OperatorSubValueSelector.h} +0 -0
  98. {hikyuu-2.1.4.dist-info → hikyuu-2.2.0.dist-info}/LICENSE +0 -0
  99. {hikyuu-2.1.4.dist-info → hikyuu-2.2.0.dist-info}/WHEEL +0 -0
  100. {hikyuu-2.1.4.dist-info → hikyuu-2.2.0.dist-info}/entry_points.txt +0 -0
@@ -31,6 +31,11 @@ def combinate_ind_analysis(
31
31
  :param list keys: 输出 Performance 统计项
32
32
  :rtype: pd.DataFrame
33
33
  '''
34
+ if not keys:
35
+ for key in keys:
36
+ if not Performance.exist(key):
37
+ raise Exception(f'Invalid key: {key}')
38
+
34
39
  pers = inner_combinate_ind_analysis(stk, query, tm, sys, buy_inds, sell_inds, n)
35
40
 
36
41
  if not keys:
@@ -75,6 +80,11 @@ def combinate_ind_analysis_multi(
75
80
  :param int n: 买入信号组合时的周期
76
81
  :param list keys: 输出 Performance 统计项
77
82
  '''
83
+ if not keys:
84
+ for key in keys:
85
+ if not Performance.exist(key):
86
+ raise Exception(f'Invalid key: {key}')
87
+
78
88
  if isinstance(stks, Block):
79
89
  blks = stks
80
90
  else:
@@ -95,6 +105,11 @@ def combinate_ind_analysis_multi(
95
105
 
96
106
 
97
107
  def analysis_sys_list(stks, query, sys_proto, keys=["累计投入本金", "当前总资产", "现金余额", "未平仓头寸净值", "赢利交易比例%", "赢利交易数", "亏损交易数"]):
108
+ if not keys:
109
+ for key in keys:
110
+ if not Performance.exist(key):
111
+ raise Exception(f'Invalid key: {key}')
112
+
98
113
  names = ["证券代码", "证券名称"]
99
114
  names.extend(keys)
100
115
  ret = {}
@@ -119,6 +134,11 @@ def analysis_sys_list(stks, query, sys_proto, keys=["累计投入本金", "当
119
134
 
120
135
 
121
136
  def analysis_sys_list_multi(stks, query, sys_proto, keys=["累计投入本金", "当前总资产", "现金余额", "未平仓头寸净值", "赢利交易比例%", "赢利交易数", "亏损交易数"]):
137
+ if not keys:
138
+ for key in keys:
139
+ if not Performance.exist(key):
140
+ raise Exception(f'Invalid key: {key}')
141
+
122
142
  out = inner_analysis_sys_list(stks, query, sys_proto)
123
143
  if not keys:
124
144
  ret = out
Binary file
Binary file
Binary file
hikyuu/cpp/core38.pyd CHANGED
Binary file
hikyuu/cpp/hikyuu.dll CHANGED
Binary file
hikyuu/cpp/sqlite3.dll CHANGED
Binary file
hikyuu/data/common.py CHANGED
@@ -91,7 +91,7 @@ def get_stktype_list(quotations=None):
91
91
 
92
92
 
93
93
  @hku_catch(ret=[], trace=True)
94
- @timeout(120)
94
+ @timeout(30)
95
95
  def get_stk_code_name_list(market: str) -> list:
96
96
  """
97
97
  获取指定证券交易所股票代码与名称列表
@@ -128,7 +128,7 @@ def get_stk_code_name_list(market: str) -> list:
128
128
 
129
129
 
130
130
  @hku_catch(ret=[], trace=True)
131
- @timeout(120)
131
+ @timeout(60)
132
132
  def get_index_code_name_list() -> list:
133
133
  """
134
134
  获取所有股票指数代码名称列表
@@ -191,7 +191,7 @@ def get_new_holidays():
191
191
 
192
192
 
193
193
  @hku_catch(ret=[], trace=True)
194
- @timeout(120)
194
+ @timeout(60)
195
195
  def get_china_bond10_rate(start_date="19901219"):
196
196
  """获取中国国债收益率10年"""
197
197
  bond_zh_us_rate_df = ak.bond_zh_us_rate(start_date)
@@ -0,0 +1,5 @@
1
+ DELETE FROM `hku_base`.`stkweight`;
2
+ UPDATE `hku_base`.`coderuletype` SET `codepre`=51 WHERE `codepre`=510 AND `marketid`=1;
3
+ UPDATE `hku_base`.`coderuletype` SET `codepre`=50 WHERE `codepre`=500 AND `marketid`=1;
4
+ UPDATE `hku_base`.`coderuletype` SET `codepre`=20 WHERE `codepre`=200 AND `marketid`=2;
5
+ UPDATE `hku_base`.`version` set `version` = 22;
@@ -0,0 +1,4 @@
1
+ DELETE FROM `hku_base`.`stkweight`;
2
+ alter table `hku_base`.`stkweight` add `suogu` DOUBLE not null default 0;
3
+ ALTER TABLE `hku_base`.`stkweight` AUTO_INCREMENT = 1;
4
+ UPDATE `hku_base`.`version` set `version` = 23;
@@ -51,7 +51,7 @@ def pytdx_import_weight_to_mysql(pytdx_api, connect, market):
51
51
  cur.execute(
52
52
  "select id, stockid, date, countAsGift, countForSell, priceForSell, \
53
53
  bonus, countOfIncreasement, totalCount, \
54
- freeCount from `hku_base`.`stkweight` where stockid=%s \
54
+ freeCount, suogu from `hku_base`.`stkweight` where stockid=%s \
55
55
  order by date desc limit 1" % stockid
56
56
  )
57
57
  a = [x for x in cur.fetchall()]
@@ -79,10 +79,6 @@ def pytdx_import_weight_to_mysql(pytdx_api, connect, market):
79
79
  if xdxr['songzhuangu'] is not None:
80
80
  new_last_db_weight[3] = 10000 * xdxr['songzhuangu']
81
81
  update_last_db_weight = True
82
- if xdxr['suogu'] is not None:
83
- # etf 扩股
84
- new_last_db_weight[3] += 100000 * (xdxr['suogu']-1)
85
- update_last_db_weight = True
86
82
  if xdxr['peigu'] is not None:
87
83
  new_last_db_weight[4] = 10000 * xdxr['peigu']
88
84
  update_last_db_weight = True
@@ -100,26 +96,27 @@ def pytdx_import_weight_to_mysql(pytdx_api, connect, market):
100
96
  new_last_db_weight[9] = xdxr['panhouliutong']
101
97
  update_last_db_weight = True
102
98
  last_free_count = new_last_db_weight[9]
99
+ if xdxr['suogu'] is not None:
100
+ # etf 扩缩股
101
+ new_last_db_weight[10] = xdxr['suogu']
102
+ update_last_db_weight = True
103
103
  continue
104
104
  if date not in records:
105
- songzhuangu = 10000 * xdxr['songzhuangu'] if xdxr['songzhuangu'] is not None else 0
106
- songzhuangu += 100000 * (xdxr['suogu']-1) if xdxr['suogu'] is not None else 0
107
105
  records[date] = [
108
106
  stockid,
109
107
  date,
110
- songzhuangu, # countAsGift
108
+ 10000 * xdxr['songzhuangu'] if xdxr['songzhuangu'] is not None else 0, # countAsGift
111
109
  10000 * xdxr['peigu'] if xdxr['peigu'] is not None else 0, # countForSell
112
110
  1000 * xdxr['peigujia'] if xdxr['peigujia'] is not None else 0, # priceForSell
113
111
  1000 * xdxr['fenhong'] if xdxr['fenhong'] is not None else 0, # bonus
114
112
  0, # countOfIncreasement, pytdx 不区分送股和转增股,统一记在送股
115
113
  xdxr['houzongguben'] if xdxr['houzongguben'] is not None else last_total_count, # totalCount
116
- xdxr['panhouliutong'] if xdxr['panhouliutong'] is not None else last_free_count # freeCount
114
+ xdxr['panhouliutong'] if xdxr['panhouliutong'] is not None else last_free_count, # freeCount
115
+ xdxr["suogu"] if xdxr["suogu"] is not None else 0
117
116
  ]
118
117
  else:
119
118
  if xdxr['songzhuangu'] is not None:
120
119
  records[date][2] = 10000 * xdxr['songzhuangu']
121
- if xdxr['suogu'] is not None:
122
- records[date][2] += 100000 * (xdxr['suogu']-1)
123
120
  if xdxr['peigu'] is not None:
124
121
  records[date][3] = 10000 * xdxr['peigu']
125
122
  if xdxr['peigujia'] is not None:
@@ -130,6 +127,8 @@ def pytdx_import_weight_to_mysql(pytdx_api, connect, market):
130
127
  records[date][7] = xdxr['houzongguben']
131
128
  if xdxr['panhouliutong'] is not None:
132
129
  records[date][8] = xdxr['panhouliutong']
130
+ if xdxr['suogu'] is not None:
131
+ records[date][9] = xdxr['suogu']
133
132
  if xdxr['houzongguben'] is not None:
134
133
  last_total_count = xdxr['houzongguben']
135
134
  if xdxr['panhouliutong'] is not None:
@@ -144,8 +143,8 @@ def pytdx_import_weight_to_mysql(pytdx_api, connect, market):
144
143
  x = new_last_db_weight
145
144
  cur.execute(
146
145
  "UPDATE `hku_base`.`stkweight` SET countAsGift=%s, countForSell=%s, priceForSell=%s, \
147
- bonus=%s, totalCount=%s, freeCount=%s \
148
- where id=%s" % (x[3], x[4], x[5], x[6], x[8], x[9], x[0])
146
+ bonus=%s, totalCount=%s, freeCount=%s, suogu=%s \
147
+ where id=%s" % (x[3], x[4], x[5], x[6], x[8], x[9], x[10], x[0])
149
148
  )
150
149
  connect.commit()
151
150
  cur.close()
@@ -154,8 +153,8 @@ def pytdx_import_weight_to_mysql(pytdx_api, connect, market):
154
153
  cur = connect.cursor()
155
154
  cur.executemany(
156
155
  "INSERT INTO `hku_base`.`stkweight` (stockid, date, countAsGift, \
157
- countForSell, priceForSell, bonus, countOfIncreasement, totalCount, freeCount) \
158
- VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)", [x for x in records.values()]
156
+ countForSell, priceForSell, bonus, countOfIncreasement, totalCount, freeCount, suogu) \
157
+ VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", [x for x in records.values()]
159
158
  )
160
159
  connect.commit()
161
160
  cur.close()
@@ -48,7 +48,7 @@ def pytdx_import_weight_to_sqlite(pytdx_api, connect, market):
48
48
  a = cur.execute(
49
49
  "select id, stockid, date, countAsGift, countForSell, priceForSell, \
50
50
  bonus, countOfIncreasement, totalCount, \
51
- freeCount from stkweight where stockid=%s \
51
+ freeCount, suogu from stkweight where stockid=%s \
52
52
  order by date desc limit 1" % stockid
53
53
  )
54
54
  a = [x for x in a]
@@ -76,10 +76,6 @@ def pytdx_import_weight_to_sqlite(pytdx_api, connect, market):
76
76
  if xdxr['songzhuangu'] is not None:
77
77
  new_last_db_weight[3] = int(10000 * xdxr['songzhuangu'])
78
78
  update_last_db_weight = True
79
- if xdxr['suogu'] is not None:
80
- # etf 扩股
81
- new_last_db_weight[3] += int(100000 * (xdxr['suogu']-1))
82
- update_last_db_weight = True
83
79
  if xdxr['peigu'] is not None:
84
80
  new_last_db_weight[4] = int(10000 * xdxr['peigu'])
85
81
  update_last_db_weight = True
@@ -97,14 +93,16 @@ def pytdx_import_weight_to_sqlite(pytdx_api, connect, market):
97
93
  new_last_db_weight[9] = round(xdxr['panhouliutong'])
98
94
  update_last_db_weight = True
99
95
  last_free_count = new_last_db_weight[9]
96
+ if xdxr['suogu'] is not None:
97
+ # etf 扩股
98
+ new_last_db_weight[10] = xdxr['suogu']
99
+ update_last_db_weight = True
100
100
  continue
101
101
  if date not in records:
102
- songzhuangu = int(10000 * xdxr['songzhuangu']) if xdxr['songzhuangu'] is not None else 0
103
- songzhuangu += int(100000 * (xdxr['suogu']-1)) if xdxr['suogu'] is not None else 0
104
102
  records[date] = [
105
103
  stockid,
106
104
  date,
107
- songzhuangu, # countForGift
105
+ int(10000 * xdxr['songzhuangu']) if xdxr['songzhuangu'] is not None else 0, # countForGift
108
106
  int(10000 * xdxr['peigu']) if xdxr['peigu'] is not None else 0, # countForSell
109
107
  int(1000 * xdxr['peigujia']) if xdxr['peigujia'] is not None else 0, # priceForSell
110
108
  int(1000 * xdxr['fenhong']) if xdxr['fenhong'] is not None else 0, # bonus
@@ -112,13 +110,12 @@ def pytdx_import_weight_to_sqlite(pytdx_api, connect, market):
112
110
  round(xdxr['houzongguben'])
113
111
  if xdxr['houzongguben'] is not None else last_total_count, # totalCount
114
112
  round(xdxr['panhouliutong'])
115
- if xdxr['panhouliutong'] is not None else last_free_count # freeCount
113
+ if xdxr['panhouliutong'] is not None else last_free_count, # freeCount
114
+ xdxr["suogu"] if xdxr["suogu"] is not None else 0
116
115
  ]
117
116
  else:
118
117
  if xdxr['songzhuangu'] is not None:
119
118
  records[date][2] = int(10000 * xdxr['songzhuangu'])
120
- if xdxr['suogu'] is not None:
121
- records[date][2] += int(100000 * (xdxr['suogu']-1))
122
119
  if xdxr['peigu'] is not None:
123
120
  records[date][3] = int(10000 * xdxr['peigu'])
124
121
  if xdxr['peigujia'] is not None:
@@ -129,6 +126,8 @@ def pytdx_import_weight_to_sqlite(pytdx_api, connect, market):
129
126
  records[date][7] = round(xdxr['houzongguben'])
130
127
  if xdxr['panhouliutong'] is not None:
131
128
  records[date][8] = round(xdxr['panhouliutong'])
129
+ if xdxr['suogu'] is not None:
130
+ records[date][9] = xdxr['suogu']
132
131
  if xdxr['houzongguben'] is not None:
133
132
  last_total_count = round(xdxr['houzongguben'])
134
133
  if xdxr['panhouliutong'] is not None:
@@ -143,8 +142,8 @@ def pytdx_import_weight_to_sqlite(pytdx_api, connect, market):
143
142
  x = new_last_db_weight
144
143
  cur.execute(
145
144
  "UPDATE StkWeight SET countAsGift=%s, countForSell=%s, priceForSell=%s, \
146
- bonus=%s, totalCount=%s, freeCount=%s \
147
- where id=%s" % (x[3], x[4], x[5], x[6], x[8], x[9], x[0])
145
+ bonus=%s, totalCount=%s, freeCount=%s, suogu=%s \
146
+ where id=%s" % (x[3], x[4], x[5], x[6], x[8], x[9], x[10], x[0])
148
147
  )
149
148
  connect.commit()
150
149
  cur.close()
@@ -153,8 +152,8 @@ def pytdx_import_weight_to_sqlite(pytdx_api, connect, market):
153
152
  cur = connect.cursor()
154
153
  cur.executemany(
155
154
  "INSERT INTO StkWeight(stockid, date, countAsGift, \
156
- countForSell, priceForSell, bonus, countOfIncreasement, totalCount, freeCount) \
157
- VALUES (?,?,?,?,?,?,?,?,?)", [x for x in records.values()]
155
+ countForSell, priceForSell, bonus, countOfIncreasement, totalCount, freeCount, suogu) \
156
+ VALUES (?,?,?,?,?,?,?,?,?,?)", [x for x in records.values()]
158
157
  )
159
158
  connect.commit()
160
159
  cur.close()
@@ -0,0 +1,7 @@
1
+ BEGIN TRANSACTION;
2
+ DELETE FROM `stkWeight`;
3
+ UPDATE `coderuletype` SET `codepre`=51 WHERE `codepre`=510 AND `marketid`=1;
4
+ UPDATE `coderuletype` SET `codepre`=50 WHERE `codepre`=500 AND `marketid`=1;
5
+ UPDATE `coderuletype` SET `codepre`=20 WHERE `codepre`=200 AND `marketid`=2;
6
+ UPDATE `version` set `version` = 23;
7
+ COMMIT;
@@ -0,0 +1,22 @@
1
+ BEGIN TRANSACTION;
2
+ DROP TABLE `stkWeight`;
3
+ CREATE TABLE "stkWeight" (
4
+ id INTEGER NOT NULL,
5
+ stockid INTEGER,
6
+ date INTEGER,
7
+ "countAsGift" INTEGER,
8
+ "countForSell" INTEGER,
9
+ "priceForSell" INTEGER,
10
+ bonus INTEGER,
11
+ "countOfIncreasement" INTEGER,
12
+ "totalCount" INTEGER,
13
+ "freeCount" INTEGER,
14
+ "suogu" NUMBER,
15
+ PRIMARY KEY (id AUTOINCREMENT),
16
+ FOREIGN KEY(stockid) REFERENCES "Stock" (stockid)
17
+ );
18
+ CREATE INDEX "ix_stkWeight_stockid" ON "stkWeight" (stockid);
19
+ CREATE INDEX "ix_stkWeight_date" ON "stkWeight" (date);
20
+ CREATE INDEX "ix_stkWeight" ON "stkWeight" (stockid, date);
21
+ UPDATE `version` set `version` = 24;
22
+ COMMIT;
@@ -73,7 +73,7 @@ def request_data(api, stklist, parse_one_result):
73
73
 
74
74
 
75
75
  @hku_catch(ret=([], []))
76
- def get_spot(stocklist, ip, port, batch_func=None):
76
+ def inner_get_spot(stocklist, ip, port, batch_func=None):
77
77
  api = TdxHq_API()
78
78
  hku_check(api.connect(ip, port), 'Failed connect tdx ({}:{})!'.format(ip, port))
79
79
 
@@ -107,7 +107,7 @@ def get_spot(stocklist, ip, port, batch_func=None):
107
107
 
108
108
 
109
109
  @spend_time
110
- def get_spot2(stocklist, ip, port, batch_func=None):
110
+ def get_spot(stocklist, ip, port, batch_func=None):
111
111
  hosts = search_best_tdx()
112
112
  hosts_cnt = len(hosts)
113
113
  num = len(stocklist) // hosts_cnt
@@ -123,7 +123,7 @@ def get_spot2(stocklist, ip, port, batch_func=None):
123
123
  break
124
124
 
125
125
  def do_inner(param):
126
- ret = get_spot(param[0], param[1], param[2], param[3])
126
+ ret = inner_get_spot(param[0], param[1], param[2], param[3])
127
127
  return ret
128
128
 
129
129
  with futures.ThreadPoolExecutor() as executor:
hikyuu/gui/HikyuuTDX.py CHANGED
@@ -267,8 +267,6 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
267
267
 
268
268
  current_dir = os.path.dirname(__file__)
269
269
  self.setWindowIcon(QIcon("{}/hikyuu.ico".format(current_dir)))
270
- # self.setFixedSize(self.width(), self.height())
271
- self.import_status_label.setText('')
272
270
  self.import_detail_textEdit.clear()
273
271
  self.reset_progress_bar()
274
272
  self.day_start_dateEdit.setMinimumDate(datetime.date(1990, 12, 19))
@@ -703,6 +701,9 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
703
701
  self.start_import_pushButton.setEnabled(False)
704
702
  self.reset_progress_bar()
705
703
 
704
+ if config.getboolean('weight', 'enable', fallback=False):
705
+ self.hdf5_weight_label.setText("正在导入")
706
+
706
707
  self.import_status_label.setText("正在启动任务....")
707
708
  QApplication.processEvents()
708
709
 
@@ -115,6 +115,13 @@ class ImportHistoryFinanceTask:
115
115
  old_md5 = hashlib.md5(f.read()).hexdigest()
116
116
  if old_md5 != item['hash']:
117
117
  self.download_file(item)
118
+ else:
119
+ # 不管是否有变化,都导入一次,以便切换引擎时可以导入
120
+ shutil.unpack_archive(dest_file, extract_dir=self.dest_dir)
121
+ filename = item['filename']
122
+ filename = f'{self.dest_dir}/{filename[0:-4]}.dat'
123
+ self.import_to_db(filename)
124
+ hku_info(f"Import finance file: {filename}")
118
125
  count += 1
119
126
  self.queue.put([self.task_name, None, None, int(100 * count / self.total_count), self.total_count])
120
127
  except Exception as e:
@@ -91,8 +91,8 @@ class ImportWeightToSqliteTask:
91
91
  hku_check(api.connect(self.host, self.port), "failed connect pytdx {}:{}!", self.host, self.port)
92
92
 
93
93
  if self.cmd == 'weight':
94
- count = pytdx_import_weight(api, connect, self.market)
95
- self.logger.info("导入 {} 权息记录数: {}".format(self.market, count))
94
+ total_count = pytdx_import_weight(api, connect, self.market)
95
+ self.logger.info("导入 {} 权息记录数: {}".format(self.market, total_count))
96
96
  self.queue.put([self.msg_name, '导入权息数据完毕!', 0, 0, f'{self.market} {total_count}'])
97
97
  elif self.cmd == 'finance':
98
98
  self.queue.put([self.msg_name, f'下载通达信当前财务信息({self.market})...', 0, 0, 0])
@@ -653,7 +653,7 @@ class Ui_MainWindow(object):
653
653
  "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">导入深证分时数据:</p>\n"
654
654
  "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">导入权息数据数:</p>\n"
655
655
  "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">导入完毕!</p></body></html>"))
656
- self.import_status_label.setText(_translate("MainWindow", "import_status_label"))
656
+ self.import_status_label.setText(_translate("MainWindow", "请勿盘中导入!"))
657
657
  self.sched_import_pushButton.setText(_translate("MainWindow", "启动定时导入"))
658
658
  self.label_40.setText(_translate("MainWindow", "导入执行时间:"))
659
659
  self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "执行导入"))
hikyuu/gui/start_qmt.py CHANGED
@@ -2,15 +2,15 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
 
5
- from hikyuu.fetcher.stock.zh_stock_a_qmt import parse_one_result_qmt
5
+ from hikyuu.fetcher.stock.zh_stock_a_qmt import parse_one_result_qmt, get_spot
6
6
  from hikyuu.gui.spot_server import release_nng_senders, start_send_spot, end_send_spot, send_spot
7
7
 
8
8
 
9
9
  def callback(datas):
10
10
  records = []
11
11
  for stock_code, data in datas.items():
12
- # print(stock_code, data)
13
12
  records.append(parse_one_result_qmt(stock_code, data))
13
+ # print(len(records))
14
14
 
15
15
  if records:
16
16
  start_send_spot()
@@ -19,18 +19,104 @@ def callback(datas):
19
19
 
20
20
 
21
21
  if __name__ == "__main__":
22
- from hikyuu.interactive import *
23
- from xtquant import xtdata
22
+ import os
23
+ import configparser
24
+
25
+ from hikyuu.data.hku_config_template import generate_default_config
26
+ from hikyuu import *
27
+
28
+ config_file = os.path.expanduser('~') + "/.hikyuu/hikyuu.ini"
29
+ if not os.path.exists(config_file):
30
+ # 创建默认配置
31
+ hku_info("创建默认配置文件")
32
+ generate_default_config()
33
+
34
+ ini = configparser.ConfigParser()
35
+ ini.read(config_file, encoding='utf-8')
36
+ hku_param = Parameter()
37
+ hku_param["tmpdir"] = ini.get('hikyuu', 'tmpdir')
38
+ hku_param["datadir"] = ini.get('hikyuu', 'datadir')
39
+ if ini.has_option('hikyuu', 'quotation_server'):
40
+ hku_param["quotation_server"] = ini['hikyuu']['quotation_server']
41
+
42
+ # 不加载历史财务信息及权息数据
43
+ hku_param["load_history_finance"] = False
44
+ hku_param["load_stock_weight"] = False
45
+
46
+ base_param = Parameter()
47
+ base_info_config = ini.options('baseinfo')
48
+ for p in base_info_config:
49
+ base_param[p] = ini.get('baseinfo', p)
50
+
51
+ block_param = Parameter()
52
+ block_config = ini.options('block')
53
+ for p in block_config:
54
+ block_param[p] = ini.get('block', p)
55
+
56
+ # 不使用配置文件中的预加载参数
57
+ preload_param = Parameter()
58
+ if p in Query.get_all_ktype():
59
+ preload_param[p] = False
24
60
 
25
- code_list = [f'{s.code}.{s.market}' for s in sm if s.valid]
26
- # code_list = ['000001.SZ']
61
+ kdata_param = Parameter()
62
+ kdata_config = ini.options('kdata')
63
+ for p in kdata_config:
64
+ if p == "convert":
65
+ kdata_param[p] = ini.getboolean('kdata', p)
66
+ continue
67
+ kdata_param[p] = ini.get('kdata', p)
27
68
 
69
+ context = StrategyContext(["all"])
70
+ context.ktype_list = ["day"]
71
+
72
+ sm.init(base_param, block_param, kdata_param, preload_param, hku_param, context)
73
+
74
+ # 后续希望每次先主动获取一次全部的tick, 这里需要等待所有数据加载完毕,以便保证全部证券收到第一次tick通知
75
+ hku_info("waiting all data loaded ...")
76
+ while not sm.data_ready:
77
+ import time
78
+ time.sleep(100)
79
+
80
+ stk_list = [s for s in sm if s.valid and s.type in (
81
+ constant.STOCKTYPE_A, constant.STOCKTYPE_INDEX, constant.STOCKTYPE_ETF,
82
+ constant.STOCKTYPE_GEM, constant.STOCKTYPE_START, constant.STOCKTYPE_A_BJ)]
83
+
84
+ hku_info("start xtquant")
85
+ code_list = [f'{s.code}.{s.market}' for s in stk_list]
86
+ from xtquant import xtdata
28
87
  xtdata.subscribe_whole_quote(code_list, callback)
29
88
 
30
- try:
31
- xtdata.run()
32
- except Exception as e:
33
- hku_error(e)
34
- finally:
35
- # 退出释放资源
36
- release_nng_senders()
89
+ # 每日 9:30 时,主动读取行情一次,以便 hikyuu 生成当日首个分钟线
90
+ while True:
91
+ try:
92
+ today = Datetime.today()
93
+ if today.day_of_week() not in (0, 6) and not sm.is_holiday(today):
94
+ hku_info("get full tick ...")
95
+ start_send_spot()
96
+ records = get_spot(stk_list, None, None, send_spot)
97
+ end_send_spot()
98
+ now = Datetime.now()
99
+ today_open = today + TimeDelta(0, 9, 30)
100
+ if now < today_open:
101
+ delta = today_open - Datetime.now()
102
+ else:
103
+ delta = today_open + Days(1) - Datetime.now()
104
+ hku_info(f"start timer: {delta}s")
105
+ time.sleep(delta.total_seconds())
106
+ except KeyboardInterrupt:
107
+ print("Ctrl-C 终止")
108
+ break
109
+ except Exception as e:
110
+ hku_error(e)
111
+ time.sleep(10)
112
+
113
+ release_nng_senders()
114
+
115
+ # try:
116
+ # xtdata.run()
117
+ # except Exception as e:
118
+ # hku_error(e)
119
+ # finally:
120
+ # # 退出释放资源
121
+ # release_nng_senders()
122
+ # exit(0)
@@ -20,13 +20,13 @@ namespace hku {
20
20
  class HKU_API StockWeight {
21
21
  public:
22
22
  /** 默认构造函数,返回Null<StockWeight>() */
23
- StockWeight();
23
+ StockWeight() = default;
24
24
 
25
25
  explicit StockWeight(const Datetime& datetime);
26
26
 
27
27
  StockWeight(const Datetime& datetime, price_t countAsGift, price_t countForSell,
28
28
  price_t priceForSell, price_t bonus, price_t increasement, price_t totalCount,
29
- price_t freeCount);
29
+ price_t freeCount, price_t suogu);
30
30
 
31
31
  /** 权息日期 */
32
32
  Datetime datetime() const {
@@ -68,15 +68,21 @@ public:
68
68
  return m_freeCount;
69
69
  }
70
70
 
71
+ /** 扩缩股比例 */
72
+ price_t suogu() const {
73
+ return m_suogu;
74
+ }
75
+
71
76
  private:
72
- Datetime m_datetime; // 权息日期
73
- price_t m_countAsGift; // 每10股送X股
74
- price_t m_countForSell; // 每10股配X股
75
- price_t m_priceForSell; // 配股价
76
- price_t m_bonus; // 每10股红利
77
- price_t m_increasement; // 每10股转增X股
78
- price_t m_totalCount; // 总股本(万股)
79
- price_t m_freeCount; // 流通股(万股)
77
+ Datetime m_datetime; // 权息日期
78
+ price_t m_countAsGift{0.}; // 每10股送X股
79
+ price_t m_countForSell{0.}; // 每10股配X股
80
+ price_t m_priceForSell{0.}; // 配股价
81
+ price_t m_bonus{0.}; // 每10股红利
82
+ price_t m_increasement{0.}; // 每10股转增X股
83
+ price_t m_totalCount{0.}; // 总股本(万股)
84
+ price_t m_freeCount{0.}; // 流通股(万股)
85
+ price_t m_suogu{0.}; // 扩缩股比例
80
86
  };
81
87
 
82
88
  /** @ingroup StockManage */
@@ -13,20 +13,20 @@
13
13
 
14
14
  namespace hku {
15
15
 
16
- struct HKU_API AnalysisSystemWithBlockOut {
16
+ struct HKU_API AnalysisSystemOutput {
17
17
  string market_code; ///< 证券代码
18
18
  string name; ///< 证券名称
19
19
  PriceList values; ///< 统计各项指标值
20
20
 
21
- AnalysisSystemWithBlockOut() = default;
22
- AnalysisSystemWithBlockOut(const AnalysisSystemWithBlockOut& other) = default;
23
- AnalysisSystemWithBlockOut(AnalysisSystemWithBlockOut&& rv)
21
+ AnalysisSystemOutput() = default;
22
+ AnalysisSystemOutput(const AnalysisSystemOutput& other) = default;
23
+ AnalysisSystemOutput(AnalysisSystemOutput&& rv)
24
24
  : market_code(std::move(rv.market_code)),
25
25
  name(std::move(rv.name)),
26
26
  values(std::move(rv.values)) {}
27
27
 
28
- AnalysisSystemWithBlockOut& operator=(const AnalysisSystemWithBlockOut&) = default;
29
- AnalysisSystemWithBlockOut& operator=(AnalysisSystemWithBlockOut&& rv) {
28
+ AnalysisSystemOutput& operator=(const AnalysisSystemOutput&) = default;
29
+ AnalysisSystemOutput& operator=(AnalysisSystemOutput&& rv) {
30
30
  HKU_IF_RETURN(this == &rv, *this);
31
31
  market_code = std::move(rv.market_code);
32
32
  name = std::move(rv.name);
@@ -35,12 +35,42 @@ struct HKU_API AnalysisSystemWithBlockOut {
35
35
  }
36
36
  };
37
37
 
38
- vector<AnalysisSystemWithBlockOut> HKU_API analysisSystemList(const SystemList& sys_list,
39
- const StockList& stk_list,
40
- const KQuery& query);
38
+ /**
39
+ * 统计所有指定系统策略, 系统列表中的每一个系统都应该是独立的系统实例
40
+ * @note 系统实例列表和证券列表是一一对应,不是两两组合
41
+ * @param sys_list 系统策略实例列表
42
+ * @param stk_list 证券列表,须与系统策略列表一一对应
43
+ * @param query 查询条件
44
+ * @return vector<AnalysisSystemOutput>
45
+ */
46
+ vector<AnalysisSystemOutput> HKU_API analysisSystemList(const SystemList& sys_list,
47
+ const StockList& stk_list,
48
+ const KQuery& query);
49
+
50
+ /**
51
+ * 以指定的 stock 统计执行所有的系统策略
52
+ * @param sys_list 系统策略思路列表,每一个都应是单独的实例
53
+ * @param stk 指定证券
54
+ * @param query 查询条件
55
+ * @return vector<AnalysisSystemOutput>
56
+ */
57
+ vector<AnalysisSystemOutput> HKU_API analysisSystemList(const SystemList& sys_list,
58
+ const Stock& stk, const KQuery& query);
41
59
 
42
- vector<AnalysisSystemWithBlockOut> HKU_API analysisSystemList(const StockList& stk_list,
43
- const KQuery& query,
44
- const SystemPtr& pro_sys);
60
+ /**
61
+ * 以指定的 stock 统计执行所有的系统策略,并按指定的统计项返回统计项最高或最低的系统实例及其统计值
62
+ * @param sys_list 系统策略思路列表,每一个都应是单独的实例
63
+ * @param stk 指定证券
64
+ * @param query 查询条件
65
+ * @param sort_key Performance 中的统计项名称,按该统计项返回
66
+ * @param sort_mode 0 为取统计最高值的系统,其他值为取统计最低值的系统
67
+ * @return std::pair<double, SYSPtr>
68
+ */
69
+ std::pair<double, SYSPtr> HKU_API findOptimalSystem(const SystemList& sys_list, const Stock& stk,
70
+ const KQuery& query, const string& sort_key,
71
+ int sort_mode = 0);
45
72
 
73
+ std::pair<double, SYSPtr> HKU_API findOptimalSystemMulti(const SystemList& sys_list,
74
+ const Stock& stk, const KQuery& query,
75
+ const string& sort_key, int sort_mode = 0);
46
76
  } // namespace hku