hikyuu 2.3.0__py3-none-win_amd64.whl → 2.5.0__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 (179) hide show
  1. hikyuu/__init__.py +438 -6
  2. hikyuu/__init__.pyi +791 -0
  3. hikyuu/analysis/__init__.pyi +487 -0
  4. hikyuu/analysis/analysis.pyi +517 -0
  5. hikyuu/core.pyi +482 -0
  6. hikyuu/cpp/__init__.pyi +3 -0
  7. hikyuu/cpp/boost_date_time-mt.dll +0 -0
  8. hikyuu/cpp/boost_serialization-mt.dll +0 -0
  9. hikyuu/cpp/boost_wserialization-mt.dll +0 -0
  10. hikyuu/cpp/core310.pyd +0 -0
  11. hikyuu/cpp/core311.pyd +0 -0
  12. hikyuu/cpp/core312.pyd +0 -0
  13. hikyuu/cpp/core312.pyi +12867 -0
  14. hikyuu/cpp/core313.pyd +0 -0
  15. hikyuu/cpp/core38.pyd +0 -0
  16. hikyuu/cpp/core39.pyd +0 -0
  17. hikyuu/cpp/hikyuu.dll +0 -0
  18. hikyuu/cpp/hikyuu.lib +0 -0
  19. hikyuu/cpp/sqlite3.dll +0 -0
  20. hikyuu/data/common_mysql.py +24 -7
  21. hikyuu/data/common_pytdx.py +17 -1
  22. hikyuu/data/em_block_to_mysql.py +3 -2
  23. hikyuu/data/em_block_to_sqlite.py +8 -3
  24. hikyuu/data/mysql_upgrade/0025.sql +61 -0
  25. hikyuu/data/mysql_upgrade/0026.sql +9 -0
  26. hikyuu/data/sqlite_upgrade/0025.sql +63 -0
  27. hikyuu/data/sqlite_upgrade/0026.sql +10 -0
  28. hikyuu/draw/__init__.pyi +35 -0
  29. hikyuu/draw/drawplot/__init__.py +3 -0
  30. hikyuu/draw/drawplot/__init__.pyi +134 -0
  31. hikyuu/draw/drawplot/bokeh_draw.pyi +796 -0
  32. hikyuu/draw/drawplot/common.pyi +10 -0
  33. hikyuu/draw/drawplot/echarts_draw.py +219 -24
  34. hikyuu/draw/drawplot/echarts_draw.pyi +682 -0
  35. hikyuu/draw/drawplot/matplotlib_draw.py +18 -3
  36. hikyuu/draw/drawplot/matplotlib_draw.pyi +1101 -0
  37. hikyuu/draw/elder.pyi +44 -0
  38. hikyuu/draw/kaufman.pyi +38 -0
  39. hikyuu/draw/volume.pyi +31 -0
  40. hikyuu/examples/notebook/Demo/Demo2.ipynb +1 -1
  41. hikyuu/extend.py +9 -3
  42. hikyuu/extend.pyi +636 -0
  43. hikyuu/fetcher/stock/zh_block_em.py +118 -51
  44. hikyuu/gui/data/EscapetimeThread.py +4 -4
  45. hikyuu/gui/data/ImportBlockInfoTask.py +3 -2
  46. hikyuu/gui/data/ImportHistoryFinanceTask.py +2 -0
  47. hikyuu/gui/data/MainWindow.py +48 -42
  48. hikyuu/gui/importdata.py +13 -26
  49. hikyuu/hub.py +2 -4
  50. hikyuu/hub.pyi +254 -0
  51. hikyuu/include/hikyuu/DataType.h +5 -0
  52. hikyuu/include/hikyuu/Stock.h +7 -0
  53. hikyuu/include/hikyuu/indicator/Indicator.h +8 -1
  54. hikyuu/include/hikyuu/indicator/Indicator2InImp.h +65 -0
  55. hikyuu/include/hikyuu/indicator/IndicatorImp.h +4 -3
  56. hikyuu/include/hikyuu/indicator/build_in.h +12 -0
  57. hikyuu/include/hikyuu/indicator/crt/ADVANCE.h +3 -1
  58. hikyuu/include/hikyuu/indicator/crt/CONTEXT.h +2 -2
  59. hikyuu/include/hikyuu/indicator/crt/CORR.h +4 -2
  60. hikyuu/include/hikyuu/indicator/crt/COST.h +3 -0
  61. hikyuu/include/hikyuu/indicator/crt/CYCLE.h +24 -0
  62. hikyuu/include/hikyuu/indicator/crt/DECLINE.h +3 -1
  63. hikyuu/include/hikyuu/indicator/crt/DISCARD.h +27 -0
  64. hikyuu/include/hikyuu/indicator/crt/DMA.h +2 -1
  65. hikyuu/include/hikyuu/indicator/crt/HSL.h +1 -13
  66. hikyuu/include/hikyuu/indicator/crt/INBLOCK.h +31 -0
  67. hikyuu/include/hikyuu/indicator/crt/INDEX.h +60 -0
  68. hikyuu/include/hikyuu/indicator/crt/INSUM.h +5 -2
  69. hikyuu/include/hikyuu/indicator/crt/ISINF.h +28 -0
  70. hikyuu/include/hikyuu/indicator/crt/ISINFA.h +28 -0
  71. hikyuu/include/hikyuu/indicator/crt/ISNA.h +29 -0
  72. hikyuu/include/hikyuu/indicator/crt/JUMPDOWN.h +24 -0
  73. hikyuu/include/hikyuu/indicator/crt/JUMPUP.h +24 -0
  74. hikyuu/include/hikyuu/indicator/crt/LASTVALUE.h +29 -0
  75. hikyuu/include/hikyuu/indicator/crt/LIUTONGPAN.h +1 -0
  76. hikyuu/include/hikyuu/indicator/crt/REPLACE.h +29 -0
  77. hikyuu/include/hikyuu/indicator/crt/SPEARMAN.h +3 -2
  78. hikyuu/include/hikyuu/indicator/crt/WINNER.h +38 -0
  79. hikyuu/include/hikyuu/indicator/imp/IContext.h +1 -1
  80. hikyuu/include/hikyuu/indicator/imp/ICorr.h +7 -22
  81. hikyuu/include/hikyuu/indicator/imp/ICost.h +31 -0
  82. hikyuu/include/hikyuu/indicator/imp/ICycle.h +30 -0
  83. hikyuu/include/hikyuu/indicator/imp/IDiscard.h +28 -0
  84. hikyuu/include/hikyuu/indicator/imp/IDma.h +7 -24
  85. hikyuu/include/hikyuu/indicator/imp/IHsl.h +30 -0
  86. hikyuu/include/hikyuu/indicator/imp/IInBlock.h +30 -0
  87. hikyuu/include/hikyuu/indicator/imp/IIndex.h +26 -0
  88. hikyuu/include/hikyuu/indicator/imp/IIsInf.h +26 -0
  89. hikyuu/include/hikyuu/indicator/imp/IIsInfa.h +26 -0
  90. hikyuu/include/hikyuu/indicator/imp/IIsNa.h +26 -0
  91. hikyuu/include/hikyuu/indicator/imp/IJumpDown.h +24 -0
  92. hikyuu/include/hikyuu/indicator/imp/IJumpUp.h +24 -0
  93. hikyuu/include/hikyuu/indicator/imp/ILastValue.h +26 -0
  94. hikyuu/include/hikyuu/indicator/imp/IReplace.h +26 -0
  95. hikyuu/include/hikyuu/indicator/imp/ISpearman.h +6 -21
  96. hikyuu/include/hikyuu/indicator/imp/IWinner.h +26 -0
  97. hikyuu/include/hikyuu/indicator_talib/imp/TaMavp.h +6 -20
  98. hikyuu/include/hikyuu/indicator_talib/imp/ta_defines.h +14 -65
  99. hikyuu/include/hikyuu/indicator_talib/imp/ta_imp.h +54 -90
  100. hikyuu/include/hikyuu/indicator_talib/ta_crt.h +11 -9
  101. hikyuu/include/hikyuu/strategy/RunPortfolioInStrategy.h +3 -4
  102. hikyuu/include/hikyuu/strategy/Strategy.h +4 -5
  103. hikyuu/include/hikyuu/trade_manage/TradeRecord.h +5 -1
  104. hikyuu/include/hikyuu/trade_sys/allocatefunds/build_in.h +1 -0
  105. hikyuu/include/hikyuu/trade_sys/allocatefunds/crt/AF_FixedWeightList.h +22 -0
  106. hikyuu/include/hikyuu/trade_sys/allocatefunds/imp/FixedWeightListAllocateFunds.h +25 -0
  107. hikyuu/include/hikyuu/trade_sys/moneymanager/MoneyManagerBase.h +17 -4
  108. hikyuu/include/hikyuu/trade_sys/moneymanager/build_in.h +2 -0
  109. hikyuu/include/hikyuu/trade_sys/moneymanager/crt/MM_FixedCapital.h +6 -0
  110. hikyuu/include/hikyuu/trade_sys/moneymanager/crt/MM_FixedCapitalFunds.h +26 -0
  111. hikyuu/include/hikyuu/trade_sys/moneymanager/crt/MM_FixedCountTps.h +27 -0
  112. hikyuu/include/hikyuu/trade_sys/moneymanager/crt/MM_FixedRisk.h +6 -0
  113. hikyuu/include/hikyuu/trade_sys/moneymanager/crt/MM_FixedUnits.h +6 -0
  114. hikyuu/include/hikyuu/trade_sys/moneymanager/crt/MM_WilliamsFixedRisk.h +7 -0
  115. hikyuu/include/hikyuu/trade_sys/moneymanager/imp/FixedCapitalFundsMM.h +28 -0
  116. hikyuu/include/hikyuu/trade_sys/moneymanager/imp/FixedCountTpsMM.h +44 -0
  117. hikyuu/include/hikyuu/trade_sys/multifactor/build_in.h +1 -0
  118. hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_Weight.h +30 -0
  119. hikyuu/include/hikyuu/trade_sys/multifactor/imp/WeightMultiFactor.h +41 -0
  120. hikyuu/include/hikyuu/trade_sys/portfolio/Portfolio.h +38 -37
  121. hikyuu/include/hikyuu/trade_sys/portfolio/build_in.h +1 -0
  122. hikyuu/include/hikyuu/trade_sys/portfolio/crt/PF_Simple.h +25 -1
  123. hikyuu/include/hikyuu/trade_sys/portfolio/crt/PF_WithoutAF.h +50 -0
  124. hikyuu/include/hikyuu/trade_sys/portfolio/imp/SimplePortfolio.h +53 -0
  125. hikyuu/include/hikyuu/trade_sys/portfolio/imp/WithoutAFPortfolio.h +57 -0
  126. hikyuu/include/hikyuu/trade_sys/selector/imp/MultiFactorSelector.h +7 -0
  127. hikyuu/include/hikyuu/trade_sys/signal/SignalBase.h +51 -5
  128. hikyuu/include/hikyuu/trade_sys/signal/build_in.h +2 -0
  129. hikyuu/include/hikyuu/trade_sys/signal/crt/SG_Bool.h +2 -1
  130. hikyuu/include/hikyuu/trade_sys/signal/crt/SG_Logic.h +37 -0
  131. hikyuu/include/hikyuu/trade_sys/signal/crt/SG_OneSide.h +28 -0
  132. hikyuu/include/hikyuu/trade_sys/signal/imp/OneSideSignal.h +46 -0
  133. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/AddSignal.h +19 -0
  134. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/AddValueSignal.h +19 -0
  135. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/DivSignal.h +19 -0
  136. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/DivValueSignal.h +22 -0
  137. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/MulSignal.h +19 -0
  138. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/MulValueSignal.h +19 -0
  139. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/OperatorSignal.h +68 -0
  140. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/OperatorValueSignal.h +67 -0
  141. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/SubSignal.h +19 -0
  142. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/SubValueSignal.h +22 -0
  143. hikyuu/include/hikyuu/trade_sys/signal/imp/logic/__init__.py +1 -0
  144. hikyuu/include/hikyuu/trade_sys/stoploss/crt/ST_Indicator.h +1 -1
  145. hikyuu/include/hikyuu/trade_sys/stoploss/imp/IndicatorStoploss.h +3 -4
  146. hikyuu/include/hikyuu/utilities/FilterNode.h +2 -2
  147. hikyuu/include/hikyuu/utilities/Log.h +42 -15
  148. hikyuu/include/hikyuu/utilities/datetime/Datetime.h +1 -1
  149. hikyuu/include/hikyuu/utilities/datetime/TimeDelta.h +2 -2
  150. hikyuu/include/hikyuu/utilities/db_connect/DBCondition.h +4 -0
  151. hikyuu/include/hikyuu/utilities/db_connect/SQLResultSet.h +2 -2
  152. hikyuu/include/hikyuu/utilities/db_connect/mysql/MySQLConnect.h +5 -1
  153. hikyuu/include/hikyuu/utilities/node/NodeServer.h +4 -4
  154. hikyuu/include/hikyuu/utilities/thread/MQStealThreadPool.h +2 -2
  155. hikyuu/include/hikyuu/utilities/thread/MQThreadPool.h +2 -2
  156. hikyuu/include/hikyuu/utilities/thread/StealThreadPool.h +5 -5
  157. hikyuu/include/hikyuu/utilities/thread/ThreadPool.h +2 -2
  158. hikyuu/include/hikyuu/utilities/thread/algorithm.h +16 -10
  159. hikyuu/include/hikyuu/version.h +4 -4
  160. hikyuu/indicator/indicator.py +1 -0
  161. hikyuu/interactive.py +3 -266
  162. hikyuu/trade_manage/__init__.pyi +584 -0
  163. hikyuu/trade_manage/broker.pyi +54 -0
  164. hikyuu/trade_manage/broker_easytrader.pyi +21 -0
  165. hikyuu/trade_manage/broker_mail.pyi +55 -0
  166. hikyuu/trade_manage/trade.pyi +590 -0
  167. hikyuu/util/__init__.pyi +55 -0
  168. hikyuu/util/check.pyi +59 -0
  169. hikyuu/util/mylog.pyi +70 -0
  170. hikyuu/util/notebook.pyi +23 -0
  171. hikyuu/util/singleton.pyi +18 -0
  172. hikyuu/util/slice.pyi +8 -0
  173. {hikyuu-2.3.0.dist-info → hikyuu-2.5.0.dist-info}/METADATA +3 -2
  174. {hikyuu-2.3.0.dist-info → hikyuu-2.5.0.dist-info}/RECORD +178 -95
  175. {hikyuu-2.3.0.dist-info → hikyuu-2.5.0.dist-info}/top_level.txt +1 -0
  176. hikyuu/deprecated.py +0 -651
  177. {hikyuu-2.3.0.dist-info → hikyuu-2.5.0.dist-info}/LICENSE +0 -0
  178. {hikyuu-2.3.0.dist-info → hikyuu-2.5.0.dist-info}/WHEEL +0 -0
  179. {hikyuu-2.3.0.dist-info → hikyuu-2.5.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,10 @@
1
+ from __future__ import annotations
2
+ from hikyuu.cpp.core312 import Query
3
+ __all__ = ['Query', 'get_draw_title']
4
+ def get_draw_title(kdata):
5
+ """
6
+ 根据typ值,返回相应的标题,如 上证指数(日线)
7
+ 参数:kdata: KData实例
8
+ 返回:一个包含stock名称的字符串,可用作绘图时的标题
9
+
10
+ """
@@ -1,7 +1,7 @@
1
1
  from functools import wraps
2
2
 
3
3
  from pyecharts import options as opts
4
- from pyecharts.charts import Kline, Scatter, Line, Bar, Grid
4
+ from pyecharts.charts import Kline, Scatter, Line, Bar, Grid, Page
5
5
  from pyecharts.charts.base import Base as ChartBase
6
6
  from pyecharts.commons.utils import JsCode
7
7
 
@@ -9,6 +9,92 @@ from hikyuu.core import KData, System
9
9
  from .common import get_draw_title
10
10
  from hikyuu import *
11
11
 
12
+
13
+ class MultiLineTextChart(ChartBase):
14
+ def __init__(self, init_opts: opts.InitOpts = opts.InitOpts()):
15
+ super().__init__(init_opts=init_opts)
16
+ self._last_x = 50 # 默认起始 x 坐标
17
+ self._last_y = 5 # 默认起始 y 坐标
18
+ self._line_height = 20 # 默认行高
19
+
20
+ def reset_position(self, x=None, y=None):
21
+ if x is not None:
22
+ self._last_x = x
23
+ if y is not None:
24
+ self._last_y = y
25
+
26
+ def add(self, text: str, x = None, y = None, text_style = None):
27
+ """
28
+ 添加多行文本
29
+
30
+ :param text: 要显示的文本内容
31
+ :param x: 文本区域的左上角 x 坐标
32
+ :param y: 文本区域的左上角 y 坐标
33
+ :param text_style: 文本样式,如字体大小、颜色等
34
+ """
35
+ if text_style is None:
36
+ text_style = {"fontSize": 14, "color": "#333", "fontFamily": "Arial"}
37
+
38
+ graphic_elements = self.options.get('graphic', [])
39
+
40
+ if x is None:
41
+ x = self._last_x
42
+ if y is None:
43
+ y = self._last_y + self._line_height
44
+
45
+ # 默认左右边距各50
46
+ width = int(self.width.strip('px')) - 100
47
+ if x is not None:
48
+ width -= x
49
+ lines = self._split_text(text, width, text_style.get("font_size", 14))
50
+
51
+ for i, line in enumerate(lines):
52
+ graphic_elements.append(
53
+ opts.GraphicText(
54
+ graphic_item=opts.GraphicItem(
55
+ position=[x, y + i * (text_style.get("font_size", 14) + 5)],
56
+ z=100,
57
+ ),
58
+ graphic_textstyle_opts=opts.GraphicTextStyleOpts(
59
+ text=line,
60
+ font=text_style.get("fontFamily", "sans-serif"),
61
+ font_size=text_style.get("font_size", 14),
62
+ graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
63
+ fill=text_style.get("color", "#000"))
64
+ )
65
+ )
66
+ )
67
+ self._last_x = x
68
+ self._last_y = y + i * (text_style.get("font_size", 14) + 5)
69
+
70
+ self.options.update(graphic=graphic_elements)
71
+
72
+
73
+ def _split_text(self, text: str, width: int, font_size: int):
74
+ """
75
+ 根据宽度和字体大小分割文本为多行
76
+
77
+ :param text: 要分割的文本
78
+ :param width: 文本区域的宽度
79
+ :param font_size: 字体大小
80
+ :return: 分割后的文本行列表
81
+ """
82
+ # 假设每个字符的宽度大致为字体大小的一半
83
+ max_chars_per_line = int(width / (font_size / 2))
84
+ lines = []
85
+ current_line = ""
86
+ for word in text.split():
87
+ if len(current_line) + len(word) + 1 <= max_chars_per_line:
88
+ current_line += " " + word if current_line else word
89
+ else:
90
+ if current_line:
91
+ lines.append(current_line)
92
+ current_line = word
93
+ if current_line:
94
+ lines.append(current_line)
95
+ return lines
96
+
97
+
12
98
  # 控制k线图和volume图的位置
13
99
  grid_pos = [
14
100
  opts.GridOpts(pos_left="5%", pos_right="1%", height="57%"),
@@ -17,12 +103,12 @@ grid_pos = [
17
103
 
18
104
 
19
105
  def _get_js_data_var(kdata):
20
- datas = [[r.open, r.close, r.low, r.high, r.volume] for r in kdata]
106
+ datas = [[round(r.open, 2), round(r.close, 2), round(r.low, 2), round(r.high, 2), round(r.volume, 2)] for r in kdata]
21
107
  return datas
22
108
 
23
109
 
24
110
  def _brush_chart(kdata, chart):
25
- datetimes_str = [str(dt) for dt in kdata.get_datetime_list()]
111
+ datetimes_str = simple_datetime_list(kdata.get_datetime_list(), kdata.get_query().ktype)
26
112
  brush_range = (datetimes_str[len(datetimes_str) // 2], datetimes_str[len(datetimes_str) * 3 // 4])
27
113
  if hasattr(chart, 'add_dispatch_actions'): # PR https://github.com/pyecharts/pyecharts/pull/2244 not yet merged
28
114
  chart.add_dispatch_actions(
@@ -66,11 +152,25 @@ def get_series_name(kdata):
66
152
  return stitle
67
153
 
68
154
 
155
+ def simple_datetime_list(datetimes: list, ktype:str=None):
156
+ if ktype is None:
157
+ return [
158
+ sd.split(' ')[0] if sd.endswith('00:00:00') else
159
+ sd.rsplit(':', 1)[0] if sd.endswith(':00') else
160
+ sd
161
+ for sd in (str(dt) for dt in datetimes)
162
+ ]
163
+ if ktype.startswith('MIN') or ktype.startswith('HOUR'):
164
+ datetimes = [str(dt).rsplit(':', 1)[0] for dt in datetimes]
165
+ else:
166
+ datetimes = [str(dt).split(' ')[0] for dt in datetimes]
167
+ return datetimes
168
+
169
+
69
170
  def kplot_line(kdata: KData):
70
- datetimes = kdata.get_datetime_list()
71
- datetimes = [str(dt) for dt in datetimes]
171
+ datetimes = simple_datetime_list(kdata.get_datetime_list(), kdata.get_query().ktype)
72
172
  # order in OCLH
73
- kdata_points = [(r.open, r.close, r.low, r.high) for r in kdata]
173
+ kdata_points = [(round(r.open, 2), round(r.close, 2), round(r.low, 2), round(r.high, 2)) for r in kdata]
74
174
  title = get_draw_title(kdata)
75
175
  last_record = kdata[-1]
76
176
  text = u'%s 开:%.2f 高:%.2f 低:%.2f 收:%.2f 涨幅:%.2f%%' % (
@@ -92,11 +192,11 @@ def kplot_line(kdata: KData):
92
192
  ),
93
193
  datazoom_opts=[
94
194
  opts.DataZoomOpts(
95
- is_show=True,
195
+ is_show=len(datetimes) > 200,
96
196
  xaxis_index=[0, 1], # 同时控制k线图和volume图的x轴缩放
97
197
  type_="slider",
98
198
  pos_top="85%",
99
- range_start=0,
199
+ range_start=(100 - 200 * 100 / len(datetimes)) if len(datetimes) > 200 else 0,
100
200
  range_end=100,
101
201
  ),
102
202
  ],
@@ -163,8 +263,7 @@ def kplot_line(kdata: KData):
163
263
 
164
264
 
165
265
  def volume_barplot(kdata: KData):
166
- datetimes = kdata.get_datetime_list()
167
- datetimes = [str(dt) for dt in datetimes]
266
+ datetimes = simple_datetime_list(kdata.get_datetime_list(), kdata.get_query().ktype)
168
267
  volumes = [r.volume for r in kdata]
169
268
  bar_vol = (
170
269
  Bar()
@@ -212,15 +311,15 @@ def volume_barplot(kdata: KData):
212
311
 
213
312
 
214
313
  @_chart_html_wrap
215
- def iplot(indicator, kref: KData = None, chart=None):
314
+ def iplot(indicator, kref: KData = None, chart=None, ilongname=False):
216
315
  datetimes = indicator.get_datetime_list()
217
- py_indicator = [None if x == constant.null_price else x for x in indicator]
218
- datetimes = [str(dt) for dt in datetimes]
316
+ py_indicator = [None if x == constant.null_price else round(x, 2) for x in indicator]
317
+ datetimes = simple_datetime_list(datetimes)
219
318
  if not datetimes:
220
319
  datetimes = list(range(len(indicator)))
221
320
  if kref:
222
- datetimes = [str(dt) for dt in kref.get_datetime_list()]
223
- name = "%s %.2f" % (indicator.long_name, indicator[-1])
321
+ datetimes = simple_datetime_list(kref.get_datetime_list(), kref.get_query().ktype)
322
+ name = indicator.name
224
323
  line = (
225
324
  Line()
226
325
  .add_xaxis(xaxis_data=datetimes)
@@ -236,6 +335,7 @@ def iplot(indicator, kref: KData = None, chart=None):
236
335
  return chart.overlap(line)
237
336
  else:
238
337
  line.set_global_opts(
338
+ title_opts=opts.TitleOpts(title="%s %.2f" % (indicator.long_name if ilongname else indicator.name, indicator[-1])),
239
339
  yaxis_opts=opts.AxisOpts(
240
340
  is_scale=True,
241
341
  splitarea_opts=opts.SplitAreaOpts(
@@ -250,6 +350,16 @@ def iplot(indicator, kref: KData = None, chart=None):
250
350
  border_color="#ccc",
251
351
  textstyle_opts=opts.TextStyleOpts(color="#000"),
252
352
  ),
353
+ datazoom_opts=[
354
+ opts.DataZoomOpts(
355
+ is_show=len(datetimes) > 200,
356
+ xaxis_index=0,
357
+ type_="slider",
358
+ pos_top="92%",
359
+ range_start=(100 - 200 * 100 / len(datetimes)) if len(datetimes) > 200 else 0,
360
+ range_end=100,
361
+ )
362
+ ],
253
363
  )
254
364
  return line
255
365
 
@@ -257,12 +367,12 @@ def iplot(indicator, kref: KData = None, chart=None):
257
367
  @_chart_html_wrap
258
368
  def ibar(indicator, kref: KData = None, chart=None):
259
369
  datetimes = indicator.get_datetime_list()
260
- py_indicator = [None if x == constant.null_price else x for x in indicator]
261
- datetimes = [str(dt) for dt in datetimes]
370
+ py_indicator = [None if x == constant.null_price else round(x, 2) for x in indicator]
371
+ datetimes = simple_datetime_list(datetimes)
262
372
  if not datetimes:
263
373
  datetimes = list(range(len(indicator)))
264
374
  if kref:
265
- datetimes = [str(dt) for dt in kref.get_datetime_list()]
375
+ datetimes = simple_datetime_list(kref.get_datetime_list(), kref.get_query().ktype)
266
376
  name = "%s %.2f" % (indicator.long_name, indicator[-1])
267
377
  bar = (
268
378
  Bar()
@@ -288,9 +398,19 @@ def ibar(indicator, kref: KData = None, chart=None):
288
398
 
289
399
 
290
400
  @_chart_html_wrap
291
- def kplot(kdata: KData):
401
+ def kplot(kdata: KData, ind_main=None, ind_sub=None):
292
402
  kline = kplot_line(kdata)
403
+ if ind_main is not None:
404
+ if isinstance(ind_main, Indicator):
405
+ ind_main = [ind_main]
406
+ for ind in ind_main:
407
+ kline = iplot(ind, kdata, kline)
293
408
  vol_bar = volume_barplot(kdata)
409
+ if ind_sub is not None:
410
+ if isinstance(ind_sub, Indicator):
411
+ ind_sub = [ind_sub]
412
+ for ind in ind_sub:
413
+ vol_bar = iplot(ind, kdata, vol_bar)
294
414
  grid_chart = Grid()
295
415
  grid_chart.add_js_funcs("var barData = {}".format(_get_js_data_var(kdata)))
296
416
  grid_chart.add(
@@ -301,6 +421,8 @@ def kplot(kdata: KData):
301
421
  vol_bar,
302
422
  grid_opts=grid_pos[1],
303
423
  )
424
+ grid_chart.g1rootchart = kline
425
+ grid_chart.g2rootchart = vol_bar
304
426
  _brush_chart(kdata, grid_chart)
305
427
  return grid_chart
306
428
 
@@ -308,7 +430,7 @@ def kplot(kdata: KData):
308
430
  @_chart_html_wrap
309
431
  def sysplot(sys: System):
310
432
  kdata = sys.to
311
- datetimes = kdata.get_datetime_list()
433
+ datetimes = simple_datetime_list(kdata.get_datetime_list(), kdata.get_query().ktype)
312
434
  date_index = dict([(d, i) for i, d in enumerate(datetimes)])
313
435
 
314
436
  kline = kplot_line(kdata)
@@ -323,10 +445,12 @@ def sysplot(sys: System):
323
445
  sell_dates.append(t.datetime)
324
446
  else:
325
447
  pass
448
+ buy_dates = simple_datetime_list(buy_dates, kdata.get_query().ktype)
449
+ sell_dates = simple_datetime_list(sell_dates, kdata.get_query().ktype)
326
450
 
327
451
  buy_pos = []
328
452
  sell_pos = []
329
- closep = [d.close for d in kdata]
453
+ closep = [round(d.close, 2) for d in kdata]
330
454
  candle_gap = (max(closep) - min(closep)) * 0.05
331
455
 
332
456
  for d in buy_dates:
@@ -339,9 +463,6 @@ def sysplot(sys: System):
339
463
  continue
340
464
  sell_pos.append(kdata[date_index[d]].high + candle_gap)
341
465
 
342
- buy_dates = [str(dt) for dt in buy_dates]
343
- sell_dates = [str(dt) for dt in sell_dates]
344
-
345
466
  buy_scatter = (
346
467
  Scatter()
347
468
  .add_xaxis(buy_dates)
@@ -400,3 +521,77 @@ def sysplot(sys: System):
400
521
  )
401
522
  _brush_chart(kdata, grid_chart)
402
523
  return grid_chart
524
+
525
+
526
+ def sys_performance(sys, ref_stk=None):
527
+ if ref_stk is None:
528
+ ref_stk = get_stock('sh000300')
529
+
530
+ query = sys.query
531
+ sh000001_k = get_kdata('sh000001', query)
532
+ ref_dates = sh000001_k.get_datetime_list()
533
+
534
+ ref_k = ref_stk.get_kdata(query)
535
+
536
+ funds_list = sys.tm.get_funds_list(ref_dates)
537
+ funds = [f.total_assets for f in funds_list]
538
+ funds = VALUE(funds)
539
+ funds_return = [f.total_assets / f.total_base if f.total_base != 0.0 else constant.null_price for f in funds_list]
540
+ funds_return = VALUE(funds_return, align_dates=ref_dates)
541
+ funds_return.name = "系统累积收益率"
542
+ ref_return = ALIGN(ROCR(ref_k.close, 0), ref_dates)
543
+ ref_return.name = f"{ref_stk.name}({ref_stk.market_code})"
544
+
545
+ per = Performance()
546
+ text = per.report(sys.tm, sh000001_k[-1].datetime)
547
+
548
+ # 计算最大回撤
549
+ max_pullback = min(MDD(funds).to_np())
550
+
551
+ # 计算 sharp
552
+ bond = ZHBOND10(ref_dates)
553
+ sigma = STDEV(ROCP(funds), len(ref_dates))
554
+ sigma = 15.874507866387544 * sigma[-1] # 15.874 = sqrt(252)
555
+ sharp = (per['帐户平均年收益率%'] - bond[-1]) * 0.01 / sigma if sigma != 0.0 else 0.0
556
+
557
+ invest_total = per['累计投入本金'] + per['累计投入资产']
558
+ cur_fund = per['当前总资产']
559
+ t1 = '投入总资产: {:<.2f} 当前总资产: {:<.2f} 当前盈利: {:<.2f}'.format(
560
+ invest_total, cur_fund, cur_fund - invest_total)
561
+ t2 = '当前策略收益: {:<.2f}% 年化收益率: {:<.2f}% 最大回撤: {:<.2f}%'.format(
562
+ funds_return[-1]*100 - 100, per["帐户平均年收益率%"], max_pullback)
563
+ t3 = '系统胜率: {:<.2f}% 盈/亏比: 1 : {:<.2f} 夏普比率: {:<.2f}'.format(
564
+ per['赢利交易比例%'], per['净赢利/亏损比例'], sharp)
565
+
566
+ line = iplot(ref_return, ref_k)
567
+ line = iplot(funds_return, ref_k, line)
568
+ line.get_options().update(dataZoom=[
569
+ opts.DataZoomOpts(
570
+ is_show=len(ref_dates) > 500,
571
+ xaxis_index=0,
572
+ type_="slider",
573
+ pos_top="92%",
574
+ range_start=(100 - 500 * 100 / len(ref_dates)) if len(ref_dates) > 500 else 0,
575
+ range_end=100,
576
+ ),
577
+ ])
578
+
579
+ page = Page()
580
+ page.add(line)
581
+
582
+ tchart = MultiLineTextChart(opts.InitOpts(height='65px'))
583
+ tchart.add(t1, y = 5)
584
+ tchart.add(t2)
585
+ tchart.add(t3)
586
+ page.add(tchart)
587
+
588
+ txchart = MultiLineTextChart(opts.InitOpts(height='550px'))
589
+ tlines = text.splitlines()
590
+ tlcount = len(tlines)
591
+ for i in range(tlcount//2):
592
+ txchart.add(tlines[i])
593
+ txchart.reset_position(y=5)
594
+ for i in range(tlcount//2, tlcount):
595
+ txchart.add(tlines[i], x=400)
596
+ page.add(txchart)
597
+ return page