hikyuu 2.6.8.4__py3-none-win_amd64.whl → 2.6.9__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 (183) hide show
  1. hikyuu/__init__.py +5 -12
  2. hikyuu/__init__.pyi +33 -8
  3. hikyuu/analysis/__init__.pyi +26 -0
  4. hikyuu/analysis/analysis.pyi +27 -1
  5. hikyuu/core.py +2 -0
  6. hikyuu/core.pyi +28 -2
  7. hikyuu/cpp/arrow.dll +0 -0
  8. hikyuu/cpp/boost_date_time-mt.dll +0 -0
  9. hikyuu/cpp/boost_serialization-mt.dll +0 -0
  10. hikyuu/cpp/boost_system-mt.dll +0 -0
  11. hikyuu/cpp/boost_wserialization-mt.dll +0 -0
  12. hikyuu/cpp/core310.pyd +0 -0
  13. hikyuu/cpp/core310.pyi +446 -13
  14. hikyuu/cpp/core311.pyd +0 -0
  15. hikyuu/cpp/core311.pyi +446 -13
  16. hikyuu/cpp/core312.pyd +0 -0
  17. hikyuu/cpp/core312.pyi +446 -13
  18. hikyuu/cpp/core313.pyd +0 -0
  19. hikyuu/cpp/core313.pyi +446 -13
  20. hikyuu/cpp/core39.pyd +0 -0
  21. hikyuu/cpp/core39.pyi +446 -13
  22. hikyuu/cpp/hikyuu.dll +0 -0
  23. hikyuu/cpp/hikyuu.lib +0 -0
  24. hikyuu/cpp/i18n/zh_CN/hikyuu.mo +0 -0
  25. hikyuu/cpp/msvcp140-a118642f3ae8774fb9dc223e15c4a52e.dll +0 -0
  26. hikyuu/cpp/parquet.dll +0 -0
  27. hikyuu/cpp/sqlite3.dll +0 -0
  28. hikyuu/data/clickhouse_upgrade/createdb.sql +105 -105
  29. hikyuu/data/common.py +3 -3
  30. hikyuu/data/common_clickhouse.py +1 -1
  31. hikyuu/data/download_block.py +318 -0
  32. hikyuu/data/em_block_to_clickhouse.py +26 -74
  33. hikyuu/data/em_block_to_mysql.py +25 -75
  34. hikyuu/data/em_block_to_sqlite.py +26 -78
  35. hikyuu/data/hku_config_template.py +3 -3
  36. hikyuu/data/pytdx_to_clickhouse.py +15 -11
  37. hikyuu/data/pytdx_to_h5.py +6 -2
  38. hikyuu/data/pytdx_to_mysql.py +5 -1
  39. hikyuu/data/pytdx_weight_to_clickhouse.py +1 -1
  40. hikyuu/data/pytdx_weight_to_mysql.py +1 -1
  41. hikyuu/data/pytdx_weight_to_sqlite.py +1 -1
  42. hikyuu/data/zh_bond10_to_clickhouse.py +1 -1
  43. hikyuu/draw/drawplot/__init__.pyi +1 -1
  44. hikyuu/draw/drawplot/bokeh_draw.pyi +31 -6
  45. hikyuu/draw/drawplot/echarts_draw.pyi +31 -6
  46. hikyuu/draw/drawplot/matplotlib_draw.py +4 -74
  47. hikyuu/draw/drawplot/matplotlib_draw.pyi +31 -6
  48. hikyuu/examples/notebook/Demo/Demo1.ipynb +48 -33
  49. hikyuu/extend.pyi +29 -3
  50. hikyuu/fetcher/stock/zh_block_em.py +50 -18
  51. hikyuu/gui/HikyuuTDX.py +81 -30
  52. hikyuu/gui/data/CollectSpotThread.py +1 -1
  53. hikyuu/gui/data/EscapetimeThread.py +8 -14
  54. hikyuu/gui/data/ImportBlockInfoTask.py +3 -10
  55. hikyuu/gui/data/MainWindow.py +1168 -715
  56. hikyuu/gui/data/SchedImportThread.py +2 -2
  57. hikyuu/gui/data/UsePytdxImportToH5Thread.py +3 -3
  58. hikyuu/gui/data/UseQmtImportToH5Thread.py +2 -2
  59. hikyuu/gui/data/UseTdxImportToH5Thread.py +3 -3
  60. hikyuu/gui/data/tool.py +32 -25
  61. hikyuu/gui/dataserver.py +5 -3
  62. hikyuu/hub.pyi +6 -6
  63. hikyuu/include/hikyuu/DataType.h +4 -16
  64. hikyuu/include/hikyuu/KData.h +6 -3
  65. hikyuu/include/hikyuu/KDataPrivatedBufferImp.h +1 -1
  66. hikyuu/include/hikyuu/KDataSharedBufferImp.h +1 -1
  67. hikyuu/include/hikyuu/KQuery.h +2 -2
  68. hikyuu/include/hikyuu/Stock.h +3 -0
  69. hikyuu/include/hikyuu/StockManager.h +13 -3
  70. hikyuu/include/hikyuu/config.h +3 -0
  71. hikyuu/include/hikyuu/data_driver/BaseInfoDriver.h +8 -0
  72. hikyuu/include/hikyuu/data_driver/BlockInfoDriver.h +6 -0
  73. hikyuu/include/hikyuu/data_driver/KDataDriver.h +26 -1
  74. hikyuu/include/hikyuu/data_driver/base_info/mysql/MySQLBaseInfoDriver.h +1 -1
  75. hikyuu/include/hikyuu/data_driver/base_info/sqlite/SQLiteBaseInfoDriver.h +1 -1
  76. hikyuu/include/hikyuu/data_driver/block_info/mysql/MySQLBlockInfoDriver.h +2 -1
  77. hikyuu/include/hikyuu/data_driver/block_info/qianlong/QLBlockInfoDriver.h +2 -1
  78. hikyuu/include/hikyuu/data_driver/block_info/sqlite/SQLiteBlockInfoDriver.h +2 -1
  79. hikyuu/include/hikyuu/data_driver/kdata/DoNothingKDataDriver.h +1 -1
  80. hikyuu/include/hikyuu/data_driver/kdata/cvs/KDataTempCsvDriver.h +1 -1
  81. hikyuu/include/hikyuu/data_driver/kdata/hdf5/H5KDataDriver.h +1 -1
  82. hikyuu/include/hikyuu/data_driver/kdata/mysql/MySQLKDataDriver.h +1 -1
  83. hikyuu/include/hikyuu/data_driver/kdata/sqlite/SQLiteKDataDriver.h +1 -1
  84. hikyuu/include/hikyuu/data_driver/kdata/tdx/TdxKDataDriver.h +1 -1
  85. hikyuu/include/hikyuu/hikyuu.h +1 -1
  86. hikyuu/include/hikyuu/indicator/build_in.h +1 -0
  87. hikyuu/include/hikyuu/indicator/crt/CYCLE.h +4 -4
  88. hikyuu/include/hikyuu/indicator/crt/HSL.h +2 -2
  89. hikyuu/include/hikyuu/indicator/crt/QUANTILE_TRUNC.h +30 -0
  90. hikyuu/include/hikyuu/indicator/crt/TURNOVER.h +1 -0
  91. hikyuu/include/hikyuu/indicator/crt/ZSCORE.h +2 -2
  92. hikyuu/include/hikyuu/indicator/imp/IQuantileTrunc.h +25 -0
  93. hikyuu/include/hikyuu/misc.h +38 -0
  94. hikyuu/include/hikyuu/plugin/dataserver.h +2 -1
  95. hikyuu/include/hikyuu/plugin/extind.h +37 -0
  96. hikyuu/include/hikyuu/plugin/hkuextra.h +0 -18
  97. hikyuu/include/hikyuu/plugin/hkuviews.h +36 -0
  98. hikyuu/include/hikyuu/plugin/interface/DataServerPluginInterface.h +2 -2
  99. hikyuu/include/hikyuu/plugin/interface/ExtendIndicatorsPluginInterface.h +12 -0
  100. hikyuu/include/hikyuu/plugin/interface/HkuExtraPluginInterface.h +0 -14
  101. hikyuu/include/hikyuu/plugin/interface/HkuViewsPluginInterface.h +34 -0
  102. hikyuu/include/hikyuu/plugin/interface/plugins.h +8 -1
  103. hikyuu/include/hikyuu/python/pybind_utils.h +6 -1
  104. hikyuu/include/hikyuu/strategy/RunSystemInStrategy.h +3 -0
  105. hikyuu/include/hikyuu/trade_manage/Performance.h +4 -4
  106. hikyuu/include/hikyuu/trade_manage/TradeManagerBase.h +10 -1
  107. hikyuu/include/hikyuu/trade_sys/moneymanager/imp/FixedCapitalFundsMM.h +0 -4
  108. hikyuu/include/hikyuu/trade_sys/multifactor/MultiFactorBase.h +36 -3
  109. hikyuu/include/hikyuu/trade_sys/multifactor/NormalizeBase.h +125 -0
  110. hikyuu/include/hikyuu/trade_sys/multifactor/ScoresFilterBase.h +125 -0
  111. hikyuu/include/hikyuu/trade_sys/multifactor/build_in.h +3 -0
  112. hikyuu/include/hikyuu/trade_sys/multifactor/buildin_norm.h +36 -0
  113. hikyuu/include/hikyuu/trade_sys/multifactor/buildin_scfilter.h +51 -0
  114. hikyuu/include/hikyuu/trade_sys/multifactor/filter/GroupSCFilter.h +24 -0
  115. hikyuu/include/hikyuu/trade_sys/multifactor/filter/IgnoreLessOrEqualValueSCFilter.h +24 -0
  116. hikyuu/include/hikyuu/trade_sys/multifactor/filter/IgnoreNanSCFilter.h +24 -0
  117. hikyuu/include/hikyuu/trade_sys/multifactor/filter/MinAmountPercentSCFilter.h +25 -0
  118. hikyuu/include/hikyuu/trade_sys/multifactor/filter/PriceSCFilter.h +24 -0
  119. hikyuu/include/hikyuu/trade_sys/multifactor/filter/TopNSCFilter.h +24 -0
  120. hikyuu/include/hikyuu/trade_sys/multifactor/filter/__init__.py +1 -0
  121. hikyuu/include/hikyuu/trade_sys/multifactor/imp/EqualWeightMultiFactor.h +1 -1
  122. hikyuu/include/hikyuu/trade_sys/multifactor/imp/ICIRMultiFactor.h +1 -1
  123. hikyuu/include/hikyuu/trade_sys/multifactor/imp/ICMultiFactor.h +1 -1
  124. hikyuu/include/hikyuu/trade_sys/multifactor/imp/WeightMultiFactor.h +1 -1
  125. hikyuu/include/hikyuu/trade_sys/multifactor/normalize/NormMinMax.h +23 -0
  126. hikyuu/include/hikyuu/trade_sys/multifactor/normalize/NormQuantile.h +28 -0
  127. hikyuu/include/hikyuu/trade_sys/multifactor/normalize/NormQuantileUniform.h +28 -0
  128. hikyuu/include/hikyuu/trade_sys/multifactor/normalize/NormZScore.h +25 -0
  129. hikyuu/include/hikyuu/trade_sys/multifactor/normalize/__init__.py +1 -0
  130. hikyuu/include/hikyuu/trade_sys/multifactor/normalize/quantile_trunc.h +16 -0
  131. hikyuu/include/hikyuu/trade_sys/portfolio/Portfolio.h +7 -0
  132. hikyuu/include/hikyuu/trade_sys/portfolio/imp/SimplePortfolio.h +7 -0
  133. hikyuu/include/hikyuu/trade_sys/portfolio/imp/WithoutAFPortfolio.h +7 -0
  134. hikyuu/include/hikyuu/trade_sys/selector/SelectorBase.h +49 -0
  135. hikyuu/include/hikyuu/trade_sys/selector/build_in.h +1 -0
  136. hikyuu/include/hikyuu/trade_sys/selector/crt/SE_MultiFactor2.h +40 -0
  137. hikyuu/include/hikyuu/trade_sys/selector/imp/MultiFactorSelector.h +0 -3
  138. hikyuu/include/hikyuu/trade_sys/selector/imp/MultiFactorSelector2.h +49 -0
  139. hikyuu/include/hikyuu/trade_sys/selector/imp/logic/OperatorSelector.h +1 -1
  140. hikyuu/include/hikyuu/trade_sys/selector/imp/logic/OperatorValueSelector.h +1 -1
  141. hikyuu/include/hikyuu/trade_sys/signal/imp/BandSignal2.h +0 -4
  142. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/AddValueSignal.h +2 -2
  143. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/DivValueSignal.h +2 -2
  144. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/MulValueSignal.h +2 -2
  145. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/OperatorSignal.h +1 -1
  146. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/OperatorValueSignal.h +4 -4
  147. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/SubValueSignal.h +2 -2
  148. hikyuu/include/hikyuu/trade_sys/system/System.h +14 -1
  149. hikyuu/include/hikyuu/utilities/SpendTimer.h +17 -7
  150. hikyuu/include/hikyuu/utilities/arithmetic.h +55 -0
  151. hikyuu/include/hikyuu/utilities/db_connect/mysql/MySQLConnect.h +1 -1
  152. hikyuu/include/hikyuu/utilities/db_connect/mysql/MySQLStatement.h +1 -1
  153. hikyuu/include/hikyuu/utilities/db_connect/sqlite/SQLiteConnect.h +1 -1
  154. hikyuu/include/hikyuu/utilities/db_connect/sqlite/SQLiteStatement.h +1 -1
  155. hikyuu/include/hikyuu/utilities/plugin/PluginLoader.h +4 -1
  156. hikyuu/include/hikyuu/version.h +4 -4
  157. hikyuu/plugin/backtest.dll +0 -0
  158. hikyuu/plugin/clickhousedriver.dll +0 -0
  159. hikyuu/plugin/dataserver.dll +0 -0
  160. hikyuu/plugin/device.dll +0 -0
  161. hikyuu/plugin/extind.dll +0 -0
  162. hikyuu/plugin/hkuextra.dll +0 -0
  163. hikyuu/plugin/hkuviews.dll +0 -0
  164. hikyuu/plugin/import2hdf5.dll +0 -0
  165. hikyuu/plugin/tmreport.dll +0 -0
  166. hikyuu/trade_manage/__init__.pyi +30 -5
  167. hikyuu/trade_manage/trade.pyi +30 -5
  168. hikyuu/util/__init__.pyi +1 -1
  169. hikyuu/util/singleton.pyi +1 -1
  170. {hikyuu-2.6.8.4.dist-info → hikyuu-2.6.9.dist-info}/METADATA +13 -14
  171. {hikyuu-2.6.8.4.dist-info → hikyuu-2.6.9.dist-info}/RECORD +174 -153
  172. {hikyuu-2.6.8.4.dist-info → hikyuu-2.6.9.dist-info}/top_level.txt +2 -1
  173. hikyuu/data_driver/__init__.py +0 -49
  174. hikyuu/data_driver/jqdata_data_driver.py +0 -277
  175. hikyuu/data_driver/pytdx_data_driver.py +0 -292
  176. hikyuu/fetcher/stock/zh_stock_a_huatai.py +0 -51
  177. hikyuu/fetcher/stock/zh_stock_a_pytdx.py +0 -129
  178. hikyuu/gui/data/CollectToMemThread.py +0 -123
  179. hikyuu/gui/data/CollectToMySQLThread.py +0 -178
  180. hikyuu/gui/start_huatai_insight.py +0 -510
  181. hikyuu/tools/update_block_info.py +0 -168
  182. {hikyuu-2.6.8.4.dist-info → hikyuu-2.6.9.dist-info}/WHEEL +0 -0
  183. {hikyuu-2.6.8.4.dist-info → hikyuu-2.6.9.dist-info}/entry_points.txt +0 -0
hikyuu/cpp/hikyuu.dll CHANGED
Binary file
hikyuu/cpp/hikyuu.lib CHANGED
Binary file
Binary file
hikyuu/cpp/parquet.dll ADDED
Binary file
hikyuu/cpp/sqlite3.dll CHANGED
Binary file
@@ -880,15 +880,15 @@ INSERT INTO `hku_base`.`holiday` (`date`) VALUES
880
880
 
881
881
  CREATE DATABASE IF NOT EXISTS hku_data;
882
882
  CREATE table if not exists hku_data.day_k (
883
- `market` String,
884
- `code` String,
883
+ `market` FixedString(2),
884
+ `code` FixedString(6),
885
885
  `date` DateTime,
886
- `open` DOUBLE,
887
- `high` DOUBLE,
888
- `low` DOUBLE,
889
- `close` DOUBLE,
890
- `amount` DOUBLE,
891
- `volume` DOUBLE
886
+ `open` UInt32,
887
+ `high` UInt32,
888
+ `low` UInt32,
889
+ `close` UInt32,
890
+ `amount` UInt64,
891
+ `volume` UInt64
892
892
  )
893
893
  ENGINE = MergeTree()
894
894
  PARTITION BY market
@@ -896,188 +896,188 @@ PRIMARY KEY (market, code, date)
896
896
  ORDER BY (market, code, date)
897
897
  SETTINGS index_granularity = 2048;
898
898
  CREATE table if not exists hku_data.week_k (
899
- `market` String,
900
- `code` String,
899
+ `market` FixedString(2),
900
+ `code` FixedString(6),
901
901
  `date` DateTime,
902
- `open` DOUBLE,
903
- `high` DOUBLE,
904
- `low` DOUBLE,
905
- `close` DOUBLE,
906
- `amount` DOUBLE,
907
- `volume` DOUBLE
902
+ `open` UInt32,
903
+ `high` UInt32,
904
+ `low` UInt32,
905
+ `close` UInt32,
906
+ `amount` UInt64,
907
+ `volume` UInt64
908
908
  )
909
909
  ENGINE = MergeTree()
910
910
  PARTITION BY market
911
911
  PRIMARY KEY (market, code, date)
912
912
  ORDER BY (market, code, date);
913
913
  CREATE table if not exists hku_data.month_k (
914
- `market` String,
915
- `code` String,
914
+ `market` FixedString(2),
915
+ `code` FixedString(6),
916
916
  `date` DateTime,
917
- `open` DOUBLE,
918
- `high` DOUBLE,
919
- `low` DOUBLE,
920
- `close` DOUBLE,
921
- `amount` DOUBLE,
922
- `volume` DOUBLE
917
+ `open` UInt32,
918
+ `high` UInt32,
919
+ `low` UInt32,
920
+ `close` UInt32,
921
+ `amount` UInt64,
922
+ `volume` UInt64
923
923
  )
924
924
  ENGINE = MergeTree()
925
925
  PARTITION BY market
926
926
  PRIMARY KEY (market, code, date)
927
927
  ORDER BY (market, code, date);
928
928
  CREATE table if not exists hku_data.quarter_k (
929
- `market` String,
930
- `code` String,
929
+ `market` FixedString(2),
930
+ `code` FixedString(6),
931
931
  `date` DateTime,
932
- `open` DOUBLE,
933
- `high` DOUBLE,
934
- `low` DOUBLE,
935
- `close` DOUBLE,
936
- `amount` DOUBLE,
937
- `volume` DOUBLE
932
+ `open` UInt32,
933
+ `high` UInt32,
934
+ `low` UInt32,
935
+ `close` UInt32,
936
+ `amount` UInt64,
937
+ `volume` UInt64
938
938
  )
939
939
  ENGINE = MergeTree()
940
940
  PARTITION BY market
941
941
  PRIMARY KEY (market, code, date)
942
942
  ORDER BY (market, code, date);
943
943
  CREATE table if not exists hku_data.halfyear_k (
944
- `market` String,
945
- `code` String,
944
+ `market` FixedString(2),
945
+ `code` FixedString(6),
946
946
  `date` DateTime,
947
- `open` DOUBLE,
948
- `high` DOUBLE,
949
- `low` DOUBLE,
950
- `close` DOUBLE,
951
- `amount` DOUBLE,
952
- `volume` DOUBLE
947
+ `open` UInt32,
948
+ `high` UInt32,
949
+ `low` UInt32,
950
+ `close` UInt32,
951
+ `amount` UInt64,
952
+ `volume` UInt64
953
953
  )
954
954
  ENGINE = MergeTree()
955
955
  PARTITION BY market
956
956
  PRIMARY KEY (market, code, date)
957
957
  ORDER BY (market, code, date);
958
958
  CREATE table if not exists hku_data.year_k (
959
- `market` String,
960
- `code` String,
959
+ `market` FixedString(2),
960
+ `code` FixedString(6),
961
961
  `date` DateTime,
962
- `open` DOUBLE,
963
- `high` DOUBLE,
964
- `low` DOUBLE,
965
- `close` DOUBLE,
966
- `amount` DOUBLE,
967
- `volume` DOUBLE
962
+ `open` UInt32,
963
+ `high` UInt32,
964
+ `low` UInt32,
965
+ `close` UInt32,
966
+ `amount` UInt64,
967
+ `volume` UInt64
968
968
  )
969
969
  ENGINE = MergeTree()
970
970
  PARTITION BY market
971
971
  PRIMARY KEY (market, code, date)
972
972
  ORDER BY (market, code, date);
973
973
  CREATE table if not exists hku_data.min_k (
974
- `market` String,
975
- `code` String,
974
+ `market` FixedString(2),
975
+ `code` FixedString(6),
976
976
  `date` DateTime,
977
- `open` DOUBLE,
978
- `high` DOUBLE,
979
- `low` DOUBLE,
980
- `close` DOUBLE,
981
- `amount` DOUBLE,
982
- `volume` DOUBLE
977
+ `open` UInt32,
978
+ `high` UInt32,
979
+ `low` UInt32,
980
+ `close` UInt32,
981
+ `amount` UInt64,
982
+ `volume` UInt64
983
983
  )
984
984
  ENGINE = MergeTree()
985
985
  PARTITION BY (market, toYear(date)-toYear(date)%10)
986
986
  PRIMARY KEY (market, code, date)
987
987
  ORDER BY (market, code, date);
988
988
  CREATE table if not exists hku_data.min5_k (
989
- `market` String,
990
- `code` String,
989
+ `market` FixedString(2),
990
+ `code` FixedString(6),
991
991
  `date` DateTime,
992
- `open` DOUBLE,
993
- `high` DOUBLE,
994
- `low` DOUBLE,
995
- `close` DOUBLE,
996
- `amount` DOUBLE,
997
- `volume` DOUBLE
992
+ `open` UInt32,
993
+ `high` UInt32,
994
+ `low` UInt32,
995
+ `close` UInt32,
996
+ `amount` UInt64,
997
+ `volume` UInt64
998
998
  )
999
999
  ENGINE = MergeTree()
1000
1000
  PARTITION BY (market, toYear(date)-toYear(date)%10)
1001
1001
  PRIMARY KEY (market, code, date)
1002
1002
  ORDER BY (market, code, date);
1003
1003
  CREATE table if not exists hku_data.min15_k (
1004
- `market` String,
1005
- `code` String,
1004
+ `market` FixedString(2),
1005
+ `code` FixedString(6),
1006
1006
  `date` DateTime,
1007
- `open` DOUBLE,
1008
- `high` DOUBLE,
1009
- `low` DOUBLE,
1010
- `close` DOUBLE,
1011
- `amount` DOUBLE,
1012
- `volume` DOUBLE
1007
+ `open` UInt32,
1008
+ `high` UInt32,
1009
+ `low` UInt32,
1010
+ `close` UInt32,
1011
+ `amount` UInt64,
1012
+ `volume` UInt64
1013
1013
  )
1014
1014
  ENGINE = MergeTree()
1015
1015
  PARTITION BY (market, toYear(date)-toYear(date)%10)
1016
1016
  PRIMARY KEY (market, code, date)
1017
1017
  ORDER BY (market, code, date);
1018
1018
  CREATE table if not exists hku_data.min30_k (
1019
- `market` String,
1020
- `code` String,
1019
+ `market` FixedString(2),
1020
+ `code` FixedString(6),
1021
1021
  `date` DateTime,
1022
- `open` DOUBLE,
1023
- `high` DOUBLE,
1024
- `low` DOUBLE,
1025
- `close` DOUBLE,
1026
- `amount` DOUBLE,
1027
- `volume` DOUBLE
1022
+ `open` UInt32,
1023
+ `high` UInt32,
1024
+ `low` UInt32,
1025
+ `close` UInt32,
1026
+ `amount` UInt64,
1027
+ `volume` UInt64
1028
1028
  )
1029
1029
  ENGINE = MergeTree()
1030
1030
  PARTITION BY (market, toYear(date)-toYear(date)%10)
1031
1031
  PRIMARY KEY (market, code, date)
1032
1032
  ORDER BY (market, code, date);
1033
1033
  CREATE table if not exists hku_data.min60_k (
1034
- `market` String,
1035
- `code` String,
1034
+ `market` FixedString(2),
1035
+ `code` FixedString(6),
1036
1036
  `date` DateTime,
1037
- `open` DOUBLE,
1038
- `high` DOUBLE,
1039
- `low` DOUBLE,
1040
- `close` DOUBLE,
1041
- `amount` DOUBLE,
1042
- `volume` DOUBLE
1037
+ `open` UInt32,
1038
+ `high` UInt32,
1039
+ `low` UInt32,
1040
+ `close` UInt32,
1041
+ `amount` UInt64,
1042
+ `volume` UInt64
1043
1043
  )
1044
1044
  ENGINE = MergeTree()
1045
1045
  PARTITION BY market
1046
1046
  PRIMARY KEY (market, code, date)
1047
1047
  ORDER BY (market, code, date);
1048
1048
  CREATE table if not exists hku_data.hour2_k (
1049
- `market` String,
1050
- `code` String,
1049
+ `market` FixedString(2),
1050
+ `code` FixedString(6),
1051
1051
  `date` DateTime,
1052
- `open` DOUBLE,
1053
- `high` DOUBLE,
1054
- `low` DOUBLE,
1055
- `close` DOUBLE,
1056
- `amount` DOUBLE,
1057
- `volume` DOUBLE
1052
+ `open` UInt32,
1053
+ `high` UInt32,
1054
+ `low` UInt32,
1055
+ `close` UInt32,
1056
+ `amount` UInt64,
1057
+ `volume` UInt64
1058
1058
  )
1059
1059
  ENGINE = MergeTree()
1060
1060
  PARTITION BY market
1061
1061
  PRIMARY KEY (market, code, date)
1062
1062
  ORDER BY (market, code, date);
1063
1063
  CREATE table if not exists hku_data.timeline (
1064
- `market` String,
1065
- `code` String,
1064
+ `market` FixedString(2),
1065
+ `code` FixedString(6),
1066
1066
  `date` DateTime,
1067
- `price` DOUBLE,
1068
- `vol` DOUBLE
1067
+ `price` UInt32,
1068
+ `vol` UInt32
1069
1069
  )
1070
1070
  ENGINE = MergeTree()
1071
1071
  PARTITION BY (market, toYear(date)-toYear(date)%10)
1072
1072
  PRIMARY KEY (market, code, date)
1073
1073
  ORDER BY (market, code, date);
1074
1074
  CREATE table if not exists hku_data.transdata (
1075
- `market` String,
1076
- `code` String,
1075
+ `market` FixedString(2),
1076
+ `code` FixedString(6),
1077
1077
  `date` DateTime,
1078
- `price` DOUBLE,
1079
- `vol` DOUBLE,
1080
- `buyorsell` int
1078
+ `price` UInt32,
1079
+ `vol` UInt32,
1080
+ `buyorsell` UInt8
1081
1081
  )
1082
1082
  ENGINE = MergeTree()
1083
1083
  PARTITION BY (market, toYear(date))
hikyuu/data/common.py CHANGED
@@ -200,11 +200,11 @@ def get_china_bond10_rate(start_date="19901219"):
200
200
 
201
201
 
202
202
  def modifiy_code(code):
203
- if code.startswith(('0', '3')):
203
+ if code.startswith(('0', '3', '5', '20')):
204
204
  return 'SZ' + code
205
- if code.startswith(('4', '8', '92')):
205
+ if code.startswith(('1', '4', '8', '92')):
206
206
  return 'BJ' + code
207
- if code.startswith('6'):
207
+ if code.startswith(('6', '900')):
208
208
  return 'SH' + code
209
209
  else:
210
210
  hku_warn("Unknow code: {}", code)
@@ -163,7 +163,7 @@ def get_last_krecord(connect, tablename):
163
163
  # hku_info(f"{tablename} {a}")
164
164
  if not a:
165
165
  return None
166
- return (Datetime.from_timestamp_utc(a[0][0]*1000000).ymdhm, a[0][1], a[0][2], a[0][3], a[0][4], a[0][5], a[0][6])
166
+ return (Datetime.from_timestamp_utc(a[0][0]*1000000).ymdhm, a[0][1]*0.001, a[0][2]*0.001, a[0][3]*0.001, a[0][4]*0.001, a[0][5]*0.001, a[0][6]*0.001)
167
167
  except:
168
168
  return None
169
169
 
@@ -0,0 +1,318 @@
1
+ #!/usr/bin/python
2
+ # -*- coding: utf8 -*-
3
+ #
4
+ # Create on: 2025-10-05
5
+ # Author: fasiondog
6
+
7
+ from hikyuu.data.common import modifiy_code
8
+ from hikyuu.util import *
9
+ from hikyuu.fetcher.stock.zh_block_em import *
10
+ import os
11
+ from datetime import datetime
12
+
13
+
14
+ def sanitize_filename(filename: str) -> str:
15
+ """
16
+ 将字符串中影响文件创建的相关目录字符替换为下划线
17
+
18
+ Args:
19
+ filename: 输入的文件名字符串
20
+
21
+ Returns:
22
+ 处理后的文件名字符串,其中非法字符已被替换为下划线
23
+ """
24
+ if not filename:
25
+ return filename
26
+
27
+ # 需要替换的非法字符(Windows和Unix系统中的非法字符)
28
+ illegal_chars = '<>:"/\\|?*'
29
+
30
+ # 替换非法字符为下划线
31
+ sanitized = filename
32
+ for char in illegal_chars:
33
+ sanitized = sanitized.replace(char, '_')
34
+
35
+ return sanitized
36
+
37
+
38
+ _BLOCK_SAVE_PATH = os.path.expanduser('~') + '/.hikyuu/downloads/block'
39
+ if not os.path.exists(_BLOCK_SAVE_PATH):
40
+ os.makedirs(_BLOCK_SAVE_PATH)
41
+
42
+
43
+ def read_block_from_path(block_path=_BLOCK_SAVE_PATH):
44
+ """
45
+ 从指定目录下读取block信息
46
+
47
+ :param block_path: block根目录路径,默认为 _BLOCK_SAVE_PATH
48
+ :return: 返回格式类似于 {'block': {'category1': {'name1': [code1, code2]}},
49
+ 'block_info': {'category1: {'name1': 'code1', 'name2': ''}}
50
+ """
51
+ result = {
52
+ 'block': {},
53
+ 'block_info': {}
54
+ }
55
+
56
+ if not os.path.exists(block_path):
57
+ return result
58
+
59
+ # 遍历所有分类目录
60
+ for category in os.listdir(block_path):
61
+ category_path = os.path.join(block_path, category)
62
+ if not os.path.isdir(category_path):
63
+ continue
64
+
65
+ result['block'][category] = {}
66
+ result['block_info'][category] = {}
67
+
68
+ # 遍历分类目录下的所有.txt文件
69
+ for file in os.listdir(category_path):
70
+ if file.endswith('.txt'):
71
+ file_path = os.path.join(category_path, file)
72
+ # 文件名作为板块名称(去掉扩展名)
73
+ block_name = os.path.splitext(file)[0]
74
+
75
+ # 解析文件名,格式为 "code_name" 或 "name"
76
+ if '_' in block_name:
77
+ parts = block_name.split('_', 1) # 只分割第一个下划线
78
+ code_part = parts[0]
79
+ name_part = parts[1]
80
+ # 判断code部分是否为纯数字或字母数字组合
81
+ if code_part.replace('_', '').isalnum():
82
+ result['block_info'][category][name_part] = code_part
83
+ block_key = name_part
84
+ else:
85
+ result['block_info'][category][block_name] = ""
86
+ block_key = block_name
87
+ else:
88
+ result['block_info'][category][block_name] = ""
89
+ block_key = block_name
90
+
91
+ # 读取文件中的股票代码
92
+ codes = []
93
+ with open(file_path, 'r', encoding='utf-8') as f:
94
+ for line in f:
95
+ code = line.strip()
96
+ if code:
97
+ codes.append(code)
98
+
99
+ result['block'][category][block_key] = codes
100
+
101
+ return result
102
+
103
+
104
+ def is_file_can_download(filepath, sec_limit=5 * 24 * 60 * 60):
105
+ """判断文件创建时间是否超过时长限制可以下载"""
106
+ if not os.path.exists(filepath):
107
+ return True
108
+
109
+ file_mtime = os.path.getmtime(filepath)
110
+ file_datetime = datetime.fromtimestamp(file_mtime)
111
+ now = datetime.now()
112
+
113
+ # 计算时间差是否超过时间限制
114
+ return (now - file_datetime).total_seconds() > sec_limit
115
+
116
+
117
+ @hku_catch()
118
+ def save_block(stkcodes: list, filename: str):
119
+ """将板块数据保存为CSV文件,格式为板块名称/code"""
120
+ with open(filename, 'w', encoding='utf-8') as f:
121
+ for code in stkcodes:
122
+ f.write(f"{code}\n")
123
+ # hku_info(f"已保存至 {filename}")
124
+
125
+
126
+ @hku_catch(ret={}, trace=False)
127
+ def down_em_all_hybk_info():
128
+ """下载东财所有行业板块列表"""
129
+ save_path = f'{_BLOCK_SAVE_PATH}/行业板块'
130
+ if not os.path.exists(save_path):
131
+ os.makedirs(save_path)
132
+ blk_list = get_hybk_names()
133
+ time.sleep(random.uniform(1, 3))
134
+ total = len(blk_list)
135
+ for i, blk in enumerate(blk_list):
136
+ filename = f"{save_path}/{blk[0]}_{blk[1]}.txt"
137
+ if is_file_can_download(filename, 5 * 24 * 60 * 60):
138
+ stk_codes = get_hybk_cons_code(blk[0])
139
+ hku_info(f"{i+1}|{total} 获取行业板块{blk[1]}成分: {len(stk_codes)}")
140
+ stk_codes = [modifiy_code(code) for code in stk_codes]
141
+ stk_codes = [code for code in stk_codes if code is not None]
142
+ save_block(stk_codes, filename)
143
+ time.sleep(random.uniform(1, 3))
144
+
145
+
146
+ @hku_catch(ret={}, trace=False)
147
+ def down_em_all_gnbk_info():
148
+ """获取所有概念版本列表"""
149
+ save_path = f'{_BLOCK_SAVE_PATH}/概念板块'
150
+ if not os.path.exists(save_path):
151
+ os.makedirs(save_path)
152
+ blk_names = stock_board_concept_name_em()['板块名称']
153
+ not_need_blks = set(["昨日连板_含一字", "昨日涨停_含一字", "昨日涨停"])
154
+ total = len(blk_names)
155
+ for i, blk_name in enumerate(blk_names):
156
+ if blk_name in not_need_blks:
157
+ continue
158
+ filename = f"{save_path}/{sanitize_filename(blk_name)}.txt"
159
+ if is_file_can_download(filename, 30 * 24 * 60 * 60):
160
+ stk_codes = stock_board_concept_cons_em(blk_name)
161
+ stk_codes = stk_codes['代码'].to_list()
162
+ stk_codes = [modifiy_code(code) for code in stk_codes]
163
+ stk_codes = [code for code in stk_codes if code is not None]
164
+ hku_info(f"{i+1}|{total} 获取概念板块{blk_name}成分: {len(stk_codes)}")
165
+ save_block(stk_codes, filename)
166
+ time.sleep(random.uniform(1, 3))
167
+
168
+
169
+ @hku_catch(ret={}, trace=False)
170
+ def down_em_all_dybk_info():
171
+ """获取所有地域板块列表"""
172
+ save_path = f'{_BLOCK_SAVE_PATH}/地域板块'
173
+ if not os.path.exists(save_path):
174
+ os.makedirs(save_path)
175
+ blk_list = get_dybk_names()
176
+
177
+ url = "http://13.push2.eastmoney.com/api/qt/clist/get"
178
+ params = {
179
+ "pn": "1",
180
+ "pz": str(em_num_per_page),
181
+ "po": "1",
182
+ "np": "1",
183
+ "ut": "bd1d9ddb04089700cf9c27f6f7426281",
184
+ "fltt": "2",
185
+ "invt": "2",
186
+ "fid": "f3",
187
+ # "fs": f"b:{stock_board_code} f:!50",
188
+ "fields": "f12",
189
+ "_": "1626081702127",
190
+ }
191
+
192
+ total = len(blk_list)
193
+ for i, v in enumerate(blk_list):
194
+ blk_code, blk_name = v[0], v[1]
195
+ filename = f"{save_path}/{blk_name}.txt"
196
+ if not is_file_can_download(filename, 10 * 24 * 60 * 60):
197
+ continue
198
+
199
+ params["fs"] = f"b:{blk_code} f:!50"
200
+ params["pn"] = 1
201
+ time.sleep(random.uniform(1, 3))
202
+ r = requests.get(url, params=params, timeout=15)
203
+ data = r.json()
204
+ if data["data"] is None:
205
+ continue
206
+
207
+ stk_json = r.json()
208
+ stk_json = stk_json["data"]["diff"]
209
+ stk_codes = []
210
+
211
+ total_page = math.ceil(data["data"]["total"] / em_num_per_page)
212
+ for page in range(2, total_page + 1):
213
+ params["pn"] = page
214
+ r = requests.get(url, params=params, timeout=15)
215
+ stk_json = r.json()
216
+ stk_json = stk_json["data"]["diff"]
217
+ stk_codes.extend([f"{v['f12']}" for v in stk_json])
218
+ time.sleep(random.uniform(1, 3))
219
+
220
+ stk_codes = [modifiy_code(code) for code in stk_codes]
221
+ stk_codes = [code for code in stk_codes if code is not None]
222
+ save_block(stk_codes, filename)
223
+ hku_info(f'{i+1}|{total} 获取地域板块{blk_name}成分: {len(stk_codes)}')
224
+
225
+
226
+ @hku_catch(ret={}, trace=False)
227
+ def download_all_zsbk_info():
228
+ """获取所有指数成分股列表"""
229
+ save_path = f'{_BLOCK_SAVE_PATH}/指数板块'
230
+ if not os.path.exists(save_path):
231
+ os.makedirs(save_path)
232
+
233
+ blk_info = ak.index_stock_info()
234
+ time.sleep(random.uniform(1, 3))
235
+
236
+ blk_info['index_code'] = blk_info['index_code'].astype(str) # 确保是字符串类型
237
+ df_000 = blk_info[blk_info['index_code'].str.startswith('000')].reset_index(drop=True) # 000前缀
238
+ df_399 = blk_info[blk_info['index_code'].str.startswith('399')].reset_index(drop=True) # 399前缀
239
+
240
+ # 2. 交替合并两个DataFrame
241
+ merged_rows = []
242
+ max_length = max(len(df_000), len(df_399)) # 取两个DataFrame的最大长度
243
+
244
+ for i in range(max_length):
245
+ # 先加000前缀的行(如果存在)
246
+ if i < len(df_000):
247
+ merged_rows.append(df_000.iloc[i])
248
+ # 再加399前缀的行(如果存在)
249
+ if i < len(df_399):
250
+ merged_rows.append(df_399.iloc[i])
251
+
252
+ # 3. 转换为DataFrame
253
+ blk_info = pd.DataFrame(merged_rows).reset_index(drop=True)
254
+
255
+ not_need_blks = set(["000012", "000013", "000022", "000061", "000101", "000188",
256
+ "000817", "000847", "000849", "000850", "000851", "000853",
257
+ "000854", "000856", "000857", "000858", "000923", "000973",
258
+ "000974", "000996", "000997", "000999", "399415", "399416"])
259
+
260
+ failed_sina = 0
261
+ blk_set = {}
262
+ blk_codes = blk_info["index_code"]
263
+ blk_names = blk_info["display_name"]
264
+ total = len(blk_codes)
265
+ for i in range(total):
266
+ blk_name = blk_names[i]
267
+ blk_code = blk_codes[i]
268
+ # 沪深指数有重复,避免深指覆盖
269
+ if blk_name in blk_set or blk_code in not_need_blks:
270
+ continue
271
+
272
+ market_block_code = f'SH{blk_code}' if blk_code.startswith('0') else f'SZ{blk_code}'
273
+ filename = f"{save_path}/{market_block_code}_{blk_name}.txt"
274
+ if not is_file_can_download(filename, 10 * 24 * 60 * 60):
275
+ continue
276
+
277
+ try:
278
+ if blk_code[:3] == "399":
279
+ if failed_sina >= 5:
280
+ continue
281
+ stk_codes = ak.index_stock_cons(symbol=blk_code)
282
+ stk_codes = stk_codes['品种代码'].to_list()
283
+ else:
284
+ stk_codes = ak.index_stock_cons_csindex(symbol=blk_code)
285
+ stk_codes = stk_codes['成分券代码'].to_list()
286
+
287
+ stk_codes = [modifiy_code(code) for code in stk_codes]
288
+ stk_codes = [code for code in stk_codes if code is not None]
289
+ save_block(stk_codes, filename)
290
+ hku_info("{}|{} 获取指数板块 {}|{} 成分: {}", i, total, blk_code, blk_name, len(stk_codes))
291
+ blk_set[blk_name] = 1
292
+ except KeyboardInterrupt:
293
+ break
294
+ except Exception as e:
295
+ print(f"Failed! {i}, {blk_code}, {blk_name} {str(e)}")
296
+ if blk_code.startswith("399"):
297
+ failed_sina += 1
298
+ # raise e
299
+ time.sleep(random.uniform(1, 3))
300
+
301
+
302
+ def download_block_info():
303
+ down_em_all_hybk_info()
304
+ # down_em_all_dybk_info()
305
+ # down_em_all_gnbk_info()
306
+ download_all_zsbk_info()
307
+
308
+
309
+ if __name__ == "__main__":
310
+ # down_em_all_hybk_info()
311
+ # down_em_all_dybk_info()
312
+ # down_em_all_gnbk_info()
313
+ # download_all_zsbk_info()
314
+
315
+ ret = read_block_from_path()
316
+ # print(ret['block'])
317
+ print(ret['block_info'])
318
+ print(tuple(ret['block'].keys()))