├── README.md ├── app.py ├── app.pyc ├── chan ├── __init__.py ├── chan_app.py ├── constant.py ├── db │ ├── dao.py │ ├── db_helper.py │ └── object.py ├── level.py ├── mapper.py ├── object.py ├── sequence.py ├── trade_manager.py ├── trend.py └── yanzheng_fenxing_handler.py ├── demo.jpeg ├── event ├── __init__.py └── engine.py ├── gateway ├── jq │ ├── __init__.py │ └── jq_gateway.py └── tq │ ├── __init__.py │ └── tq_gateway.py ├── jq ├── __init__.py ├── jq_test.py └── north_money_bool_band.py ├── mytushare ├── __init__.py ├── api.py ├── api2.py └── cache.sqlite ├── requirements.txt ├── sina ├── __init__.py ├── __init__.pyc ├── api.py └── api.pyc ├── static ├── data.json ├── key.txt ├── kline.html └── pens.json ├── test ├── __init__.py ├── cache.sqlite └── test_pandas_datareader.py ├── tools ├── __init__.py ├── __init__.pyc ├── time_tools.py └── time_tools.pyc ├── trader ├── __init__.py ├── constant.py ├── event.py ├── gateway.py └── object.py ├── web ├── __init__.py ├── encoder │ ├── __init__.py │ └── alchemy_encoder.py └── web_app.py └── yahoo ├── __init__.py ├── __init__.pyc ├── api.py └── api.pyc /README.md: -------------------------------------------------------------------------------- 1 | # ChanMaster 2 | 缠论量化 3 | 4 | 自动分型、严格笔、同级别分解、线段、中枢 5 | 6 | 7 |  8 | 9 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | import os 3 | if os.path.exists("/tmp/ChanMaster/chan.db"): 4 | os.remove("/tmp/ChanMaster/chan.db") 5 | 6 | import logging 7 | 8 | from chan.chan_app import ChanApp 9 | from chan.level import FiveMinuteLevel, OneMinuteLevel 10 | from gateway.jq.jq_gateway import JQGateway 11 | from gateway.tq.tq_gateway import TQGateway 12 | from trader.constant import Exchange 13 | 14 | __author__ = "hanweiwei" 15 | __date__ = "2018/10/24" 16 | 17 | app_log = logging.getLogger("app") 18 | app_log.setLevel(logging.INFO) 19 | handler = logging.StreamHandler(stream=None) 20 | formatter = logging.Formatter('%(asctime)s %(filename)s : %(levelname)s %(message)s') # 定义该handler格式 21 | handler.setFormatter(formatter) 22 | app_log.addHandler(handler) 23 | 24 | if __name__ == '__main__': 25 | 26 | 27 | chan_app = ChanApp(FiveMinuteLevel(), JQGateway, Exchange.AGU, "603568.XSHG") 28 | chan_app.start() 29 | -------------------------------------------------------------------------------- /app.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kymeii/ChanMaster/b25661ee1d69b756abcbe60e97a8d7c84fcad009/app.pyc -------------------------------------------------------------------------------- /chan/__init__.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | __author__ = "hanweiwei" 4 | __date__ = "2018/10/25" -------------------------------------------------------------------------------- /chan/chan_app.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from datetime import datetime 3 | from typing import List 4 | 5 | from chan.level import Level 6 | from chan.object import ChanBarData, Pen, YanZhengFenxing, DerivePen 7 | from chan.trend import BaseTrend 8 | from chan.yanzheng_fenxing_handler import YanZhengFenxingHandler 9 | from event.engine import EventEngine, Event 10 | from tools import time_tools 11 | from trader.constant import Exchange, Interval 12 | from trader.event import EVENT_BAR 13 | from trader.gateway import BaseGateway 14 | from trader.object import KLineRequest, BarData, SubscribeBarRequest 15 | 16 | __author__ = "hanweiwei" 17 | __date__ = "2018/10/25" 18 | 19 | 20 | class SubTrend(BaseTrend): 21 | def __init__(self, interval: Interval, parent_trend): 22 | super().__init__(interval, parent_trend) 23 | 24 | def _handle_pens(self): 25 | if len(self.pens): 26 | cur = self.pens[-1] 27 | last_fenxing = cur.end_fenxing 28 | elif len(self.fenxings) > 2: 29 | last_fenxing = self.fenxings[0] 30 | else: 31 | # 分型不够 32 | return 33 | index = last_fenxing.index + 1 34 | while index < len(self.fenxings): 35 | 36 | cur_fenxing = self.fenxings[index] 37 | if last_fenxing.is_top == cur_fenxing.is_top: 38 | # 同向分型 ,看是否需要修正笔 39 | if last_fenxing.is_top and cur_fenxing.extreme_bar.include_high > last_fenxing.extreme_bar.include_high \ 40 | or \ 41 | not last_fenxing.is_top and cur_fenxing.extreme_bar.include_low < last_fenxing.extreme_bar.include_low: 42 | self._fix_pen() 43 | # 修正笔,重置last_fenxing 44 | if len(self.pens): 45 | cur = self.pens[-1] 46 | last_fenxing = cur.end_fenxing 47 | elif last_fenxing.index + 1 < len(self.fenxings): 48 | last_fenxing = self.fenxings[last_fenxing.index + 1] 49 | else: 50 | # 分型不够 51 | return 52 | index = last_fenxing.index + 1 53 | continue 54 | 55 | if self._is_fenxing_match(last_fenxing.index, cur_fenxing.index): 56 | pen = Pen(len(self.pens), last_fenxing, cur_fenxing, cur_fenxing.is_top) 57 | self.pens.append(pen) 58 | # print("new pen %s -> %s", pen.start_bar_index(), pen.end_bar_index()) 59 | self.pen_dao.insert(pen) 60 | self._handle_segments(False) 61 | self._handle_centre() 62 | # 新的笔产生,重置last_fenxing 63 | last_fenxing = cur_fenxing 64 | index = cur_fenxing.index + 1 65 | 66 | def _fix_pen(self): 67 | while self.pens: 68 | # 修正笔 69 | last_pen = self.pens[-1] 70 | for i in range(last_pen.end_fenxing.index + 1, len(self.fenxings)): 71 | if self._is_fenxing_match(last_pen.start_fenxing.index, i): 72 | last_pen_end_bar_index_before = last_pen.end_bar_index() 73 | last_pen.end_fenxing = self.fenxings[i] 74 | self.pen_dao.insert(self.pens[-1]) 75 | # print("fix pen %s %s,%s -> %s,%s" % (last_pen.index, 76 | # self.pens[-1].start_bar_index(), last_pen_end_bar_index_before, 77 | # self.pens[-1].start_bar_index(), 78 | # self.pens[-1].end_bar_index())) 79 | self._handle_segments(True) 80 | self._handle_centre() 81 | return True 82 | 83 | # print("delete pen", last_pen.index, last_pen.start_bar_index(), last_pen.end_bar_index()) 84 | self.pens.remove(last_pen) 85 | self.pen_dao.delete(last_pen) 86 | return False 87 | 88 | def _is_fenxing_match(self, start: int, end: int): 89 | 90 | # if end - start == 1: 91 | # # 次级别要有结构 92 | # return False 93 | start_fenxing = self.fenxings[start] 94 | end_fenxing = self.fenxings[end] 95 | 96 | # 满足5根k线否 97 | start_fenxing_end_bar_index = self.bars[start_fenxing.extreme_bar.end_index() + 1].end_index() 98 | end_fenxing_start_bar_index = self.bars[end_fenxing.extreme_bar.start_index() - 1].start_index() 99 | if end_fenxing_start_bar_index - start_fenxing_end_bar_index < 2: 100 | # 不满足5根k线 101 | return False 102 | 103 | # end 是不是start分型与end分型之间的极值分型 104 | # 找出极值分型, 以及回荡深度,为次高点成笔做准备 105 | highest = start_fenxing.extreme_bar.include_high # 记录遍利过的最高点 106 | lowest = start_fenxing.extreme_bar.include_low # 记录遍历过的最低点 107 | highest_fenxing = start_fenxing 108 | lowest_fenxing = start_fenxing 109 | 110 | secondary_back_deep = 0 # 次高点成笔回荡深度 111 | for i in range(start + 1, end + 1): 112 | cur = self.fenxings[i] 113 | if cur.is_top == start_fenxing.is_top and secondary_back_deep < 0.5: 114 | if start_fenxing.is_top: 115 | secondary_back_deep = (cur.extreme_bar.include_high - lowest) / (highest - lowest) 116 | else: 117 | secondary_back_deep = (highest - cur.extreme_bar.include_low) / (highest - lowest) 118 | 119 | if cur.is_top and highest < cur.extreme_bar.include_high: 120 | highest = cur.extreme_bar.include_high 121 | highest_fenxing = cur 122 | elif not cur.is_top and lowest > cur.extreme_bar.include_low: 123 | lowest = cur.extreme_bar.include_low 124 | lowest_fenxing = cur 125 | 126 | if start_fenxing.is_top and highest_fenxing != start_fenxing \ 127 | or \ 128 | not start_fenxing.is_top and lowest_fenxing != start_fenxing: 129 | return False 130 | 131 | # end分型是极值分型,可以直接成笔 132 | if start_fenxing.is_top and lowest_fenxing == end_fenxing \ 133 | or \ 134 | not start_fenxing.is_top and highest_fenxing == end_fenxing: 135 | return True 136 | 137 | # 回荡深度超过50%,不满足次高点成笔 138 | if secondary_back_deep > 0: 139 | return False 140 | # 次高点成笔,满足4根k线否 141 | if start_fenxing.is_top: 142 | extreme_fenxing = lowest_fenxing 143 | else: 144 | extreme_fenxing = highest_fenxing 145 | extreme_fenxing_start_bar_index = self.bars[extreme_fenxing.bar_index - 1].include_index 146 | if extreme_fenxing_start_bar_index - start_fenxing_end_bar_index < 1: 147 | # 次高点成笔不足4根k线 148 | return True 149 | else: 150 | # 次高点成笔 151 | return True 152 | 153 | 154 | class Trend(BaseTrend): 155 | def __init__(self, interval: Interval, parent_trend): 156 | super().__init__(interval, parent_trend) 157 | self.pens: List[Pen] = [] 158 | self.bars: List[ChanBarData] = [] 159 | self.yanzheng_fenxing_handler: YanZhengFenxingHandler = None 160 | 161 | def _on_derive_pen(self, start_datetime: datetime, end_datetime: datetime, is_rise: bool): 162 | # 需要修正,推笔不能用分型来表示,应该严格定义到那根K线上 163 | if self.interval == Interval.MINUTE_5: 164 | start_datetime = time_tools.m1_2_m5(start_datetime) 165 | end_datetime = time_tools.m1_2_m5(end_datetime) 166 | elif self.interval == Interval.MINUTE_30: 167 | print("30m pend %s %s" % (start_datetime, end_datetime)) 168 | start_datetime = time_tools.m5_2_m30(start_datetime) 169 | end_datetime = time_tools.m5_2_m30(end_datetime) 170 | print("30m pend %s %s" % (start_datetime, end_datetime)) 171 | 172 | start_bar = None 173 | end_bar = None 174 | for i in range(len(self.bars) - 1, -1, -1): 175 | bar = self.bars[i] 176 | if bar.datetime < start_datetime: 177 | break 178 | if bar.datetime == end_datetime: 179 | end_bar = bar 180 | if bar.datetime == start_datetime: 181 | start_bar = bar 182 | if start_bar and end_bar: 183 | pen = DerivePen(index=len(self.pens), _start_bar=start_bar, _end_bar=end_bar, 184 | is_rise=is_rise) 185 | self.pens.append(pen) 186 | self.pen_dao.insert(pen) 187 | self._handle_segments(False) 188 | self.on_new_pen() 189 | else: 190 | # print(start_datetime, end_datetime) 191 | pass 192 | self._handle_centre() 193 | 194 | def on_bar(self, bar: BarData): 195 | super(Trend, self).on_bar(bar) 196 | if self.yanzheng_fenxing_handler: 197 | self.yanzheng_fenxing_handler.on_new_bar(self.bars[-1]) 198 | 199 | def on_new_fenxing(self): 200 | if self.yanzheng_fenxing_handler: 201 | self.yanzheng_fenxing_handler.on_new_fenxing(self.fenxings[-1]) 202 | 203 | def on_new_pen(self): 204 | # 验证分型处理器更新 205 | self.yanzheng_fenxing_handler = YanZhengFenxingHandler() 206 | # self.yanzheng_fenxing_handler.init(self) 207 | 208 | def on_yanzheng_fenxing_success(self, yanzheng_fenxing: YanZhengFenxing): 209 | last_pen = self.pens[-1] 210 | if yanzheng_fenxing.extreme_fenxing.is_top and yanzheng_fenxing.extreme_fenxing.extreme_bar.include_high > last_pen.high(): 211 | print("二卖", yanzheng_fenxing.confirm_bar.index, "开仓价", yanzheng_fenxing.confirm_bar.close_price, 212 | "止损价", yanzheng_fenxing.loss_price) 213 | elif not yanzheng_fenxing.extreme_fenxing.is_top and yanzheng_fenxing.extreme_fenxing.extreme_bar.include_low > last_pen.low(): 214 | print("二买", yanzheng_fenxing.confirm_bar.index, "开仓价", yanzheng_fenxing.confirm_bar.close_price, 215 | "止损价", yanzheng_fenxing.loss_price) 216 | 217 | 218 | class ChanApp(object): 219 | """ 220 | 做本级别线段 221 | 使用次级别严格笔,推出本级别笔,再推出本级别的中枢和线段 222 | """ 223 | 224 | def __init__(self, level: Level, gateway: type, exchange: Exchange, symbol: str): 225 | """ 226 | 227 | :param level: 228 | :param gateway: 229 | :param exchange: 230 | :param symbol: 231 | """ 232 | self._level = level 233 | self._exchange = exchange 234 | self._symbol = symbol 235 | self._parent_trend = Trend(self._level.get_parent_level(), None) 236 | self._trend = Trend(self._level.get_level(), self._parent_trend) 237 | self._child_trend = SubTrend(self._level.get_child_level(), self._trend) 238 | self._event_engine = EventEngine() 239 | self._gateway: BaseGateway = gateway(self._event_engine) 240 | 241 | def init(self): 242 | init_start_time = time_tools.timestamp() 243 | 244 | sub_klines = 8000 245 | request = KLineRequest(self._symbol, self._exchange, self._level.get_parent_level(), int(sub_klines / 5 / 5)) 246 | bars = self._gateway.get_kline_data(request) 247 | self._parent_trend.init_bars(bars) 248 | 249 | request = KLineRequest(self._symbol, self._exchange, self._level.get_level(), int(sub_klines / 5)) 250 | bars = self._gateway.get_kline_data(request) 251 | self._trend.init_bars(bars) 252 | 253 | request = KLineRequest(self._symbol, self._exchange, self._level.get_child_level(), sub_klines) 254 | bars = self._gateway.get_kline_data(request) 255 | self._child_trend.init_bars(bars) 256 | init_end_time = time_tools.timestamp() 257 | print("init total time %s" % (init_end_time - init_start_time)) 258 | 259 | def start(self): 260 | self.init() 261 | 262 | print("init bar finish") 263 | self._event_engine.register(EVENT_BAR, self.on_bar) 264 | self._event_engine.start() 265 | 266 | self._gateway.subscribe_bar( 267 | SubscribeBarRequest(symbol=self._symbol, exchange=self._exchange, interval=self._level.get_child_level())) 268 | 269 | self._gateway.subscribe_bar( 270 | SubscribeBarRequest(symbol=self._symbol, exchange=self._exchange, interval=self._level.get_level())) 271 | 272 | self._gateway.subscribe_bar( 273 | SubscribeBarRequest(symbol=self._symbol, exchange=self._exchange, interval=self._level.get_parent_level())) 274 | self._gateway.connect(None) 275 | 276 | def on_bar(self, event: Event): 277 | bar: BarData = event.data 278 | # print(bar) 279 | if bar.interval == self._level.get_level(): 280 | self._trend.on_bar(bar) 281 | elif bar.interval == self._level.get_child_level(): 282 | self._child_trend.on_bar(bar) 283 | elif bar.interval == self._level.get_parent_level(): 284 | self._parent_trend.on_bar(bar) 285 | 286 | # dataframe_60 = getKLineData("600887.SS", scale=MINUTE_60, start_date="20181010", end_date="20181118") 287 | # dataframe_60 = getKLineData("SH603019", scale=MINUTE_60, count=len(dataframe) / 12) 288 | # handle_include(dataframe_60) 289 | # handle_fenxing(dataframe_60) 290 | # pens_60 = handle_pen(dataframe_60) 291 | # if pens_60: 292 | # print dataframe_60.ix[pens_60[0]["start"]] 293 | 294 | # app_log.info("处理数据完毕:%s", datetime.datetime.now()) 295 | # 296 | # json_str = dataframe.to_json(orient="records") 297 | # data = encoder.loads(json_str) 298 | # data = {"kline": data, "pens": pens} 299 | # with open("../static/data.encoder", "w") as fp: 300 | # encoder.dump(data, fp) 301 | # fp.close() 302 | # # break 303 | # time.sleep(60) 304 | 305 | # plt.figure() 306 | # pl = dataframe.plot.box() 307 | # plt.show() 308 | -------------------------------------------------------------------------------- /chan/constant.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from enum import Enum 3 | 4 | __author__ = "hanweiwei" 5 | __date__ = "2019-06-02" 6 | 7 | 8 | -------------------------------------------------------------------------------- /chan/db/dao.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from typing import List 3 | 4 | from chan.db.db_helper import get_session 5 | from chan.db.object import PenDO, ChanBarDataDO, CentreDO 6 | from chan.mapper import ChanBarDataMP, PenMP, CentreMP 7 | from chan.object import ChanBarData, Pen, Centre 8 | 9 | __author__ = "hanweiwei" 10 | __date__ = "2019-06-06" 11 | 12 | 13 | class ChanBarDataDao(): 14 | 15 | def __init__(self): 16 | self.chan_bar_data_mp = ChanBarDataMP() 17 | 18 | def insert(self, chan_bar_data: ChanBarData): 19 | chan_bar_data_do = self.chan_bar_data_mp.mapper(chan_bar_data) 20 | 21 | # 创建session对象: 22 | session = get_session() 23 | # 添加到session: 24 | session.merge(chan_bar_data_do) 25 | # 提交即保存到数据库: 26 | session.commit() 27 | # 关闭session: 28 | session.close() 29 | 30 | def select(self, gateway, exchange, symbol, interval, limit): 31 | session = get_session() 32 | bars: List = session.query(ChanBarDataDO) \ 33 | .filter(ChanBarDataDO.gateway == gateway) \ 34 | .filter(ChanBarDataDO.exchange == exchange) \ 35 | .filter(ChanBarDataDO.symbol == symbol) \ 36 | .filter(ChanBarDataDO.interval == interval) \ 37 | .order_by(ChanBarDataDO.datetime.desc()) \ 38 | .limit(limit) \ 39 | .all() 40 | session.close() 41 | bars.reverse() 42 | return bars 43 | 44 | 45 | class PenDao(): 46 | 47 | def __init__(self): 48 | self.pen_mp = PenMP() 49 | 50 | def insert(self, pen: Pen): 51 | pen_do = self.pen_mp.mapper(pen) 52 | 53 | # 创建session对象: 54 | session = get_session() 55 | # 添加到session: 56 | 57 | old_pen = session.query(PenDO) \ 58 | .filter(PenDO.gateway == pen_do.gateway) \ 59 | .filter(PenDO.exchange == pen_do.exchange) \ 60 | .filter(PenDO.symbol == pen_do.symbol) \ 61 | .filter(PenDO.interval == pen_do.interval) \ 62 | .filter(PenDO.start_datetime == pen_do.start_datetime) \ 63 | .first() 64 | if old_pen: 65 | session.delete(old_pen) 66 | session.add(pen_do) 67 | # 提交即保存到数据库: 68 | session.commit() 69 | # 关闭session: 70 | session.close() 71 | 72 | def select(self, gateway, exchange, symbol, interval, start_time): 73 | session = get_session() 74 | pens: List[PenDO] = session.query(PenDO) \ 75 | .filter(PenDO.gateway == gateway) \ 76 | .filter(PenDO.exchange == exchange) \ 77 | .filter(PenDO.symbol == symbol) \ 78 | .filter(PenDO.interval == interval) \ 79 | .filter(PenDO.start_datetime >= start_time) \ 80 | .all() 81 | session.close() 82 | return pens 83 | 84 | def delete(self, pen: Pen): 85 | pen_do = self.pen_mp.mapper(pen) 86 | 87 | # 创建session对象: 88 | session = get_session() 89 | # 添加到session: 90 | 91 | old_pen = session.query(PenDO) \ 92 | .filter(PenDO.gateway == pen_do.gateway) \ 93 | .filter(PenDO.exchange == pen_do.exchange) \ 94 | .filter(PenDO.symbol == pen_do.symbol) \ 95 | .filter(PenDO.interval == pen_do.interval) \ 96 | .filter(PenDO.start_datetime == pen_do.start_datetime) \ 97 | .first() 98 | if old_pen: 99 | session.delete(old_pen) 100 | # 提交即保存到数据库: 101 | session.commit() 102 | # 关闭session: 103 | session.close() 104 | 105 | 106 | class CentreDao(): 107 | 108 | def __init__(self): 109 | self.centre_mp = CentreMP() 110 | 111 | def insert(self, centre: Centre): 112 | centre_do = self.centre_mp.mapper(centre) 113 | 114 | # 创建session对象: 115 | session = get_session() 116 | # 添加到session: 117 | 118 | old_centre = session.query(CentreDO) \ 119 | .filter(CentreDO.gateway == centre_do.gateway) \ 120 | .filter(CentreDO.exchange == centre_do.exchange) \ 121 | .filter(CentreDO.symbol == centre_do.symbol) \ 122 | .filter(CentreDO.interval == centre_do.interval) \ 123 | .filter(CentreDO.start_datetime == centre_do.start_datetime) \ 124 | .first() 125 | if old_centre: 126 | session.delete(old_centre) 127 | session.add(centre_do) 128 | # 提交即保存到数据库: 129 | session.commit() 130 | # 关闭session: 131 | session.close() 132 | 133 | def select(self, gateway, exchange, symbol, interval, start_time): 134 | session = get_session() 135 | centres: List[CentreDO] = session.query(CentreDO) \ 136 | .filter(CentreDO.gateway == gateway) \ 137 | .filter(CentreDO.exchange == exchange) \ 138 | .filter(CentreDO.symbol == symbol) \ 139 | .filter(CentreDO.interval == interval) \ 140 | .filter(CentreDO.start_datetime >= start_time) \ 141 | .all() 142 | session.close() 143 | return centres 144 | -------------------------------------------------------------------------------- /chan/db/db_helper.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from sqlalchemy import create_engine, MetaData 3 | from sqlalchemy.orm import sessionmaker, Session 4 | 5 | from chan.db.object import Base, BaseDO 6 | 7 | __author__ = "hanweiwei" 8 | __date__ = "2019-06-06" 9 | 10 | # 初始化数据库连接: 11 | engine = create_engine('sqlite:////tmp/ChanMaster/chan.db', echo=False) 12 | BaseDO.metadata.create_all(engine) 13 | # 创建DBSession类型: 14 | DBSession = sessionmaker(bind=engine) 15 | 16 | 17 | # 创建DBSession类型: 18 | 19 | 20 | def get_session(): 21 | """ 22 | :rtype : Session 23 | :return: 24 | """ 25 | return DBSession() 26 | -------------------------------------------------------------------------------- /chan/db/object.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | from sqlalchemy import Column, String, INT, FLOAT, DATETIME, BOOLEAN 4 | from sqlalchemy.ext.declarative import declarative_base 5 | 6 | __author__ = "hanweiwei" 7 | __date__ = "2019-06-03" 8 | 9 | 10 | class Base(object): 11 | pass 12 | # def to_json(self): 13 | # dict = self.__dict__ 14 | # if "_sa_instance_state" in dict: 15 | # del dict["_sa_instance_state"] 16 | # return dict 17 | 18 | 19 | # 创建对象的基类: 20 | BaseDO = declarative_base(Base) 21 | 22 | 23 | # 定义User对象: 24 | class ChanBarDataDO(BaseDO): 25 | """ 26 | create table chan_bar_data 27 | ( 28 | gateway VARCHAR(10) not null, 29 | exchange VARCHAR(10) not null, 30 | symbol VARCHAR(10) not null, 31 | datetime DATETIME not null, 32 | interval VARCHAR(5) not null, 33 | volume INT, 34 | open_price FLOAT, 35 | close_price FLOAT, 36 | high_price FLOAT, 37 | low_price FLOAT, 38 | include_high FLOAT, 39 | include_low FLOAT, 40 | include_index INT, 41 | include_tail INT, 42 | primary key (gateway, exchange, symbol, datetime, interval) 43 | ) 44 | IF NOT EXISTS; 45 | """ 46 | 47 | # 表的名字: 48 | __tablename__ = 'chan_bar_data' 49 | 50 | # 表的结构: 51 | gateway = Column(String(10), primary_key=True) 52 | exchange = Column(String(10), primary_key=True) 53 | symbol = Column(String(10), primary_key=True) 54 | interval = Column(String(5), primary_key=True) 55 | datetime = Column(DATETIME, primary_key=True) 56 | volume = Column(INT) 57 | open_price = Column(FLOAT) 58 | close_price = Column(FLOAT) 59 | high_price = Column(FLOAT) 60 | low_price = Column(FLOAT) 61 | include_high = Column(FLOAT) 62 | include_low = Column(FLOAT) 63 | include_index = Column(INT) 64 | include_tail = Column(INT) 65 | 66 | 67 | class PenDO(BaseDO): 68 | __tablename__ = 'pen' 69 | 70 | # 表的结构: 71 | gateway = Column(String(10), primary_key=True) 72 | exchange = Column(String(10), primary_key=True) 73 | symbol = Column(String(10), primary_key=True) 74 | interval = Column(String(5), primary_key=True) 75 | start_datetime = Column(DATETIME, primary_key=True) 76 | end_datetime = Column(DATETIME, primary_key=True) 77 | is_rise = Column(BOOLEAN) 78 | 79 | 80 | class CentreDO(BaseDO): 81 | __tablename__ = 'centre' 82 | 83 | # 表的结构: 84 | gateway = Column(String(10), primary_key=True) 85 | exchange = Column(String(10), primary_key=True) 86 | symbol = Column(String(10), primary_key=True) 87 | interval = Column(String(5), primary_key=True) 88 | start_datetime = Column(DATETIME, primary_key=True) 89 | end_datetime = Column(DATETIME, primary_key=True) 90 | high = Column(FLOAT) 91 | low = Column(FLOAT) 92 | is_rise = Column(BOOLEAN) 93 | -------------------------------------------------------------------------------- /chan/level.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from trader.constant import Interval 3 | 4 | __author__ = "hanweiwei" 5 | __date__ = "2019-06-02" 6 | 7 | 8 | class Level(object): 9 | 10 | def get_level(self): 11 | raise NotImplementedError 12 | 13 | def get_child_level(self): 14 | raise NotImplementedError 15 | 16 | def get_parent_level(self): 17 | raise NotImplementedError 18 | 19 | def get_grand_level(self): 20 | raise NotImplementedError 21 | 22 | 23 | class ThirtyMinuteLevel(Level): 24 | """ 25 | 5分钟级别 26 | """ 27 | 28 | def get_level(self): 29 | return Interval.MINUTE_30 30 | 31 | def get_child_level(self): 32 | return Interval.MINUTE_5 33 | 34 | def get_parent_level(self): 35 | return Interval.DAILY 36 | 37 | def get_grand_level(self): 38 | return Interval.DAILY 39 | 40 | 41 | class FiveMinuteLevel(Level): 42 | """ 43 | 5分钟级别 44 | """ 45 | 46 | def get_level(self): 47 | return Interval.MINUTE_5 48 | 49 | def get_child_level(self): 50 | return Interval.MINUTE 51 | 52 | def get_parent_level(self): 53 | return Interval.MINUTE_30 54 | 55 | def get_grand_level(self): 56 | return Interval.DAILY 57 | 58 | 59 | class OneMinuteLevel(Level): 60 | 61 | def get_level(self): 62 | return Interval.MINUTE 63 | 64 | def get_child_level(self): 65 | return Interval.SECOND_10 66 | 67 | def get_parent_level(self): 68 | return Interval.MINUTE_5 69 | 70 | def get_grand_level(self): 71 | return Interval.MINUTE_30 72 | 73 | 74 | def parse_level(level): 75 | if level == "5m": 76 | return FiveMinuteLevel() 77 | elif level == "1m": 78 | return OneMinuteLevel() 79 | elif level == "30m": 80 | return ThirtyMinuteLevel() 81 | -------------------------------------------------------------------------------- /chan/mapper.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from chan.db.object import ChanBarDataDO, PenDO, CentreDO 3 | from chan.object import ChanBarData, Pen, Centre 4 | 5 | __author__ = "hanweiwei" 6 | __date__ = "2019-06-03" 7 | 8 | 9 | class ChanBarDataMP: 10 | 11 | def mapper(self, chan_bar_data: ChanBarData): 12 | """ 13 | 14 | :param chan_bar_data: 15 | :rtype :ChanBarDataDO 16 | :return: 17 | """ 18 | return ChanBarDataDO( 19 | gateway=chan_bar_data.gateway_name, 20 | exchange=chan_bar_data.exchange.value, 21 | symbol=chan_bar_data.symbol, 22 | datetime=chan_bar_data.datetime, 23 | interval=chan_bar_data.interval.value, 24 | volume=chan_bar_data.volume, 25 | open_price=chan_bar_data.open_price, 26 | close_price=chan_bar_data.close_price, 27 | high_price=chan_bar_data.high_price, 28 | low_price=chan_bar_data.low_price, 29 | include_high=chan_bar_data.include_high, 30 | include_low=chan_bar_data.include_low, 31 | include_index=chan_bar_data.include_index, 32 | include_tail=chan_bar_data.include_tail 33 | ) 34 | 35 | 36 | class PenMP: 37 | 38 | def mapper(self, pen: Pen): 39 | """ 40 | 41 | :param pen: 42 | :rtype :PenDO 43 | :return: 44 | """ 45 | return PenDO( 46 | gateway=pen.start_bar().gateway_name, 47 | exchange=pen.start_bar().exchange.value, 48 | symbol=pen.start_bar().symbol, 49 | interval=pen.start_bar().interval.value, 50 | start_datetime=pen.start_bar().datetime, 51 | end_datetime=pen.end_bar().datetime, 52 | is_rise=pen.is_rise 53 | ) 54 | 55 | 56 | class CentreMP: 57 | 58 | def mapper(self, centre: Centre): 59 | """ 60 | 61 | :param centre: 62 | :rtype :CentreDO 63 | :return: 64 | """ 65 | return CentreDO( 66 | gateway=centre.start_pen.start_bar().gateway_name, 67 | exchange=centre.start_pen.start_bar().exchange.value, 68 | symbol=centre.start_pen.start_bar().symbol, 69 | interval=centre.start_pen.start_bar().interval.value, 70 | start_datetime=centre.start_pen.start_bar().datetime, 71 | end_datetime=centre.end_pen.end_bar().datetime, 72 | is_rise=centre.is_rise, 73 | high=centre.high, 74 | low=centre.low 75 | ) 76 | -------------------------------------------------------------------------------- /chan/object.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from dataclasses import dataclass 3 | 4 | from trader.object import BarData 5 | 6 | __author__ = "hanweiwei" 7 | __date__ = "2019-06-02" 8 | 9 | 10 | @dataclass 11 | class ChanBarData(BarData): 12 | index: int = 0 13 | include_high: float = 0 14 | include_low: float = 0 15 | include_index: int = -1 16 | include_tail: int = -1 17 | 18 | def is_include(self): 19 | return self.include_index != -1 20 | 21 | def start_index(self): 22 | if self.is_include(): 23 | return self.include_index 24 | else: 25 | return self.index 26 | 27 | def end_index(self): 28 | if self.is_include(): 29 | return self.include_tail 30 | else: 31 | return self.index 32 | 33 | 34 | @dataclass 35 | class Fenxing(object): 36 | index: int = 0 37 | is_top: bool = False # 是否顶分 38 | extreme_bar: ChanBarData = None 39 | bar_index: int = 0 40 | start_bar: ChanBarData = None 41 | end_bar: ChanBarData = None 42 | 43 | 44 | @dataclass 45 | class BasePen(object): 46 | def start_bar(self): 47 | raise NotImplementedError 48 | 49 | def end_bar(self): 50 | raise NotImplementedError 51 | 52 | def high(self): 53 | raise NotImplementedError 54 | 55 | def low(self): 56 | raise NotImplementedError 57 | 58 | 59 | @dataclass 60 | class Pen(BasePen): 61 | index: int 62 | start_fenxing: Fenxing 63 | end_fenxing: Fenxing 64 | is_rise: bool 65 | 66 | def start_bar(self): 67 | return self.start_fenxing.extreme_bar 68 | 69 | def start_bar_index(self): 70 | return self.start_fenxing.bar_index 71 | 72 | def end_bar(self): 73 | return self.end_fenxing.extreme_bar 74 | 75 | def end_bar_index(self): 76 | return self.end_fenxing.bar_index 77 | 78 | def high(self): 79 | if self.is_rise: 80 | return self.end_bar().include_high 81 | else: 82 | return self.start_bar().include_high 83 | 84 | def low(self): 85 | if self.is_rise: 86 | return self.start_bar().include_low 87 | else: 88 | return self.end_bar().include_low 89 | 90 | 91 | @dataclass 92 | class DerivePen(BasePen): 93 | index: int 94 | _start_bar: ChanBarData 95 | _end_bar: ChanBarData 96 | is_rise: bool = False 97 | 98 | def start_bar(self): 99 | return self._start_bar 100 | 101 | def end_bar(self): 102 | return self._end_bar 103 | 104 | def high(self): 105 | if self.is_rise: 106 | return self.end_bar().include_high 107 | else: 108 | return self.start_bar().include_high 109 | 110 | def low(self): 111 | if self.is_rise: 112 | return self.start_bar().include_low 113 | else: 114 | return self.end_bar().include_low 115 | 116 | 117 | @dataclass 118 | class Divider(object): 119 | """ 120 | 同级别分界线 121 | """ 122 | last_pen: Pen 123 | confirm_pen: Pen 124 | 125 | 126 | @dataclass 127 | class Centre(object): 128 | """ 129 | 中枢 130 | """ 131 | 132 | high: float # 中枢上边界 133 | low: float # 中枢下边界 134 | is_rise: bool # 上涨中枢、下跌中枢 135 | start_pen: Pen # 起笔 136 | end_pen: Pen # 结束笔 137 | 138 | 139 | @dataclass 140 | class YanZhengFenxing(object): 141 | extreme_fenxing: Fenxing 142 | confirm_fenxing: Fenxing 143 | confirm_bar: ChanBarData 144 | loss_price: float 145 | invalid: bool = False # 验证分型是否已经失效 146 | 147 | def should_stop_loss(self, bar: BarData): 148 | return self.extreme_fenxing.is_top and bar.close_price > self.loss_price \ 149 | or \ 150 | not self.extreme_fenxing.is_top and bar.close_price < self.loss_price 151 | -------------------------------------------------------------------------------- /chan/sequence.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | __author__ = "hanweiwei" 4 | __date__ = "2019-06-09" 5 | 6 | 7 | class SignatureSequenceItem(object): 8 | """ 9 | 特征序列 10 | 11 | 12 | """ 13 | EXTEND = 1 # 延伸 14 | TURN = 2 # 转折 15 | INCLUDE = 3 # 包含 16 | 17 | def __init__(self, is_rise, extremum_pen_index, high, low): 18 | self.is_rise = is_rise 19 | self.extremum_pen_index = extremum_pen_index # 极值点笔索引。极值点:上升线段的最高点,下降线段的最低点 20 | # 高低点用作包含关系和分型的判断 21 | self.high = high # 高点 22 | self.low = low # 低点 23 | 24 | def __str__(self): 25 | return "is_rise:%s,extremum_pen_index:%s,high:%s,low:%s" % ( 26 | self.is_rise, self.extremum_pen_index, self.high, self.low) 27 | 28 | @classmethod 29 | def create_by_pen(cls, pen): 30 | """ 31 | :type pen:Pen 32 | :return: 33 | """ 34 | return SignatureSequenceItem(not pen.is_rise, pen.index, pen.high(), pen.low()) 35 | 36 | def grow(self, next_signature): 37 | """ 38 | 特征序列的生长 39 | 特征序列之间的二种关系: 40 | 延伸:沿着线段方向运行,可能有相互包含 41 | 转折:特征序列形成了分型,导致线段终结 42 | :type next_signature: SignatureSequenceItem 43 | :param next_signature: 44 | :return: relation, signature : 特征序列关系 和 极值特征序列 45 | """ 46 | if self.high < next_signature.high and self.low < next_signature.low and self.is_rise or \ 47 | self.high > next_signature.high and self.low > next_signature.low and not self.is_rise: 48 | # 延伸,没有包含 49 | relation = SignatureSequenceItem.EXTEND 50 | return relation, next_signature 51 | 52 | elif self.high < next_signature.high and self.low < next_signature.low and not self.is_rise or \ 53 | self.high > next_signature.high and self.low > next_signature.low and self.is_rise: 54 | # 直接转折 55 | relation = SignatureSequenceItem.TURN 56 | # if self.is_rise: 57 | return relation, self 58 | # else: 59 | # return relation, next_signature 60 | else: 61 | # 处于包含关系, 但也算延伸 62 | relation = SignatureSequenceItem.EXTEND 63 | if self.low <= next_signature.low and self.high >= next_signature.high: 64 | # 左包含右 65 | if self.is_rise: 66 | ret_signature = SignatureSequenceItem(self.is_rise, self.extremum_pen_index, 67 | self.high, 68 | next_signature.low) 69 | else: 70 | ret_signature = SignatureSequenceItem(self.is_rise, self.extremum_pen_index, 71 | next_signature.high, 72 | self.low) 73 | else: 74 | # if self.is_rise: 75 | ret_signature = next_signature 76 | # 笔破坏 77 | if self.is_rise: 78 | ret_signature = SignatureSequenceItem(self.is_rise, next_signature.extremum_pen_index, 79 | next_signature.high, 80 | self.low) 81 | else: 82 | ret_signature = SignatureSequenceItem(self.is_rise, next_signature.extremum_pen_index, 83 | self.high, 84 | next_signature.low) 85 | return relation, ret_signature 86 | -------------------------------------------------------------------------------- /chan/trade_manager.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | __author__ = "hanweiwei" 4 | __date__ = "2019-06-09" 5 | 6 | 7 | class TradeManager(object): 8 | 9 | def __init__(self): 10 | pass 11 | 12 | 13 | -------------------------------------------------------------------------------- /chan/trend.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from abc import abstractmethod 3 | from datetime import datetime 4 | from typing import List 5 | 6 | from chan.db.dao import ChanBarDataDao, CentreDao, PenDao 7 | from chan.object import ChanBarData, Fenxing, Divider, Centre, Pen, YanZhengFenxing 8 | from chan.sequence import SignatureSequenceItem 9 | from trader.constant import Interval 10 | from trader.object import BarData 11 | 12 | __author__ = "hanweiwei" 13 | __date__ = "2019-06-09" 14 | 15 | 16 | class BaseTrend(object): 17 | """ 18 | 走势 19 | """ 20 | 21 | def __init__(self, interval: Interval, parent_trend): 22 | """ 23 | 24 | :param parentTrend: 25 | :type parentTrend:BaseTrend 26 | """ 27 | self.interval = interval 28 | self.parent_trend: BaseTrend = parent_trend 29 | 30 | self.chan_bar_data_dao = ChanBarDataDao() 31 | self.pen_dao = PenDao() 32 | self.centre_dao = CentreDao() 33 | 34 | self.bars: List[ChanBarData] = [] 35 | self.fenxings: List[Fenxing] = [] 36 | self.pens: List[Pen] = [] 37 | self.dividers: List[Divider] = [] 38 | self.centres: List[Centre] = [] 39 | 40 | # 当前是否上涨趋势 41 | self.is_rise = True 42 | 43 | def init_bars(self, bars: List[BarData]): 44 | for index, bar in enumerate(bars): 45 | # if index > len(bars) / 2: 46 | # break 47 | self._append_bar(bar) 48 | 49 | def on_bar(self, bar: BarData): 50 | self._append_bar(bar) 51 | 52 | @abstractmethod 53 | def on_new_fenxing(self): 54 | pass 55 | 56 | @abstractmethod 57 | def on_new_pen(self): 58 | pass 59 | 60 | @abstractmethod 61 | def _on_derive_pen(self, start_datetime: datetime, end_datetime: datetime, is_rise: bool): 62 | 63 | """ 64 | 次级别推出本级别的笔 65 | :param pen: 66 | :return: 67 | """ 68 | 69 | @abstractmethod 70 | def _handle_pens(self): 71 | pass 72 | 73 | def _append_bar(self, bar: BarData): 74 | index = len(self.bars) 75 | row = ChanBarData(symbol=bar.symbol, exchange=bar.exchange, interval=bar.interval, datetime=bar.datetime, 76 | open_price=bar.open_price, high_price=bar.high_price, low_price=bar.low_price, 77 | close_price=bar.close_price, volume=bar.volume, gateway_name=bar.gateway_name, 78 | include_high=bar.high_price, include_low=bar.low_price, 79 | include_index=-1, include_tail=-1, index=index) 80 | if len(self.bars) > 2: 81 | last_index = index - 1 82 | last_row = self.bars[last_index] 83 | if last_row.is_include(): 84 | # 前一根K线也是包含, 找此包含关系的第一根K线的前一根K线 85 | last_last_row = self.bars[last_row.include_index - 1] 86 | else: 87 | last_last_row = self.bars[index - 2] 88 | before_include_after = (last_row.include_high >= row.high_price) and ( 89 | last_row.include_low <= row.low_price) 90 | after_include_before = (last_row.include_high <= row.high_price) and ( 91 | last_row.include_low >= row.low_price) 92 | if before_include_after: 93 | # 前包后 94 | if last_last_row.include_high > last_row.include_high: 95 | # 低低 96 | row.include_high = row.high_price 97 | row.include_low = last_row.include_low 98 | else: 99 | # 高高 100 | row.include_high = last_row.include_high 101 | row.include_low = row.low_price 102 | if last_row.is_include(): 103 | row.include_index = last_row.include_index 104 | else: 105 | row.include_index = last_index 106 | last_row.include_index = last_index 107 | for i in range(row.include_index, row.index): 108 | self.bars[i].include_low = row.include_low 109 | self.bars[i].include_high = row.include_high 110 | elif after_include_before: 111 | # 后包前 112 | if last_last_row.include_high > last_row.include_high: 113 | # 低低 114 | row.include_high = last_row.include_high 115 | row.include_low = row.low_price 116 | else: 117 | # 高高 118 | row.include_high = row.high_price 119 | row.include_low = last_row.include_low 120 | if last_row.is_include(): 121 | row.include_index = last_row.include_index 122 | else: 123 | row.include_index = last_index 124 | last_row.include_index = last_index 125 | for i in range(row.include_index, row.index): 126 | self.bars[i].include_low = row.include_low 127 | self.bars[i].include_high = row.include_high 128 | else: 129 | if last_row.is_include(): 130 | for i in range(last_index, last_row.include_index - 1, -1): 131 | _temp_row = self.bars[i] 132 | _temp_row.include_tail = last_index 133 | self.bars.append(row) 134 | self.chan_bar_data_dao.insert(row) 135 | self._handle_fenxing() 136 | 137 | def _handle_fenxing(self): 138 | index = len(self.bars) - 1 139 | cur = self.bars[len(self.bars) - 1] 140 | if cur.is_include(): 141 | # 有包含关系,所以这跟k线不会产生新的分型 142 | return 143 | else: 144 | last_index = index - 1 145 | if last_index < 0: 146 | return 147 | last = self.bars[last_index] 148 | 149 | if last.is_include(): 150 | # 取包含关系的第一根K线的前一根K线作为last 151 | last_last_index = last.include_index - 1 152 | else: 153 | last_last_index = last_index - 1 154 | if last_last_index < 0: 155 | return 156 | last_last = self.bars[last_last_index] 157 | 158 | if last_last.include_high > last.include_high and cur.include_high > last.include_high: 159 | # 底分型 160 | if last.is_include(): 161 | for i in range(last.start_index(), last.end_index() + 1): 162 | bar = self.bars[i] 163 | if bar.low_price == bar.include_low: 164 | extreme_bar = bar 165 | else: 166 | extreme_bar = last 167 | self.fenxings.append( 168 | Fenxing(index=len(self.fenxings), is_top=False, extreme_bar=extreme_bar, bar_index=extreme_bar.index, 169 | start_bar=last_last, end_bar=cur)) 170 | elif last_last.include_high < last.include_high and cur.include_high < last.include_high: 171 | # 顶分型 172 | if last.is_include(): 173 | for i in range(last.start_index(), last.end_index() + 1): 174 | bar = self.bars[i] 175 | if bar.high_price == bar.include_high: 176 | extreme_bar = bar 177 | else: 178 | extreme_bar = last 179 | self.fenxings.append( 180 | Fenxing(index=len(self.fenxings), is_top=True, extreme_bar=extreme_bar, bar_index=extreme_bar.index, 181 | start_bar=last_last, end_bar=cur)) 182 | else: 183 | # 有新的分型产生,才会产生新的笔 184 | return 185 | self._handle_pens() 186 | self.on_new_fenxing() 187 | 188 | def _handle_segments(self, has_fix_pen=False): 189 | """ 190 | 线段 191 | :return: 192 | """ 193 | if len(self.pens) < 3: return 194 | 195 | if has_fix_pen: 196 | while self.dividers: 197 | divider = self.dividers[-1] 198 | if self.pens[-1].index <= divider.confirm_pen.index: 199 | # 修正笔导致之前的线段划分失效 200 | self.dividers.remove(divider) 201 | continue 202 | break 203 | 204 | if self.dividers: 205 | divider = self.dividers[-1] 206 | # 为什么直接+4: 因为确认前一个同级别分界线时,新的线段至少已经走了三笔,可以直接从第四笔取特征序列来进行后续的判断 207 | signature_sequence_index = divider.confirm_pen.index + 1 208 | if signature_sequence_index >= len(self.pens): 209 | return 210 | start_pen = self.pens[divider.last_pen.index + 1] 211 | 212 | else: 213 | signature_sequence_index = 0 # 当前特征序列在pens列表中的索引 214 | current_pen = self.pens[signature_sequence_index] 215 | 216 | # 始终把初始走势当成上涨线段 217 | # 第一笔下跌,这一笔是特征序列的0号 218 | # 第一笔上涨,就把第二笔当作特征序列的0号,不管第一笔 219 | if current_pen.is_rise: 220 | # 第一笔上涨,就把第二笔当作特征序列的0号,不管第一笔 221 | # 第一笔就是线段的开始 222 | signature_sequence_index += 1 223 | start_pen = self.pens[0] 224 | else: 225 | # 第一笔下跌,把第二笔作为线段的开始 226 | start_pen = self.pens[signature_sequence_index + 1] 227 | current_pen = self.pens[signature_sequence_index] 228 | # print(current_pen.index) 229 | current_signature = SignatureSequenceItem.create_by_pen(current_pen) 230 | signature_sequence_index += 2 231 | while signature_sequence_index < len(self.pens): 232 | next_signature = SignatureSequenceItem.create_by_pen(self.pens[signature_sequence_index]) 233 | relation, ret_signature = current_signature.grow(next_signature) 234 | if self.interval == Interval.MINUTE_5: 235 | print(current_signature.extremum_pen_index, current_signature.high, current_signature.low, 236 | next_signature.extremum_pen_index, 237 | next_signature.high, next_signature.low, relation, 238 | ret_signature.extremum_pen_index) 239 | if relation == SignatureSequenceItem.EXTEND: 240 | # 线段的延伸 241 | current_signature = ret_signature 242 | signature_sequence_index += 2 243 | elif ret_signature == SignatureSequenceItem.INCLUDE: 244 | current_signature = ret_signature 245 | signature_sequence_index += 2 246 | else: 247 | # 线段的转折 248 | pen = self.pens[ret_signature.extremum_pen_index] 249 | divider = Divider(self.pens[pen.index - 1], confirm_pen=self.pens[signature_sequence_index]) 250 | self.dividers.append(divider) 251 | 252 | # 推笔 253 | if self.parent_trend: 254 | self.parent_trend._on_derive_pen(start_pen.start_bar().datetime, 255 | divider.last_pen.end_bar().datetime, 256 | ret_signature.is_rise) 257 | signature_sequence_index += 1 258 | if signature_sequence_index >= len(self.pens): 259 | break 260 | start_pen = self.pens[divider.last_pen.index + 1] 261 | current_signature = SignatureSequenceItem.create_by_pen(self.pens[signature_sequence_index]) # 特征序列的1号 262 | signature_sequence_index += 2 263 | 264 | def _handle_centre(self): 265 | """ 266 | 处理中枢 267 | :return: 268 | """ 269 | if len(self.pens) < 3: 270 | return 271 | if self.centres: 272 | cur_centre = self.centres[-1] 273 | cur_pen = self.pens[-1] 274 | if cur_pen.index - cur_centre.end_pen.index == 1: 275 | if not (cur_pen.high() < cur_centre.low or cur_pen.low() > cur_centre.high): 276 | # 中枢维持 277 | cur_centre.end_pen = cur_pen 278 | self.centre_dao.insert(cur_centre) 279 | return 280 | else: 281 | # 中枢破坏 282 | return 283 | elif cur_pen.index <= cur_centre.end_pen.index: 284 | # 没有产生新的笔,是修正笔 285 | # 最简单就是把这个中枢删掉,重新生成个中枢。 麻烦点,就去删掉之前中枢中的笔,重新确定中枢的属性。 286 | # 这里采用简单的方法 287 | self.centres.remove(cur_centre) 288 | 289 | # 新中枢判断 290 | if self.centres: 291 | cur_pen = self.pens[self.centres[-1].end_pen.index + 1] # 这个笔是出三买和三卖的笔 292 | else: 293 | cur_pen = self.pens[0] 294 | if cur_pen.is_rise: 295 | cur_pen = self.pens[1] 296 | 297 | new_centre = None 298 | cur_index = cur_pen.index 299 | next_index = cur_pen.index + 2 300 | while next_index < len(self.pens): 301 | cur_pen = self.pens[cur_index] 302 | next_pen = self.pens[next_index] 303 | if not (cur_pen.high() < next_pen.low() or cur_pen.low() > next_pen.high()): 304 | centre_low = cur_pen.low() if cur_pen.low() > next_pen.low() else next_pen.low() 305 | centre_high = cur_pen.high() if cur_pen.high() < next_pen.high() else next_pen.high() 306 | new_centre = Centre(high=centre_high, low=centre_low, is_rise=not cur_pen.is_rise, start_pen=cur_pen, 307 | end_pen=next_pen) 308 | self.centres.append(new_centre) 309 | self.centre_dao.insert(new_centre) 310 | break 311 | cur_index += 2 312 | next_index += 2 313 | 314 | # 产生了新中枢,去看中枢是否延伸 315 | if not new_centre: 316 | return 317 | cur_index = next_index + 1 318 | while cur_index < len(self.pens): 319 | cur_pen = self.pens[cur_index] 320 | if not (cur_pen.high() < new_centre.low or cur_pen.low() > new_centre.high): 321 | # 中枢维持 322 | new_centre.end_pen = cur_pen 323 | self.centre_dao.insert(new_centre) 324 | cur_index += 1 325 | continue 326 | break 327 | 328 | def on_yanzheng_fenxing_success(self, yanzheng_fenxing: YanZhengFenxing): 329 | pass 330 | -------------------------------------------------------------------------------- /chan/yanzheng_fenxing_handler.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | from typing import List 3 | 4 | from chan.object import Fenxing, YanZhengFenxing, ChanBarData 5 | from chan.trend import BaseTrend 6 | from trader.object import BarData 7 | 8 | __author__ = "hanweiwei" 9 | __date__ = "2019-06-09" 10 | 11 | 12 | class YanZhengFenxingHandler(object): 13 | """ 14 | 新产生一个极值点分型, 就有可能出多个验证分型 15 | """ 16 | trend: BaseTrend = None 17 | extreme_fenxing: Fenxing = None 18 | confirm_fenxing: Fenxing = None # 正在判定中的验证分型 19 | fenxing_pause: bool = False # 是否分型停顿 20 | complete_yanzheng_fenxings: List[YanZhengFenxing] = [] # 已完成的验证分型 21 | judge_price: float = 0 22 | 23 | def on_new_fenxing(self, fenxing: Fenxing): 24 | if not self.extreme_fenxing and self.trend.pens[-1].end_fenxing.is_top!=fenxing.is_top: 25 | self.extreme_fenxing= fenxing 26 | return 27 | if fenxing.is_top != self.extreme_fenxing.is_top: 28 | return 29 | if fenxing.is_top and fenxing.extreme_bar.include_high > self.extreme_fenxing.extreme_bar.include_high: 30 | self.extreme_fenxing = fenxing 31 | self.confirm_fenxing = None 32 | self.fenxing_pause = False 33 | elif not fenxing.is_top and fenxing.extreme_bar.include_low < self.extreme_fenxing.extreme_bar.include_low: 34 | self.extreme_fenxing = fenxing 35 | self.confirm_fenxing = None 36 | self.fenxing_pause = False 37 | else: 38 | if self.complete_yanzheng_fenxings: 39 | last_yanzheng_fenxing = self.complete_yanzheng_fenxings[-1] 40 | if last_yanzheng_fenxing.extreme_fenxing == self.extreme_fenxing and not last_yanzheng_fenxing.invalid: 41 | # 上一个验证分型未失效 42 | return 43 | 44 | self.confirm_fenxing = fenxing 45 | if self.fenxing_pause: 46 | # 1.分型停顿 + 验证分型 47 | if self.confirm_fenxing.is_top: 48 | loss_price = self.confirm_fenxing.extreme_bar.include_high 49 | else: 50 | loss_price = self.confirm_fenxing.extreme_bar.include_low 51 | yanzheng_fenxing = YanZhengFenxing(extreme_fenxing=self.extreme_fenxing, 52 | confirm_fenxing=self.confirm_fenxing, loss_price=loss_price, 53 | confirm_bar=self.confirm_fenxing.end_bar) 54 | self.complete_yanzheng_fenxings.append(yanzheng_fenxing) 55 | self.trend.on_yanzheng_fenxing_success(yanzheng_fenxing) 56 | self.confirm_fenxing = None 57 | else: 58 | if self.extreme_fenxing.is_top: 59 | extreme_fenxing_last_include_extreme_price = self.extreme_fenxing.end_bar.include_low 60 | else: 61 | extreme_fenxing_last_include_extreme_price = self.extreme_fenxing.end_bar.include_high 62 | # 计算穿越判据价格 63 | if self.extreme_fenxing.is_top: 64 | yanzheng_fenxing_last_include_extreme_price = self.confirm_fenxing.end_bar.include_low 65 | if yanzheng_fenxing_last_include_extreme_price < extreme_fenxing_last_include_extreme_price: 66 | self.judge_price = yanzheng_fenxing_last_include_extreme_price 67 | else: 68 | self.judge_price = extreme_fenxing_last_include_extreme_price 69 | else: 70 | yanzheng_fenxing_last_include_extreme_price = self.confirm_fenxing.end_bar.include_high 71 | if yanzheng_fenxing_last_include_extreme_price > extreme_fenxing_last_include_extreme_price: 72 | self.judge_price = yanzheng_fenxing_last_include_extreme_price 73 | else: 74 | self.judge_price = extreme_fenxing_last_include_extreme_price 75 | 76 | def on_new_bar(self, bar: ChanBarData): 77 | if not self.extreme_fenxing: 78 | return 79 | # 验证分型破坏止损 80 | if self.complete_yanzheng_fenxings and not self.complete_yanzheng_fenxings[-1].invalid: 81 | last_yanzheng_fenxing = self.complete_yanzheng_fenxings[-1] 82 | if last_yanzheng_fenxing.should_stop_loss(bar): 83 | self.complete_yanzheng_fenxings[-1].invalid = True 84 | 85 | if self.confirm_fenxing: 86 | # 2。验证分型和极值分型极值穿越判断 87 | if self.extreme_fenxing.is_top and bar.close_price < self.judge_price \ 88 | or \ 89 | not self.extreme_fenxing.is_top and bar.close_price > self.judge_price: 90 | # 验证分型和极值分型极值穿越判据成立,验证分型有效 91 | if self.confirm_fenxing.is_top: 92 | loss_price = self.confirm_fenxing.extreme_bar.include_high 93 | else: 94 | loss_price = self.confirm_fenxing.extreme_bar.include_low 95 | yanzheng_fenxing = YanZhengFenxing(extreme_fenxing=self.extreme_fenxing, 96 | confirm_fenxing=self.confirm_fenxing, loss_price=loss_price, 97 | confirm_bar=bar) 98 | self.complete_yanzheng_fenxings.append(yanzheng_fenxing) 99 | self.trend.on_yanzheng_fenxing_success(yanzheng_fenxing) 100 | self.confirm_fenxing = None 101 | 102 | self.judge_fenxing_pause(bar) 103 | 104 | def judge_fenxing_pause(self, bar): 105 | if not self.fenxing_pause: 106 | # 分型停顿判断 107 | # 计算极值分型的最后一根k线的极值 108 | if self.extreme_fenxing.is_top: 109 | extreme_fenxing_last_include_extreme_price = self.extreme_fenxing.end_bar.include_low 110 | else: 111 | extreme_fenxing_last_include_extreme_price = self.extreme_fenxing.end_bar.include_high 112 | if self.extreme_fenxing.is_top and bar.close_price < extreme_fenxing_last_include_extreme_price \ 113 | or \ 114 | not self.extreme_fenxing.is_top and bar.close_price > extreme_fenxing_last_include_extreme_price: 115 | # 分型停顿确认是验证分型有效 116 | self.fenxing_pause = True 117 | 118 | def init(self, trend: BaseTrend): 119 | self.trend = trend 120 | last_pen = self.trend.pens[-1] 121 | if last_pen.end_fenxing.index + 1 >= len(self.trend.fenxings): 122 | return 123 | extreme_fenxing = trend.fenxings[last_pen.end_fenxing.index + 1] 124 | self.extreme_fenxing = extreme_fenxing 125 | for i in range(last_pen.end_fenxing.index + 1, len(trend.fenxings)): 126 | fenxing = trend.fenxings[i] 127 | if fenxing.is_top != self.extreme_fenxing.is_top: 128 | continue 129 | if fenxing.is_top and fenxing.extreme_bar.include_high > self.extreme_fenxing.extreme_bar.include_high: 130 | self.extreme_fenxing = fenxing 131 | elif not fenxing.is_top and fenxing.extreme_bar.include_low < self.extreme_fenxing.extreme_bar.include_low: 132 | self.extreme_fenxing = fenxing 133 | for i in range(self.extreme_fenxing.end_bar.index + 1, len(trend.bars)): 134 | self.judge_fenxing_pause(trend.bars[i]) 135 | -------------------------------------------------------------------------------- /demo.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kymeii/ChanMaster/b25661ee1d69b756abcbe60e97a8d7c84fcad009/demo.jpeg -------------------------------------------------------------------------------- /event/__init__.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | __author__ = "hanweiwei" 4 | __date__ = "2019-06-08" -------------------------------------------------------------------------------- /event/engine.py: -------------------------------------------------------------------------------- 1 | """ 2 | Event-driven framework of vn.py framework. 3 | """ 4 | 5 | from collections import defaultdict 6 | from queue import Empty, Queue 7 | from threading import Thread 8 | from time import sleep 9 | from typing import Any, Callable 10 | 11 | EVENT_TIMER = "eTimer" 12 | 13 | 14 | class Event: 15 | """ 16 | Event object consists of a type string which is used 17 | by event engine for distributing event, and a data 18 | object which contains the real data. 19 | """ 20 | 21 | def __init__(self, type: str, data: Any = None): 22 | """""" 23 | self.type = type 24 | self.data = data 25 | 26 | 27 | # Defines handler function to be used in event engine. 28 | HandlerType = Callable[[Event], None] 29 | 30 | 31 | class EventEngine: 32 | """ 33 | Event engine distributes event object based on its type 34 | to those handlers registered. 35 | It also generates timer event by every interval seconds, 36 | which can be used for timing purpose. 37 | """ 38 | 39 | def __init__(self, interval: int = 1): 40 | """ 41 | Timer event is generated every 1 second by default, if 42 | interval not specified. 43 | """ 44 | self._interval = interval 45 | self._queue = Queue() 46 | self._active = False 47 | self._thread = Thread(target=self._run) 48 | self._timer = Thread(target=self._run_timer) 49 | self._handlers = defaultdict(list) 50 | self._general_handlers = [] 51 | 52 | def _run(self): 53 | """ 54 | Get event from queue and then process it. 55 | """ 56 | while self._active: 57 | try: 58 | event = self._queue.get(block=True, timeout=1) 59 | self._process(event) 60 | except Empty: 61 | pass 62 | 63 | def _process(self, event: Event): 64 | """ 65 | First ditribute event to those handlers registered listening 66 | to this type. 67 | Then distrubute event to those general handlers which listens 68 | to all types. 69 | """ 70 | if event.type in self._handlers: 71 | [handler(event) for handler in self._handlers[event.type]] 72 | 73 | if self._general_handlers: 74 | [handler(event) for handler in self._general_handlers] 75 | 76 | def _run_timer(self): 77 | """ 78 | Sleep by interval second(s) and then generate a timer event. 79 | """ 80 | while self._active: 81 | sleep(self._interval) 82 | event = Event(EVENT_TIMER) 83 | self.put(event) 84 | 85 | def start(self): 86 | """ 87 | Start event engine to process events and generate timer events. 88 | """ 89 | self._active = True 90 | self._thread.start() 91 | self._timer.start() 92 | 93 | def stop(self): 94 | """ 95 | Stop event engine. 96 | """ 97 | self._active = False 98 | self._timer.join() 99 | self._thread.join() 100 | 101 | def put(self, event: Event): 102 | """ 103 | Put an event object into event queue. 104 | """ 105 | self._queue.put(event) 106 | 107 | def register(self, type: str, handler: HandlerType): 108 | """ 109 | Register a new handler function for a specific event type. Every 110 | function can only be registered once for each event type. 111 | """ 112 | handler_list = self._handlers[type] 113 | if handler not in handler_list: 114 | handler_list.append(handler) 115 | 116 | def unregister(self, type: str, handler: HandlerType): 117 | """ 118 | Unregister an existing handler function from event engine. 119 | """ 120 | handler_list = self._handlers[type] 121 | 122 | if handler in handler_list: 123 | handler_list.remove(handler) 124 | 125 | if not handler_list: 126 | self._handlers.pop(type) 127 | 128 | def register_general(self, handler: HandlerType): 129 | """ 130 | Register a new handler function for all event types. Every 131 | function can only be registered once for each event type. 132 | """ 133 | if handler not in self._general_handlers: 134 | self._general_handlers.append(handler) 135 | 136 | def unregister_general(self, handler: HandlerType): 137 | """ 138 | Unregister an existing general handler function. 139 | """ 140 | if handler in self._general_handlers: 141 | self._general_handlers.remove(handler) -------------------------------------------------------------------------------- /gateway/jq/__init__.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | from __future__ import absolute_import 4 | 5 | __author__ = "hanweiwei" 6 | __date__ = "2020/10/13" -------------------------------------------------------------------------------- /gateway/jq/jq_gateway.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | import datetime 3 | from threading import Thread 4 | from typing import List 5 | 6 | from pandas import DataFrame 7 | 8 | from event.engine import EventEngine 9 | from trader.constant import Interval, Exchange, Direction, Offset 10 | from trader.gateway import BaseGateway 11 | from trader.object import KLineRequest, BarData, SubscribeBarRequest, OrderRequest 12 | 13 | OFFSET_DICT = { 14 | Offset.OPEN: "OPEN", 15 | Offset.CLOSE: "CLOSE", 16 | Offset.CLOSETODAY: "CLOSETODAY", 17 | } 18 | 19 | DIRECTION_DICT = { 20 | Direction.LONG: "BUY", 21 | Direction.SHORT: "SELL" 22 | } 23 | 24 | __author__ = "hanweiwei" 25 | __date__ = "2019-05-31" 26 | 27 | from tqsdk import api, TqSim, TqBacktest 28 | from jqdatasdk import * 29 | 30 | 31 | def _bar_interval_2_seconds(bar_interval): 32 | """ 33 | 34 | :param bar_interval: 35 | :return: 36 | """ 37 | if bar_interval == Interval.MINUTE: 38 | seconds = 60 39 | elif bar_interval == Interval.MINUTE_5: 40 | seconds = 300 41 | elif bar_interval == Interval.MINUTE_30: 42 | seconds = 1800 43 | elif bar_interval == Interval.HOUR: 44 | seconds = 3600 45 | elif bar_interval == Interval.DAILY: 46 | seconds = 3600 * 24 47 | elif bar_interval == Interval.WEEKLY: 48 | seconds = 3600 * 24 * 7 49 | else: 50 | raise ValueError("unknown bar interval %s" % bar_interval) 51 | return seconds 52 | 53 | 54 | def _direction(direction: Direction): 55 | return DIRECTION_DICT.get(direction) 56 | 57 | 58 | def _offset(offset: Offset): 59 | return OFFSET_DICT.get(offset) 60 | 61 | 62 | class JQGateway(BaseGateway): 63 | 64 | def __init__(self, event_engine: EventEngine): 65 | super().__init__(event_engine, "JQ") 66 | self._looper = Thread(target=self._run) 67 | 68 | self._bar_requests: List[SubscribeBarRequest] = [] 69 | self._bars_df: List[DataFrame] = [] 70 | auth("13516771087", "www1995com") 71 | 72 | def get_kline_data(self, kline_request: KLineRequest): 73 | exchange = kline_request.exchange 74 | interval = kline_request.bar_interval 75 | 76 | df = get_bars(kline_request.symbol, kline_request.data_length, unit=kline_request.bar_interval.value, 77 | fields=['date', 'open', 'high', 'low', 'close','volume'], 78 | include_now=False, end_dt=None, fq_ref_date=datetime.date.today(), df=True) 79 | data: List[BarData] = [] 80 | for ix, row in df.iterrows(): 81 | bar = self.dfrow2bar(exchange, kline_request.symbol, interval, row) 82 | data.append(bar) 83 | 84 | return data 85 | 86 | def dfrow2bar(self, exchange, symbol, interval, row): 87 | date = row["date"] 88 | if interval == Interval.MINUTE: 89 | date = date - datetime.timedelta(minutes=1) 90 | elif interval == Interval.MINUTE_5: 91 | date = date - datetime.timedelta(minutes=5) 92 | elif interval == Interval.MINUTE_30: 93 | date = date - datetime.timedelta(minutes=30) 94 | return BarData( 95 | symbol=symbol, 96 | exchange=exchange, 97 | interval=interval, 98 | datetime=date, 99 | open_price=row["open"], 100 | high_price=row["high"], 101 | low_price=row["low"], 102 | close_price=row["close"], 103 | volume=row["volume"], 104 | gateway_name=self.gateway_name 105 | ) 106 | 107 | def connect(self, setting: dict): 108 | # self._looper.start() 109 | self._run() 110 | 111 | def subscribe_bar(self, req: SubscribeBarRequest): 112 | seconds = _bar_interval_2_seconds(req.interval) 113 | symbol = f'{req.exchange.value}.{req.symbol}' 114 | self._bar_requests.append(req) 115 | 116 | def send_order(self, req: OrderRequest): 117 | symbol = f'{req.exchange.value}.{req.symbol}' 118 | direction = _direction(req.direction) 119 | offset = _offset(req.offset) 120 | 121 | def query_position(self): 122 | pass 123 | 124 | def _run(self): 125 | # 初始化k线 126 | 127 | # bars = get_bars('300253.XSHE', 24000, unit='1m', 128 | # fields=['date', 'open', 'high', 'low', 'close'], 129 | # include_now=False, end_dt=None, fq_ref_date=None, df=True) 130 | # print(bars) 131 | while True: 132 | import time 133 | # self._tqapi.wait_update() 134 | # for i, bar_df in enumerate(self._bars_df): 135 | # if self._tqapi.is_changing(bar_df.iloc[-1], "datetime"): 136 | # row = bar_df.iloc[-2] 137 | # bar_request = self._bar_requests[i] 138 | # bar = self.dfrow2bar(bar_request.exchange, bar_request.symbol, bar_request.interval, row) 139 | # self.on_bar(bar) 140 | -------------------------------------------------------------------------------- /gateway/tq/__init__.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | __author__ = "hanweiwei" 4 | __date__ = "2019-05-31" -------------------------------------------------------------------------------- /gateway/tq/tq_gateway.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | import datetime 3 | from threading import Thread 4 | from typing import List 5 | 6 | from pandas import DataFrame 7 | 8 | from event.engine import EventEngine 9 | from trader.constant import Interval, Exchange, Direction, Offset 10 | from trader.gateway import BaseGateway 11 | from trader.object import KLineRequest, BarData, SubscribeBarRequest, OrderRequest 12 | 13 | OFFSET_DICT = { 14 | Offset.OPEN: "OPEN", 15 | Offset.CLOSE: "CLOSE", 16 | Offset.CLOSETODAY: "CLOSETODAY", 17 | } 18 | 19 | DIRECTION_DICT = { 20 | Direction.LONG: "BUY", 21 | Direction.SHORT: "SELL" 22 | } 23 | 24 | __author__ = "hanweiwei" 25 | __date__ = "2019-05-31" 26 | 27 | from tqsdk import api, TqSim, TqBacktest 28 | 29 | 30 | def _bar_interval_2_seconds(bar_interval): 31 | """ 32 | 33 | :param bar_interval: 34 | :return: 35 | """ 36 | if bar_interval == Interval.MINUTE: 37 | seconds = 60 38 | elif bar_interval == Interval.MINUTE_5: 39 | seconds = 300 40 | elif bar_interval == Interval.MINUTE_30: 41 | seconds = 1800 42 | elif bar_interval == Interval.HOUR: 43 | seconds = 3600 44 | elif bar_interval == Interval.DAILY: 45 | seconds = 3600 * 24 46 | elif bar_interval == Interval.WEEKLY: 47 | seconds = 3600 * 24 * 7 48 | else: 49 | raise ValueError("unknown bar interval %s" % bar_interval) 50 | return seconds 51 | 52 | 53 | def _direction(direction: Direction): 54 | return DIRECTION_DICT.get(direction) 55 | 56 | 57 | def _offset(offset: Offset): 58 | return OFFSET_DICT.get(offset) 59 | 60 | 61 | class TQGateway(BaseGateway): 62 | 63 | def __init__(self, event_engine: EventEngine): 64 | super().__init__(event_engine, "TQ") 65 | self._tqapi = api.TqApi(TqSim(), backtest=TqBacktest(start_dt=datetime.date(2019, 3, 20), 66 | end_dt=datetime.date(2019, 6, 20))) 67 | self._looper = Thread(target=self._run) 68 | 69 | self._bar_requests: List[SubscribeBarRequest] = [] 70 | self._bars_df: List[DataFrame] = [] 71 | 72 | def get_kline_data(self, kline_request: KLineRequest): 73 | exchange = kline_request.exchange 74 | interval = kline_request.bar_interval 75 | seconds = _bar_interval_2_seconds(kline_request.bar_interval) 76 | symbol = f'{kline_request.exchange.value}.{kline_request.symbol}' 77 | df = self._tqapi.get_kline_serial(symbol, duration_seconds=seconds, 78 | data_length=kline_request.data_length) 79 | data: List[BarData] = [] 80 | for ix, row in df.iterrows(): 81 | bar = self.dfrow2bar(exchange, kline_request.symbol, interval, row) 82 | data.append(bar) 83 | 84 | return data 85 | 86 | def dfrow2bar(self, exchange, symbol, interval, row): 87 | return BarData( 88 | symbol=symbol, 89 | exchange=exchange, 90 | interval=interval, 91 | datetime=datetime.datetime.fromtimestamp(int(row["datetime"] / 1000000000)), 92 | open_price=row["open"], 93 | high_price=row["high"], 94 | low_price=row["low"], 95 | close_price=row["close"], 96 | volume=row["volume"], 97 | gateway_name=self.gateway_name 98 | ) 99 | 100 | def connect(self, setting: dict): 101 | # self._looper.start() 102 | self._run() 103 | 104 | def subscribe_bar(self, req: SubscribeBarRequest): 105 | seconds = _bar_interval_2_seconds(req.interval) 106 | symbol = f'{req.exchange.value}.{req.symbol}' 107 | df = self._tqapi.get_kline_serial(symbol, duration_seconds=seconds) 108 | self._bars_df.append(df) 109 | self._bar_requests.append(req) 110 | 111 | def send_order(self, req: OrderRequest): 112 | symbol = f'{req.exchange.value}.{req.symbol}' 113 | direction = _direction(req.direction) 114 | offset = _offset(req.offset) 115 | order = self._tqapi.insert_order(symbol=symbol, direction=direction, offset=offset, volume=int(req.volume)) 116 | 117 | def query_position(self): 118 | pass 119 | 120 | def _run(self): 121 | while True: 122 | self._tqapi.wait_update() 123 | for i, bar_df in enumerate(self._bars_df): 124 | if self._tqapi.is_changing(bar_df.iloc[-1], "datetime"): 125 | row = bar_df.iloc[-2] 126 | bar_request = self._bar_requests[i] 127 | bar = self.dfrow2bar(bar_request.exchange, bar_request.symbol, bar_request.interval, row) 128 | self.on_bar(bar) 129 | -------------------------------------------------------------------------------- /jq/__init__.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | from __future__ import absolute_import 4 | 5 | __author__ = "hanweiwei" 6 | __date__ = "2020/10/13" -------------------------------------------------------------------------------- /jq/jq_test.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | from __future__ import absolute_import 4 | 5 | __author__ = "hanweiwei" 6 | __date__ = "2020/10/13" 7 | 8 | from jqdatasdk import * 9 | 10 | if __name__ == '__main__': 11 | auth('13516771087', 'www1995com') 12 | print get_query_count() -------------------------------------------------------------------------------- /jq/north_money_bool_band.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | from __future__ import absolute_import 4 | 5 | __author__ = "hanweiwei" 6 | __date__ = "2020/10/18" 7 | 8 | """ 9 | 北上资金布林轨,择时使用 10 | """ 11 | 12 | from jqdatasdk import * 13 | import matplotlib.pyplot as pl 14 | import datetime 15 | 16 | import matplotlib.dates as mdates 17 | 18 | STDEV_N = 2 # 计算布林轨的标准差倍数 19 | WINDOW = 60 # 计算布林轨的窗口长度 20 | 21 | 22 | def get_boll(end_date): 23 | """ 24 | 获取北向资金布林带 25 | """ 26 | 27 | _base_days = get_trade_days(end_date=end_date, count=100) # 基础 28 | 29 | _mfs = [] 30 | _MiD = [] # 日平均线数组 31 | _UP = [] 32 | _DW = [] 33 | _DT = [] 34 | for i in _base_days: 35 | table = finance.STK_ML_QUOTA # 市场通成交与额度信息 36 | q = query( 37 | table.day, table.quota_daily, table.quota_daily_balance 38 | ).filter( 39 | table.link_id.in_(['310001', '310002']), table.day <= i # 沪股通、深股通 40 | ) \ 41 | .order_by(table.day.desc()) \ 42 | .limit(70) 43 | 44 | money_df = finance.run_query(q) 45 | money_df['net_amount'] = money_df['quota_daily'] - money_df['quota_daily_balance'] # 每日额度-每日剩余额度=净买入额 46 | # 分组求和 47 | money_df = money_df.groupby('day')[['net_amount']].sum().iloc[-WINDOW:] # 过去g.window天求和 48 | mid = money_df['net_amount'].mean() 49 | stdev = money_df['net_amount'].std() 50 | upper = mid + STDEV_N * stdev 51 | lower = mid - STDEV_N * stdev 52 | mf = money_df['net_amount'].iloc[-1] 53 | 54 | _DT.append(i) 55 | _mfs.append(mf) 56 | _UP.append(upper) 57 | _DW.append(lower) 58 | _MiD.append(mid) 59 | 60 | return _DT, _mfs, _UP, _DW, _MiD 61 | 62 | 63 | def main(): 64 | auth("13516771087", "www1995com") 65 | print(get_query_count()) 66 | pre_date = (datetime.date.today() - datetime.timedelta(1)).strftime('%Y-%m-%d') 67 | # pre_date = datetime.datetime(year=2016, month=4, day=1).strftime('%Y-%m-%d') 68 | dts, mfs, ups, dws, mids = get_boll(pre_date) 69 | 70 | pl.title("North Money Band") 71 | pl.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) 72 | pl.gca().xaxis.set_major_locator(mdates.MonthLocator(interval=1)) 73 | pl.plot(dts, mids, "y", lw=0.5) 74 | pl.plot(dts, ups, "r", lw=0.5) 75 | pl.plot(dts, dws, "g", lw=0.5) 76 | pl.plot(dts, mfs, lw=1) 77 | pl.show() 78 | 79 | 80 | if __name__ == '__main__': 81 | main() 82 | -------------------------------------------------------------------------------- /mytushare/__init__.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | __author__ = "hanweiwei" 4 | __date__ = "2018/11/16" -------------------------------------------------------------------------------- /mytushare/api.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | import datetime 3 | import json 4 | 5 | import requests 6 | import requests_cache 7 | 8 | from app import app_log 9 | from tools import time_tools 10 | 11 | __author__ = "hanweiwei" 12 | __date__ = "2018/11/16" 13 | 14 | TOKEN = "24b9e438d14d30648fa32dd6b457500ddc041ff0e17378d0b2083d7d" 15 | 16 | MINUTE_1 = "1MIN" 17 | MINUTE_5 = "5MIN" 18 | MINUTE_30 = "30MIN" 19 | MINUTE_60 = "60MIN" 20 | DAY_1 = "1D" 21 | 22 | KLINE_URL = "http://api.tushare.pro" 23 | 24 | requests_cache.install_cache() 25 | s = requests.Session() 26 | 27 | 28 | def getKLineData(stock_code, scale, start_date, end_date): 29 | """ 30 | 查询K线 31 | :param stock_code: 股票代码 深圳 000001.SZ 上海 600001.SS 32 | :param scale: 周期 1min 5min 30min 60min 1d 33 | :param start_date: str 34 | :param end_date: str 35 | :return: DataFrame 36 | """ 37 | 38 | start_date = parse_date(start_date) 39 | end_date = parse_date(end_date) 40 | 41 | api_params = { 42 | "ts_code": stock_code, 43 | "start_date": start_date, 44 | "end_date": end_date, 45 | "adj": "qfq", 46 | "freq": scale 47 | } 48 | params = {"api_name": "hist_bar", "token": TOKEN, "params": api_params, "fields": "open,high,low,close"} 49 | 50 | app_log.info("REQUEST START:\n%s\%s", KLINE_URL, api_params) 51 | 52 | response = s.post(KLINE_URL, headers={'Connection': 'keep-alive', 53 | "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"} 54 | , json=params) 55 | contents = response.json() 56 | # app_log.info("REQUEST END:\n%s" % response) 57 | # 58 | # chart = contents["chart"] 59 | # if chart["error"]: 60 | # raise Exception(contents["error"]) 61 | # contents = chart["result"][0] 62 | # quote = contents["indicators"]["quote"][0] 63 | # datetime_index = pd.to_datetime(contents["timestamp"], unit="s", utc=True) 64 | # datetime_index = datetime_index.tz_convert(pytz.timezone("Asia/Shanghai")) 65 | # data = pd.DataFrame({ 66 | # "high": quote["high"] 67 | # , "low": quote["low"] 68 | # , "open": quote["open"] 69 | # , "close": quote["close"] 70 | # }, index=datetime_index) 71 | # 72 | # data = data.dropna(how='any') 73 | # data['time'] = data.index 74 | return contents 75 | 76 | 77 | def parse_date(date): 78 | """ 79 | 80 | :param date: timestamp or date or str or datetime 81 | :return: 82 | """ 83 | if date: 84 | if isinstance(date, str): 85 | date = time_tools.datetime2timestamp(datetime.datetime.strptime(date, "%Y%m%d")) 86 | elif isinstance(date, datetime.date): 87 | date = time_tools.date2timestamp(date) 88 | elif isinstance(date, datetime.datetime): 89 | date = time_tools.date2timestamp(date) 90 | elif isinstance(date, int): 91 | pass 92 | else: 93 | raise ValueError("date type error, must be timestamp, date, datetime, str") 94 | return date 95 | 96 | 97 | if __name__ == '__main__': 98 | data = getKLineData("601788.SS", scale=MINUTE_5, start_date="20181111", end_date="20181114") 99 | app_log.info("\n%s", json.dumps(data,ensure_ascii=False)) 100 | # print getKLineData("601788.SS", scale=MINUTE_5, start_date="20181109", end_date="20181111") 101 | -------------------------------------------------------------------------------- /mytushare/api2.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | import datetime 3 | import json 4 | 5 | import requests 6 | import requests_cache 7 | 8 | from app import app_log 9 | from tools import time_tools 10 | 11 | __author__ = "hanweiwei" 12 | __date__ = "2018/11/16" 13 | TOKEN = "24b9e438d14d30648fa32dd6b457500ddc041ff0e17378d0b2083d7d" 14 | 15 | MINUTE_1 = "1MIN" 16 | MINUTE_5 = "5MIN" 17 | MINUTE_30 = "30MIN" 18 | MINUTE_60 = "60MIN" 19 | DAY_1 = "1D" 20 | 21 | import tushare as tu 22 | 23 | tu.set_token(TOKEN) 24 | pro_api = tu.pro_api() 25 | 26 | 27 | def getKLineData(stock_code, scale, start_date, end_date): 28 | """ 29 | 查询K线 30 | :param stock_code: 股票代码 深圳 000001.SZ 上海 600001.SS 31 | :param scale: 周期 1min 5min 30min 60min 1d 32 | :param start_date: str 33 | :param end_date: str 34 | :return: DataFrame 35 | """ 36 | return tu.pro_bar(stock_code, pro_api, start_date, end_date, freq=scale, adj="qfq") 37 | 38 | 39 | if __name__ == '__main__': 40 | data = getKLineData("000001.SZ", scale=None, start_date="20181101", end_date="20181118") 41 | app_log.info("\n%s", data) 42 | # print getKLineData("601788.SS", scale=MINUTE_5, start_date="20181109", end_date="20181111") 43 | -------------------------------------------------------------------------------- /mytushare/cache.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kymeii/ChanMaster/b25661ee1d69b756abcbe60e97a8d7c84fcad009/mytushare/cache.sqlite -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pandas 2 | pandas-datareader 3 | tqsdk 4 | sqlalchemy 5 | flask 6 | flask_cors 7 | jqdatasdk -------------------------------------------------------------------------------- /sina/__init__.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | __author__ = "hanweiwei" 4 | __date__ = "2018/10/25" -------------------------------------------------------------------------------- /sina/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kymeii/ChanMaster/b25661ee1d69b756abcbe60e97a8d7c84fcad009/sina/__init__.pyc -------------------------------------------------------------------------------- /sina/api.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | import urllib2 3 | import pandas as pd 4 | import re 5 | 6 | from app import app_log 7 | 8 | __author__ = "hanweiwei" 9 | __date__ = "2018/10/25" 10 | 11 | KLINE_URL = "https://money.finance.sina.com.cn/quotes_service/api/jsonp_v2.php/data=/CN_MarketData.getKLineData?symbol=%s&scale=%s&ma=%s&datalen=%s" 12 | 13 | MINUTE_5 = 5 14 | MINUTE_15 = 15 15 | MINUTE_30 = 30 16 | MINUTE_60 = 60 17 | DAY = 240 18 | DAY_5 = DAY * 5 19 | WEEK = DAY * 7 20 | MONTH = DAY * 30 21 | 22 | 23 | def getKLineData(stock_code="SZ000001", scale=DAY, ma="no", count=100): 24 | """ 25 | 查询K线 26 | :param stock_code: 股票代码 SZ深圳000001 SH上证600001 27 | :param scale: 周期 5m 15m 30m 60m 1day 5day 1week 1month 28 | :param ma: 移动平均线 ,分隔 29 | :param count: 数量 30 | :return: DataFrame 31 | """ 32 | contents = urllib2.urlopen(KLINE_URL % (stock_code, scale, ma, count)).read() 33 | contents = contents[6:-1] 34 | 35 | contents = re.sub(r",(\w+):", lambda s: ',"%s":' % contents[s.start(1):s.end(1)], contents) 36 | contents = re.sub(r"{(\w+):", lambda s: '{"%s":' % contents[s.start(1):s.end(1)], contents) 37 | app_log.info("获取数据成功") 38 | return pd.read_json(contents) 39 | 40 | 41 | if __name__ == '__main__': 42 | print getKLineData("SH000001", scale=MINUTE_60, count=100) 43 | -------------------------------------------------------------------------------- /sina/api.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kymeii/ChanMaster/b25661ee1d69b756abcbe60e97a8d7c84fcad009/sina/api.pyc -------------------------------------------------------------------------------- /static/data.json: -------------------------------------------------------------------------------- 1 | {"pens": [{"start": 12, "end": 18}, {"start": 18, "end": 37}, {"start": 37, "end": 70}, {"start": 70, "end": 152}, {"start": 152, "end": 163}, {"start": 163, "end": 219}, {"start": 219, "end": 236}, {"start": 236, "end": 261}], "kline": [{"volume": 862446700, "includeLow": 2873.822, "includeIndex": -1, "high": 2879.943, "includeHigh": 2879.943, "low": 2873.822, "includeTail": 0, "fenxing": 0, "close": 2879.943, "open": 2874.036, "day": "2019-05-17 14:55:00"}, {"volume": 646028700, "includeLow": 2879.681, "includeIndex": 1, "high": 2882.296, "includeHigh": 2882.296, "low": 2879.681, "includeTail": 0, "fenxing": 0, "close": 2882.296, "open": 2879.805, "day": "2019-05-17 15:00:00"}, {"volume": 1831886800, "includeLow": 2879.681, "includeIndex": 1, "high": 2882.629, "includeHigh": 2882.629, "low": 2868.759, "includeTail": 1, "fenxing": 1, "close": 2869.155, "open": 2874.801, "day": "2019-05-20 09:35:00"}, {"volume": 1434762700, "includeLow": 2865.643, "includeIndex": 3, "high": 2879.574, "includeHigh": 2879.574, "low": 2865.643, "includeTail": 0, "fenxing": 0, "close": 2879.043, "open": 2868.72, "day": "2019-05-20 09:40:00"}, {"volume": 984259900, "includeLow": 2865.643, "includeIndex": 3, "high": 2879.193, "includeHigh": 2879.193, "low": 2868.417, "includeTail": 1, "fenxing": 0, "close": 2868.417, "open": 2879.193, "day": "2019-05-20 09:45:00"}, {"volume": 1475071100, "includeLow": 2846.872, "includeIndex": 5, "high": 2869.335, "includeHigh": 2869.335, "low": 2846.872, "includeTail": 0, "fenxing": 0, "close": 2849.505, "open": 2868.828, "day": "2019-05-20 09:50:00"}, {"volume": 1012699500, "includeLow": 2846.872, "includeIndex": 5, "high": 2854.092, "includeHigh": 2854.092, "low": 2846.886, "includeTail": 1, "fenxing": 0, "close": 2854.092, "open": 2849.148, "day": "2019-05-20 09:55:00"}, {"volume": 837953800, "includeLow": 2842.608, "includeIndex": 7, "high": 2853.507, "includeHigh": 2853.507, "low": 2842.608, "includeTail": 0, "fenxing": 0, "close": 2849.528, "open": 2853.233, "day": "2019-05-20 10:00:00"}, {"volume": 555324600, "includeLow": 2842.608, "includeIndex": 7, "high": 2851.205, "includeHigh": 2851.205, "low": 2843.625, "includeTail": 0, "fenxing": 0, "close": 2843.866, "open": 2849.471, "day": "2019-05-20 10:05:00"}, {"volume": 629139600, "includeLow": 2841.501, "includeIndex": 7, "high": 2851.308, "includeHigh": 2851.205, "low": 2841.501, "includeTail": 0, "fenxing": 0, "close": 2850.416, "open": 2843.419, "day": "2019-05-20 10:10:00"}, {"volume": 404904100, "includeLow": 2841.501, "includeIndex": 7, "high": 2849.976, "includeHigh": 2849.976, "low": 2844.462, "includeTail": 1, "fenxing": 0, "close": 2845.631, "open": 2849.434, "day": "2019-05-20 10:15:00"}, {"volume": 436819100, "includeLow": 2838.958, "includeIndex": -1, "high": 2845.597, "includeHigh": 2845.597, "low": 2838.958, "includeTail": 0, "fenxing": 0, "close": 2841.246, "open": 2845.597, "day": "2019-05-20 10:20:00"}, {"volume": 379548300, "includeLow": 2838.453, "includeIndex": -1, "high": 2842.298, "includeHigh": 2842.298, "low": 2838.453, "includeTail": 0, "fenxing": 2, "close": 2840.022, "open": 2841.929, "day": "2019-05-20 10:25:00"}, {"volume": 470136200, "includeLow": 2839.392, "includeIndex": -1, "high": 2852.332, "includeHigh": 2852.332, "low": 2839.392, "includeTail": 0, "fenxing": 0, "close": 2852.241, "open": 2840.206, "day": "2019-05-20 10:30:00"}, {"volume": 457881100, "includeLow": 2852.471, "includeIndex": -1, "high": 2861.977, "includeHigh": 2861.977, "low": 2852.471, "includeTail": 0, "fenxing": 0, "close": 2861.22, "open": 2852.494, "day": "2019-05-20 10:35:00"}, {"volume": 356212500, "includeLow": 2853.189, "includeIndex": -1, "high": 2862.01, "includeHigh": 2862.01, "low": 2853.189, "includeTail": 0, "fenxing": 1, "close": 2853.632, "open": 2861.676, "day": "2019-05-20 10:40:00"}, {"volume": 297061900, "includeLow": 2852.867, "includeIndex": -1, "high": 2861.23, "includeHigh": 2861.23, "low": 2852.867, "includeTail": 0, "fenxing": 2, "close": 2861.23, "open": 2853.574, "day": "2019-05-20 10:45:00"}, {"volume": 546778600, "includeLow": 2862.162, "includeIndex": -1, "high": 2874.226, "includeHigh": 2874.226, "low": 2862.162, "includeTail": 0, "fenxing": 0, "close": 2874.134, "open": 2862.162, "day": "2019-05-20 10:50:00"}, {"volume": 476949000, "includeLow": 2869.2, "includeIndex": -1, "high": 2878.486, "includeHigh": 2878.486, "low": 2869.2, "includeTail": 0, "fenxing": 1, "close": 2869.266, "open": 2874.567, "day": "2019-05-20 10:55:00"}, {"volume": 272936100, "includeLow": 2868.501, "includeIndex": -1, "high": 2871.255, "includeHigh": 2871.255, "low": 2868.501, "includeTail": 0, "fenxing": 0, "close": 2870.252, "open": 2868.992, "day": "2019-05-20 11:00:00"}, {"volume": 269608000, "includeLow": 2864.95, "includeIndex": -1, "high": 2870.72, "includeHigh": 2870.72, "low": 2864.95, "includeTail": 0, "fenxing": 0, "close": 2864.95, "open": 2869.877, "day": "2019-05-20 11:05:00"}, {"volume": 253240400, "includeLow": 2858.935, "includeIndex": -1, "high": 2865.439, "includeHigh": 2865.439, "low": 2858.935, "includeTail": 0, "fenxing": 2, "close": 2861.495, "open": 2865.439, "day": "2019-05-20 11:10:00"}, {"volume": 224076000, "includeLow": 2861.37, "includeIndex": -1, "high": 2866.911, "includeHigh": 2866.911, "low": 2861.37, "includeTail": 0, "fenxing": 0, "close": 2865.241, "open": 2861.37, "day": "2019-05-20 11:15:00"}, {"volume": 199796500, "includeLow": 2865.139, "includeIndex": 23, "high": 2868.045, "includeHigh": 2868.045, "low": 2865.139, "includeTail": 0, "fenxing": 0, "close": 2867.462, "open": 2865.405, "day": "2019-05-20 11:20:00"}, {"volume": 227659500, "includeLow": 2865.139, "includeIndex": 23, "high": 2868.865, "includeHigh": 2868.865, "low": 2861.909, "includeTail": 1, "fenxing": 1, "close": 2864.424, "open": 2867.658, "day": "2019-05-20 11:25:00"}, {"volume": 149396800, "includeLow": 2862.908, "includeIndex": 25, "high": 2865.571, "includeHigh": 2865.571, "low": 2862.908, "includeTail": 0, "fenxing": 0, "close": 2864.214, "open": 2864.984, "day": "2019-05-20 11:30:00"}, {"volume": 230139700, "includeLow": 2861.2, "includeIndex": 25, "high": 2866.227, "includeHigh": 2865.571, "low": 2861.2, "includeTail": 0, "fenxing": 0, "close": 2861.2, "open": 2865.276, "day": "2019-05-20 13:05:00"}, {"volume": 184844000, "includeLow": 2860.812, "includeIndex": 25, "high": 2867.878, "includeHigh": 2865.571, "low": 2860.812, "includeTail": 0, "fenxing": 0, "close": 2867.129, "open": 2861.401, "day": "2019-05-20 13:10:00"}, {"volume": 183995500, "includeLow": 2860.618, "includeIndex": 25, "high": 2867.151, "includeHigh": 2865.571, "low": 2860.618, "includeTail": 1, "fenxing": 0, "close": 2860.618, "open": 2867.151, "day": "2019-05-20 13:15:00"}, {"volume": 202403200, "includeLow": 2858.053, "includeIndex": -1, "high": 2860.788, "includeHigh": 2860.788, "low": 2858.053, "includeTail": 0, "fenxing": 0, "close": 2858.305, "open": 2860.531, "day": "2019-05-20 13:20:00"}, {"volume": 209293500, "includeLow": 2855.299, "includeIndex": -1, "high": 2858.719, "includeHigh": 2858.719, "low": 2855.299, "includeTail": 0, "fenxing": 0, "close": 2855.534, "open": 2858.266, "day": "2019-05-20 13:25:00"}, {"volume": 189568700, "includeLow": 2855.197, "includeIndex": 31, "high": 2857.934, "includeHigh": 2857.934, "low": 2855.197, "includeTail": 0, "fenxing": 0, "close": 2856.476, "open": 2855.197, "day": "2019-05-20 13:30:00"}, {"volume": 220619200, "includeLow": 2853.693, "includeIndex": 31, "high": 2858.012, "includeHigh": 2857.934, "low": 2853.693, "includeTail": 1, "fenxing": 2, "close": 2857.936, "open": 2856.178, "day": "2019-05-20 13:35:00"}, {"volume": 210708100, "includeLow": 2856.942, "includeIndex": -1, "high": 2860.663, "includeHigh": 2860.663, "low": 2856.942, "includeTail": 0, "fenxing": 1, "close": 2858.839, "open": 2857.812, "day": "2019-05-20 13:40:00"}, {"volume": 174770000, "includeLow": 2856.484, "includeIndex": -1, "high": 2859.662, "includeHigh": 2859.662, "low": 2856.484, "includeTail": 0, "fenxing": 0, "close": 2857.419, "open": 2859.163, "day": "2019-05-20 13:45:00"}, {"volume": 272136600, "includeLow": 2852.619, "includeIndex": -1, "high": 2857.242, "includeHigh": 2857.242, "low": 2852.619, "includeTail": 0, "fenxing": 0, "close": 2855.113, "open": 2856.787, "day": "2019-05-20 13:50:00"}, {"volume": 238406500, "includeLow": 2850.07, "includeIndex": -1, "high": 2855.689, "includeHigh": 2855.689, "low": 2850.07, "includeTail": 0, "fenxing": 0, "close": 2850.07, "open": 2855.689, "day": "2019-05-20 13:55:00"}, {"volume": 251636300, "includeLow": 2849.359, "includeIndex": -1, "high": 2853.29, "includeHigh": 2853.29, "low": 2849.359, "includeTail": 0, "fenxing": 2, "close": 2853.227, "open": 2849.89, "day": "2019-05-20 14:00:00"}, {"volume": 193190300, "includeLow": 2852.652, "includeIndex": -1, "high": 2855.359, "includeHigh": 2855.359, "low": 2852.652, "includeTail": 0, "fenxing": 0, "close": 2854.472, "open": 2852.652, "day": "2019-05-20 14:05:00"}, {"volume": 303567200, "includeLow": 2854.639, "includeIndex": -1, "high": 2858.711, "includeHigh": 2858.711, "low": 2854.639, "includeTail": 0, "fenxing": 1, "close": 2857.169, "open": 2855.106, "day": "2019-05-20 14:10:00"}, {"volume": 245269600, "includeLow": 2853.365, "includeIndex": -1, "high": 2857.568, "includeHigh": 2857.568, "low": 2853.365, "includeTail": 0, "fenxing": 0, "close": 2853.422, "open": 2857.308, "day": "2019-05-20 14:15:00"}, {"volume": 260011200, "includeLow": 2851.415, "includeIndex": 41, "high": 2853.376, "includeHigh": 2853.376, "low": 2851.415, "includeTail": 0, "fenxing": 0, "close": 2851.415, "open": 2853.237, "day": "2019-05-20 14:20:00"}, {"volume": 323074700, "includeLow": 2851.195, "includeIndex": 41, "high": 2857.744, "includeHigh": 2853.376, "low": 2851.195, "includeTail": 1, "fenxing": 2, "close": 2857.526, "open": 2851.195, "day": "2019-05-20 14:25:00"}, {"volume": 293225600, "includeLow": 2855.313, "includeIndex": -1, "high": 2858.136, "includeHigh": 2858.136, "low": 2855.313, "includeTail": 0, "fenxing": 0, "close": 2856.518, "open": 2857.517, "day": "2019-05-20 14:30:00"}, {"volume": 314917600, "includeLow": 2856.198, "includeIndex": -1, "high": 2861.491, "includeHigh": 2861.491, "low": 2856.198, "includeTail": 0, "fenxing": 0, "close": 2861.216, "open": 2856.747, "day": "2019-05-20 14:35:00"}, {"volume": 464034000, "includeLow": 2860.919, "includeIndex": 45, "high": 2868.391, "includeHigh": 2868.391, "low": 2860.919, "includeTail": 0, "fenxing": 0, "close": 2866.88, "open": 2861.331, "day": "2019-05-20 14:40:00"}, {"volume": 362895300, "includeLow": 2865.336, "includeIndex": 45, "high": 2867.898, "includeHigh": 2868.391, "low": 2865.336, "includeTail": 1, "fenxing": 0, "close": 2865.939, "open": 2867.3, "day": "2019-05-20 14:45:00"}, {"volume": 413477000, "includeLow": 2865.67, "includeIndex": -1, "high": 2868.692, "includeHigh": 2868.692, "low": 2865.67, "includeTail": 0, "fenxing": 0, "close": 2868.175, "open": 2866.238, "day": "2019-05-20 14:50:00"}, {"volume": 524767000, "includeLow": 2867.322, "includeIndex": -1, "high": 2870.881, "includeHigh": 2870.881, "low": 2867.322, "includeTail": 0, "fenxing": 0, "close": 2870.881, "open": 2867.61, "day": "2019-05-20 14:55:00"}, {"volume": 494293000, "includeLow": 2870.339, "includeIndex": 49, "high": 2872.188, "includeHigh": 2872.188, "low": 2870.339, "includeTail": 0, "fenxing": 0, "close": 2870.605, "open": 2870.729, "day": "2019-05-20 15:00:00"}, {"volume": 1422069400, "includeLow": 2870.339, "includeIndex": 49, "high": 2880.081, "includeHigh": 2880.081, "low": 2862.738, "includeTail": 1, "fenxing": 0, "close": 2880.081, "open": 2867.707, "day": "2019-05-21 09:35:00"}, {"volume": 940352600, "includeLow": 2875.985, "includeIndex": -1, "high": 2880.783, "includeHigh": 2880.783, "low": 2875.985, "includeTail": 0, "fenxing": 0, "close": 2880.507, "open": 2879.794, "day": "2019-05-21 09:40:00"}, {"volume": 813493800, "includeLow": 2876.892, "includeIndex": -1, "high": 2887.064, "includeHigh": 2887.064, "low": 2876.892, "includeTail": 0, "fenxing": 0, "close": 2887.064, "open": 2880.683, "day": "2019-05-21 09:45:00"}, {"volume": 727740800, "includeLow": 2885.855, "includeIndex": 53, "high": 2889.03, "includeHigh": 2889.03, "low": 2885.855, "includeTail": 0, "fenxing": 0, "close": 2886.102, "open": 2887.544, "day": "2019-05-21 09:50:00"}, {"volume": 607339900, "includeLow": 2885.855, "includeIndex": 53, "high": 2889.364, "includeHigh": 2889.364, "low": 2885.118, "includeTail": 1, "fenxing": 1, "close": 2885.31, "open": 2886.807, "day": "2019-05-21 09:55:00"}, {"volume": 464478200, "includeLow": 2884.048, "includeIndex": -1, "high": 2888.289, "includeHigh": 2888.289, "low": 2884.048, "includeTail": 0, "fenxing": 2, "close": 2887.985, "open": 2884.541, "day": "2019-05-21 10:00:00"}, {"volume": 398454400, "includeLow": 2885.369, "includeIndex": -1, "high": 2889.729, "includeHigh": 2889.729, "low": 2885.369, "includeTail": 0, "fenxing": 1, "close": 2885.461, "open": 2888.34, "day": "2019-05-21 10:05:00"}, {"volume": 512783200, "includeLow": 2880.146, "includeIndex": -1, "high": 2886.647, "includeHigh": 2886.647, "low": 2880.146, "includeTail": 0, "fenxing": 0, "close": 2880.146, "open": 2885.753, "day": "2019-05-21 10:10:00"}, {"volume": 418074500, "includeLow": 2879.298, "includeIndex": -1, "high": 2881.857, "includeHigh": 2881.857, "low": 2879.298, "includeTail": 0, "fenxing": 2, "close": 2881.54, "open": 2879.97, "day": "2019-05-21 10:15:00"}, {"volume": 359239900, "includeLow": 2880.71, "includeIndex": 59, "high": 2886.576, "includeHigh": 2886.576, "low": 2880.71, "includeTail": 0, "fenxing": 0, "close": 2885.002, "open": 2880.974, "day": "2019-05-21 10:20:00"}, {"volume": 306281000, "includeLow": 2880.987, "includeIndex": 59, "high": 2885.314, "includeHigh": 2886.576, "low": 2880.987, "includeTail": 0, "fenxing": 0, "close": 2881.277, "open": 2885.12, "day": "2019-05-21 10:25:00"}, {"volume": 412523100, "includeLow": 2880.987, "includeIndex": 59, "high": 2893.288, "includeHigh": 2893.288, "low": 2880.743, "includeTail": 1, "fenxing": 0, "close": 2893.288, "open": 2880.743, "day": "2019-05-21 10:30:00"}, {"volume": 571380000, "includeLow": 2893.305, "includeIndex": 62, "high": 2900.095, "includeHigh": 2900.095, "low": 2893.305, "includeTail": 0, "fenxing": 0, "close": 2897.881, "open": 2893.305, "day": "2019-05-21 10:35:00"}, {"volume": 390586600, "includeLow": 2894.287, "includeIndex": 62, "high": 2898.933, "includeHigh": 2900.095, "low": 2894.287, "includeTail": 1, "fenxing": 0, "close": 2898.933, "open": 2897.549, "day": "2019-05-21 10:40:00"}, {"volume": 412065400, "includeLow": 2898.246, "includeIndex": -1, "high": 2901.592, "includeHigh": 2901.592, "low": 2898.246, "includeTail": 0, "fenxing": 0, "close": 2901.47, "open": 2899.395, "day": "2019-05-21 10:45:00"}, {"volume": 516523900, "includeLow": 2902.21, "includeIndex": -1, "high": 2905.911, "includeHigh": 2905.911, "low": 2902.21, "includeTail": 0, "fenxing": 1, "close": 2904.373, "open": 2902.21, "day": "2019-05-21 10:50:00"}, {"volume": 359014400, "includeLow": 2901.119, "includeIndex": -1, "high": 2903.585, "includeHigh": 2903.585, "low": 2901.119, "includeTail": 0, "fenxing": 2, "close": 2902.251, "open": 2903.325, "day": "2019-05-21 10:55:00"}, {"volume": 444372200, "includeLow": 2901.89, "includeIndex": -1, "high": 2910.312, "includeHigh": 2910.312, "low": 2901.89, "includeTail": 0, "fenxing": 0, "close": 2910.312, "open": 2901.89, "day": "2019-05-21 11:00:00"}, {"volume": 715538300, "includeLow": 2910.743, "includeIndex": -1, "high": 2917.986, "includeHigh": 2917.986, "low": 2910.743, "includeTail": 0, "fenxing": 0, "close": 2916.927, "open": 2910.743, "day": "2019-05-21 11:05:00"}, {"volume": 536507400, "includeLow": 2914.277, "includeIndex": 69, "high": 2919.237, "includeHigh": 2919.237, "low": 2914.277, "includeTail": 0, "fenxing": 0, "close": 2918.606, "open": 2916.558, "day": "2019-05-21 11:10:00"}, {"volume": 373822900, "includeLow": 2914.452, "includeIndex": 69, "high": 2918.622, "includeHigh": 2919.237, "low": 2914.452, "includeTail": 1, "fenxing": 1, "close": 2914.658, "open": 2918.621, "day": "2019-05-21 11:15:00"}, {"volume": 403458600, "includeLow": 2909.196, "includeIndex": 71, "high": 2918.153, "includeHigh": 2918.153, "low": 2909.196, "includeTail": 0, "fenxing": 0, "close": 2909.929, "open": 2914.781, "day": "2019-05-21 11:20:00"}, {"volume": 262544200, "includeLow": 2909.196, "includeIndex": 71, "high": 2914.005, "includeHigh": 2914.005, "low": 2909.468, "includeTail": 1, "fenxing": 2, "close": 2912.05, "open": 2909.468, "day": "2019-05-21 11:25:00"}, {"volume": 302221400, "includeLow": 2911.103, "includeIndex": -1, "high": 2914.123, "includeHigh": 2914.123, "low": 2911.103, "includeTail": 0, "fenxing": 0, "close": 2914.123, "open": 2912.304, "day": "2019-05-21 11:30:00"}, {"volume": 642969700, "includeLow": 2911.522, "includeIndex": 74, "high": 2915.608, "includeHigh": 2915.608, "low": 2911.522, "includeTail": 0, "fenxing": 0, "close": 2913.063, "open": 2915.608, "day": "2019-05-21 13:05:00"}, {"volume": 355385700, "includeLow": 2911.525, "includeIndex": 74, "high": 2913.873, "includeHigh": 2915.608, "low": 2911.525, "includeTail": 0, "fenxing": 0, "close": 2913.17, "open": 2913.337, "day": "2019-05-21 13:10:00"}, {"volume": 362719100, "includeLow": 2911.529, "includeIndex": 74, "high": 2914.174, "includeHigh": 2915.608, "low": 2911.529, "includeTail": 1, "fenxing": 1, "close": 2912.106, "open": 2913.642, "day": "2019-05-21 13:15:00"}, {"volume": 461097700, "includeLow": 2904.481, "includeIndex": 77, "high": 2912.138, "includeHigh": 2912.138, "low": 2904.481, "includeTail": 0, "fenxing": 0, "close": 2906.63, "open": 2911.698, "day": "2019-05-21 13:20:00"}, {"volume": 318400000, "includeLow": 2904.481, "includeIndex": 77, "high": 2907.454, "includeHigh": 2907.454, "low": 2905.834, "includeTail": 0, "fenxing": 0, "close": 2907.037, "open": 2906.597, "day": "2019-05-21 13:25:00"}, {"volume": 265226100, "includeLow": 2904.481, "includeIndex": 77, "high": 2907.323, "includeHigh": 2907.323, "low": 2905.934, "includeTail": 1, "fenxing": 2, "close": 2906.395, "open": 2906.704, "day": "2019-05-21 13:30:00"}, {"volume": 356710000, "includeLow": 2906.17, "includeIndex": 80, "high": 2910.383, "includeHigh": 2910.383, "low": 2906.17, "includeTail": 0, "fenxing": 0, "close": 2910.278, "open": 2906.17, "day": "2019-05-21 13:35:00"}, {"volume": 292472000, "includeLow": 2906.246, "includeIndex": 80, "high": 2909.709, "includeHigh": 2910.383, "low": 2906.246, "includeTail": 1, "fenxing": 1, "close": 2907.328, "open": 2909.709, "day": "2019-05-21 13:40:00"}, {"volume": 333691100, "includeLow": 2901.725, "includeIndex": 82, "high": 2907.452, "includeHigh": 2907.452, "low": 2901.725, "includeTail": 0, "fenxing": 0, "close": 2902.006, "open": 2907.184, "day": "2019-05-21 13:45:00"}, {"volume": 250574700, "includeLow": 2901.725, "includeIndex": 82, "high": 2905.256, "includeHigh": 2905.256, "low": 2901.859, "includeTail": 1, "fenxing": 2, "close": 2905.203, "open": 2901.859, "day": "2019-05-21 13:50:00"}, {"volume": 259623100, "includeLow": 2905.105, "includeIndex": -1, "high": 2906.865, "includeHigh": 2906.865, "low": 2905.105, "includeTail": 0, "fenxing": 0, "close": 2905.942, "open": 2905.804, "day": "2019-05-21 13:55:00"}, {"volume": 369875100, "includeLow": 2905.895, "includeIndex": 85, "high": 2912.021, "includeHigh": 2912.021, "low": 2905.895, "includeTail": 0, "fenxing": 0, "close": 2911.436, "open": 2906.031, "day": "2019-05-21 14:00:00"}, {"volume": 304282200, "includeLow": 2908.86, "includeIndex": 85, "high": 2911.853, "includeHigh": 2912.021, "low": 2908.86, "includeTail": 1, "fenxing": 1, "close": 2908.954, "open": 2911.853, "day": "2019-05-21 14:05:00"}, {"volume": 278788700, "includeLow": 2904.927, "includeIndex": -1, "high": 2909.053, "includeHigh": 2909.053, "low": 2904.927, "includeTail": 0, "fenxing": 0, "close": 2905.554, "open": 2908.579, "day": "2019-05-21 14:10:00"}, {"volume": 335334400, "includeLow": 2900.281, "includeIndex": 88, "high": 2905.199, "includeHigh": 2905.199, "low": 2900.281, "includeTail": 0, "fenxing": 0, "close": 2901.282, "open": 2904.916, "day": "2019-05-21 14:15:00"}, {"volume": 233629800, "includeLow": 2900.281, "includeIndex": 88, "high": 2904.431, "includeHigh": 2904.431, "low": 2901.267, "includeTail": 1, "fenxing": 2, "close": 2903.879, "open": 2901.906, "day": "2019-05-21 14:20:00"}, {"volume": 230768200, "includeLow": 2902.209, "includeIndex": 90, "high": 2904.755, "includeHigh": 2904.755, "low": 2902.209, "includeTail": 0, "fenxing": 0, "close": 2903.552, "open": 2904.477, "day": "2019-05-21 14:25:00"}, {"volume": 268071000, "includeLow": 2902.474, "includeIndex": 90, "high": 2904.541, "includeHigh": 2904.755, "low": 2902.474, "includeTail": 1, "fenxing": 0, "close": 2904.191, "open": 2902.647, "day": "2019-05-21 14:30:00"}, {"volume": 392788000, "includeLow": 2904.521, "includeIndex": -1, "high": 2908.417, "includeHigh": 2908.417, "low": 2904.521, "includeTail": 0, "fenxing": 1, "close": 2905.247, "open": 2904.521, "day": "2019-05-21 14:35:00"}, {"volume": 299989300, "includeLow": 2903.026, "includeIndex": -1, "high": 2905.717, "includeHigh": 2905.717, "low": 2903.026, "includeTail": 0, "fenxing": 2, "close": 2903.981, "open": 2905.521, "day": "2019-05-21 14:40:00"}, {"volume": 335463200, "includeLow": 2903.721, "includeIndex": 94, "high": 2906.518, "includeHigh": 2906.518, "low": 2903.721, "includeTail": 0, "fenxing": 0, "close": 2905.597, "open": 2904.152, "day": "2019-05-21 14:45:00"}, {"volume": 415662500, "includeLow": 2904.048, "includeIndex": 94, "high": 2906.221, "includeHigh": 2906.518, "low": 2904.048, "includeTail": 0, "fenxing": 0, "close": 2904.048, "open": 2905.648, "day": "2019-05-21 14:50:00"}, {"volume": 537285900, "includeLow": 2904.317, "includeIndex": 94, "high": 2905.893, "includeHigh": 2906.518, "low": 2904.317, "includeTail": 1, "fenxing": 0, "close": 2905.263, "open": 2904.366, "day": "2019-05-21 14:55:00"}, {"volume": 559624700, "includeLow": 2905.576, "includeIndex": -1, "high": 2906.963, "includeHigh": 2906.963, "low": 2905.576, "includeTail": 0, "fenxing": 1, "close": 2905.969, "open": 2906.136, "day": "2019-05-21 15:00:00"}, {"volume": 1607968800, "includeLow": 2898.13, "includeIndex": -1, "high": 2905.524, "includeHigh": 2905.524, "low": 2898.13, "includeTail": 0, "fenxing": 0, "close": 2900.621, "open": 2905.524, "day": "2019-05-22 09:35:00"}, {"volume": 1022414700, "includeLow": 2892.347, "includeIndex": -1, "high": 2899.511, "includeHigh": 2899.511, "low": 2892.347, "includeTail": 0, "fenxing": 0, "close": 2892.938, "open": 2899.511, "day": "2019-05-22 09:40:00"}, {"volume": 863424800, "includeLow": 2890.073, "includeIndex": -1, "high": 2896.735, "includeHigh": 2896.735, "low": 2890.073, "includeTail": 0, "fenxing": 2, "close": 2896.587, "open": 2893.195, "day": "2019-05-22 09:45:00"}, {"volume": 727474700, "includeLow": 2891.822, "includeIndex": 101, "high": 2896.934, "includeHigh": 2896.934, "low": 2891.822, "includeTail": 0, "fenxing": 0, "close": 2892.073, "open": 2896.934, "day": "2019-05-22 09:50:00"}, {"volume": 681652400, "includeLow": 2891.822, "includeIndex": 101, "high": 2900.16, "includeHigh": 2900.16, "low": 2891.794, "includeTail": 1, "fenxing": 0, "close": 2900.143, "open": 2892.208, "day": "2019-05-22 09:55:00"}, {"volume": 646639200, "includeLow": 2899.505, "includeIndex": -1, "high": 2904.427, "includeHigh": 2904.427, "low": 2899.505, "includeTail": 0, "fenxing": 0, "close": 2902.71, "open": 2900.56, "day": "2019-05-22 10:00:00"}, {"volume": 523585000, "includeLow": 2900.62, "includeIndex": 104, "high": 2905.841, "includeHigh": 2905.841, "low": 2900.62, "includeTail": 0, "fenxing": 0, "close": 2904.9, "open": 2902.731, "day": "2019-05-22 10:05:00"}, {"volume": 481342900, "includeLow": 2901.174, "includeIndex": 104, "high": 2905.522, "includeHigh": 2905.841, "low": 2901.174, "includeTail": 1, "fenxing": 0, "close": 2902.117, "open": 2905.147, "day": "2019-05-22 10:10:00"}, {"volume": 539387200, "includeLow": 2902.108, "includeIndex": -1, "high": 2911.314, "includeHigh": 2911.314, "low": 2902.108, "includeTail": 0, "fenxing": 0, "close": 2910.124, "open": 2902.251, "day": "2019-05-22 10:15:00"}, {"volume": 384655700, "includeLow": 2907.295, "includeIndex": -1, "high": 2912.395, "includeHigh": 2912.395, "low": 2907.295, "includeTail": 0, "fenxing": 1, "close": 2908.404, "open": 2910.442, "day": "2019-05-22 10:20:00"}, {"volume": 390404000, "includeLow": 2903.643, "includeIndex": -1, "high": 2909.94, "includeHigh": 2909.94, "low": 2903.643, "includeTail": 0, "fenxing": 0, "close": 2903.842, "open": 2908.327, "day": "2019-05-22 10:25:00"}, {"volume": 304043000, "includeLow": 2903.126, "includeIndex": -1, "high": 2904.876, "includeHigh": 2904.876, "low": 2903.126, "includeTail": 0, "fenxing": 0, "close": 2903.545, "open": 2903.528, "day": "2019-05-22 10:30:00"}, {"volume": 350126800, "includeLow": 2901.095, "includeIndex": -1, "high": 2903.788, "includeHigh": 2903.788, "low": 2901.095, "includeTail": 0, "fenxing": 0, "close": 2901.755, "open": 2903.788, "day": "2019-05-22 10:35:00"}, {"volume": 426897200, "includeLow": 2898.002, "includeIndex": -1, "high": 2902.337, "includeHigh": 2902.337, "low": 2898.002, "includeTail": 0, "fenxing": 0, "close": 2898.002, "open": 2901.216, "day": "2019-05-22 10:40:00"}, {"volume": 410300400, "includeLow": 2897.452, "includeIndex": -1, "high": 2901.042, "includeHigh": 2901.042, "low": 2897.452, "includeTail": 0, "fenxing": 0, "close": 2898.519, "open": 2897.977, "day": "2019-05-22 10:45:00"}, {"volume": 341671700, "includeLow": 2896.74, "includeIndex": -1, "high": 2899.449, "includeHigh": 2899.449, "low": 2896.74, "includeTail": 0, "fenxing": 2, "close": 2899.449, "open": 2898.316, "day": "2019-05-22 10:50:00"}, {"volume": 290240500, "includeLow": 2897.484, "includeIndex": -1, "high": 2899.794, "includeHigh": 2899.794, "low": 2897.484, "includeTail": 0, "fenxing": 0, "close": 2897.936, "open": 2899.778, "day": "2019-05-22 10:55:00"}, {"volume": 390553700, "includeLow": 2897.491, "includeIndex": 115, "high": 2907.458, "includeHigh": 2907.458, "low": 2897.491, "includeTail": 0, "fenxing": 0, "close": 2904.302, "open": 2897.547, "day": "2019-05-22 11:00:00"}, {"volume": 213017100, "includeLow": 2902.008, "includeIndex": 115, "high": 2905.275, "includeHigh": 2907.458, "low": 2902.008, "includeTail": 0, "fenxing": 0, "close": 2903.929, "open": 2903.904, "day": "2019-05-22 11:05:00"}, {"volume": 207215300, "includeLow": 2903.059, "includeIndex": 115, "high": 2905.999, "includeHigh": 2907.458, "low": 2903.059, "includeTail": 0, "fenxing": 0, "close": 2905.598, "open": 2903.572, "day": "2019-05-22 11:10:00"}, {"volume": 238187100, "includeLow": 2904.536, "includeIndex": 115, "high": 2907.429, "includeHigh": 2907.458, "low": 2904.536, "includeTail": 1, "fenxing": 1, "close": 2904.536, "open": 2905.797, "day": "2019-05-22 11:15:00"}, {"volume": 168984400, "includeLow": 2904.014, "includeIndex": -1, "high": 2905.811, "includeHigh": 2905.811, "low": 2904.014, "includeTail": 0, "fenxing": 2, "close": 2904.184, "open": 2905.24, "day": "2019-05-22 11:20:00"}, {"volume": 180419300, "includeLow": 2904.037, "includeIndex": -1, "high": 2907.135, "includeHigh": 2907.135, "low": 2904.037, "includeTail": 0, "fenxing": 0, "close": 2906.795, "open": 2904.037, "day": "2019-05-22 11:25:00"}, {"volume": 220196500, "includeLow": 2905.204, "includeIndex": -1, "high": 2907.345, "includeHigh": 2907.345, "low": 2905.204, "includeTail": 0, "fenxing": 1, "close": 2905.204, "open": 2906.88, "day": "2019-05-22 11:30:00"}, {"volume": 338466000, "includeLow": 2902.46, "includeIndex": -1, "high": 2906.829, "includeHigh": 2906.829, "low": 2902.46, "includeTail": 0, "fenxing": 0, "close": 2902.834, "open": 2906.239, "day": "2019-05-22 13:05:00"}, {"volume": 208677800, "includeLow": 2899.287, "includeIndex": 123, "high": 2903.064, "includeHigh": 2903.064, "low": 2899.287, "includeTail": 0, "fenxing": 0, "close": 2900.191, "open": 2902.851, "day": "2019-05-22 13:10:00"}, {"volume": 194964000, "includeLow": 2899.287, "includeIndex": 123, "high": 2901.668, "includeHigh": 2901.668, "low": 2899.343, "includeTail": 1, "fenxing": 2, "close": 2901.498, "open": 2900.202, "day": "2019-05-22 13:15:00"}, {"volume": 187388700, "includeLow": 2899.84, "includeIndex": -1, "high": 2902.168, "includeHigh": 2902.168, "low": 2899.84, "includeTail": 0, "fenxing": 1, "close": 2899.84, "open": 2901.529, "day": "2019-05-22 13:20:00"}, {"volume": 256265500, "includeLow": 2897.232, "includeIndex": -1, "high": 2900.891, "includeHigh": 2900.891, "low": 2897.232, "includeTail": 0, "fenxing": 0, "close": 2897.232, "open": 2899.792, "day": "2019-05-22 13:25:00"}, {"volume": 431717500, "includeLow": 2892.897, "includeIndex": -1, "high": 2896.984, "includeHigh": 2896.984, "low": 2892.897, "includeTail": 0, "fenxing": 0, "close": 2893.291, "open": 2896.511, "day": "2019-05-22 13:30:00"}, {"volume": 449908900, "includeLow": 2888.612, "includeIndex": 128, "high": 2893.835, "includeHigh": 2893.835, "low": 2888.612, "includeTail": 0, "fenxing": 0, "close": 2890.519, "open": 2893.036, "day": "2019-05-22 13:35:00"}, {"volume": 277462000, "includeLow": 2888.612, "includeIndex": 128, "high": 2892.671, "includeHigh": 2892.671, "low": 2890.776, "includeTail": 1, "fenxing": 0, "close": 2890.947, "open": 2890.794, "day": "2019-05-22 13:40:00"}, {"volume": 463422400, "includeLow": 2885.806, "includeIndex": -1, "high": 2891.06, "includeHigh": 2891.06, "low": 2885.806, "includeTail": 0, "fenxing": 0, "close": 2885.993, "open": 2891.06, "day": "2019-05-22 13:45:00"}, {"volume": 367552800, "includeLow": 2885.685, "includeIndex": 131, "high": 2890.98, "includeHigh": 2890.98, "low": 2885.685, "includeTail": 0, "fenxing": 0, "close": 2889.322, "open": 2886.204, "day": "2019-05-22 13:50:00"}, {"volume": 267229700, "includeLow": 2885.685, "includeIndex": 131, "high": 2889.291, "includeHigh": 2889.291, "low": 2886.475, "includeTail": 1, "fenxing": 2, "close": 2889.215, "open": 2889.207, "day": "2019-05-22 13:55:00"}, {"volume": 216160300, "includeLow": 2888.573, "includeIndex": -1, "high": 2891.561, "includeHigh": 2891.561, "low": 2888.573, "includeTail": 0, "fenxing": 0, "close": 2891.561, "open": 2889.506, "day": "2019-05-22 14:00:00"}, {"volume": 223683300, "includeLow": 2889.491, "includeIndex": -1, "high": 2892.666, "includeHigh": 2892.666, "low": 2889.491, "includeTail": 0, "fenxing": 1, "close": 2889.792, "open": 2891.299, "day": "2019-05-22 14:05:00"}, {"volume": 391560000, "includeLow": 2882.86, "includeIndex": -1, "high": 2890.004, "includeHigh": 2890.004, "low": 2882.86, "includeTail": 0, "fenxing": 0, "close": 2883.539, "open": 2889.431, "day": "2019-05-22 14:10:00"}, {"volume": 306703900, "includeLow": 2882.846, "includeIndex": -1, "high": 2885.253, "includeHigh": 2885.253, "low": 2882.846, "includeTail": 0, "fenxing": 0, "close": 2882.92, "open": 2883.628, "day": "2019-05-22 14:15:00"}, {"volume": 538726400, "includeLow": 2879.644, "includeIndex": -1, "high": 2883.758, "includeHigh": 2883.758, "low": 2879.644, "includeTail": 0, "fenxing": 2, "close": 2883.57, "open": 2882.886, "day": "2019-05-22 14:20:00"}, {"volume": 360188600, "includeLow": 2883.275, "includeIndex": -1, "high": 2886.11, "includeHigh": 2886.11, "low": 2883.275, "includeTail": 0, "fenxing": 0, "close": 2886.11, "open": 2883.658, "day": "2019-05-22 14:25:00"}, {"volume": 352361400, "includeLow": 2883.82, "includeIndex": -1, "high": 2886.255, "includeHigh": 2886.255, "low": 2883.82, "includeTail": 0, "fenxing": 0, "close": 2884.413, "open": 2886.249, "day": "2019-05-22 14:30:00"}, {"volume": 314531500, "includeLow": 2884.326, "includeIndex": -1, "high": 2887.901, "includeHigh": 2887.901, "low": 2884.326, "includeTail": 0, "fenxing": 0, "close": 2887.427, "open": 2884.326, "day": "2019-05-22 14:35:00"}, {"volume": 397658900, "includeLow": 2887.197, "includeIndex": 141, "high": 2893.033, "includeHigh": 2893.033, "low": 2887.197, "includeTail": 0, "fenxing": 0, "close": 2891.178, "open": 2887.299, "day": "2019-05-22 14:40:00"}, {"volume": 374451500, "includeLow": 2890.247, "includeIndex": 141, "high": 2892.271, "includeHigh": 2893.033, "low": 2890.247, "includeTail": 1, "fenxing": 1, "close": 2890.962, "open": 2890.855, "day": "2019-05-22 14:45:00"}, {"volume": 401656100, "includeLow": 2888.243, "includeIndex": -1, "high": 2890.638, "includeHigh": 2890.638, "low": 2888.243, "includeTail": 0, "fenxing": 2, "close": 2888.934, "open": 2890.629, "day": "2019-05-22 14:50:00"}, {"volume": 527443800, "includeLow": 2888.603, "includeIndex": -1, "high": 2890.955, "includeHigh": 2890.955, "low": 2888.603, "includeTail": 0, "fenxing": 0, "close": 2890.473, "open": 2888.603, "day": "2019-05-22 14:55:00"}, {"volume": 531944800, "includeLow": 2890.168, "includeIndex": -1, "high": 2891.74, "includeHigh": 2891.74, "low": 2890.168, "includeTail": 0, "fenxing": 1, "close": 2891.705, "open": 2890.282, "day": "2019-05-22 15:00:00"}, {"volume": 1639545800, "includeLow": 2863.492, "includeIndex": -1, "high": 2880.843, "includeHigh": 2880.843, "low": 2863.492, "includeTail": 0, "fenxing": 0, "close": 2865.709, "open": 2880.843, "day": "2019-05-23 09:35:00"}, {"volume": 1158949200, "includeLow": 2857.974, "includeIndex": -1, "high": 2865.84, "includeHigh": 2865.84, "low": 2857.974, "includeTail": 0, "fenxing": 2, "close": 2862.941, "open": 2865.781, "day": "2019-05-23 09:40:00"}, {"volume": 792898200, "includeLow": 2858.497, "includeIndex": 148, "high": 2866.01, "includeHigh": 2866.01, "low": 2858.497, "includeTail": 0, "fenxing": 0, "close": 2859.365, "open": 2863.069, "day": "2019-05-23 09:45:00"}, {"volume": 736468300, "includeLow": 2859.233, "includeIndex": 148, "high": 2865.278, "includeHigh": 2866.01, "low": 2859.233, "includeTail": 1, "fenxing": 1, "close": 2863.186, "open": 2859.394, "day": "2019-05-23 09:50:00"}, {"volume": 577159100, "includeLow": 2857.976, "includeIndex": 150, "high": 2862.835, "includeHigh": 2862.835, "low": 2857.976, "includeTail": 0, "fenxing": 0, "close": 2860.623, "open": 2862.756, "day": "2019-05-23 09:55:00"}, {"volume": 525598900, "includeLow": 2857.976, "includeIndex": 150, "high": 2862.342, "includeHigh": 2862.342, "low": 2859.465, "includeTail": 1, "fenxing": 0, "close": 2859.661, "open": 2860.621, "day": "2019-05-23 10:00:00"}, {"volume": 607772100, "includeLow": 2854.674, "includeIndex": -1, "high": 2859.384, "includeHigh": 2859.384, "low": 2854.674, "includeTail": 0, "fenxing": 2, "close": 2857.752, "open": 2859.384, "day": "2019-05-23 10:05:00"}, {"volume": 433407600, "includeLow": 2855.385, "includeIndex": -1, "high": 2859.506, "includeHigh": 2859.506, "low": 2855.385, "includeTail": 0, "fenxing": 0, "close": 2859.394, "open": 2857.391, "day": "2019-05-23 10:10:00"}, {"volume": 378672600, "includeLow": 2858.735, "includeIndex": -1, "high": 2862.905, "includeHigh": 2862.905, "low": 2858.735, "includeTail": 0, "fenxing": 0, "close": 2862.238, "open": 2859.527, "day": "2019-05-23 10:15:00"}, {"volume": 319021700, "includeLow": 2861.206, "includeIndex": 155, "high": 2864.123, "includeHigh": 2864.123, "low": 2861.206, "includeTail": 0, "fenxing": 0, "close": 2861.905, "open": 2862.815, "day": "2019-05-23 10:20:00"}, {"volume": 293136800, "includeLow": 2861.206, "includeIndex": 155, "high": 2866.399, "includeHigh": 2866.399, "low": 2860.052, "includeTail": 1, "fenxing": 0, "close": 2866.399, "open": 2861.752, "day": "2019-05-23 10:25:00"}, {"volume": 297726600, "includeLow": 2864.238, "includeIndex": 157, "high": 2866.892, "includeHigh": 2866.892, "low": 2864.238, "includeTail": 0, "fenxing": 0, "close": 2864.98, "open": 2866.041, "day": "2019-05-23 10:30:00"}, {"volume": 436672100, "includeLow": 2864.238, "includeIndex": 157, "high": 2873.268, "includeHigh": 2873.268, "low": 2863.266, "includeTail": 1, "fenxing": 0, "close": 2873.05, "open": 2865.087, "day": "2019-05-23 10:35:00"}, {"volume": 396613700, "includeLow": 2871.141, "includeIndex": -1, "high": 2874.141, "includeHigh": 2874.141, "low": 2871.141, "includeTail": 0, "fenxing": 1, "close": 2871.79, "open": 2872.874, "day": "2019-05-23 10:40:00"}, {"volume": 253949300, "includeLow": 2870.539, "includeIndex": 160, "high": 2873.071, "includeHigh": 2873.071, "low": 2870.539, "includeTail": 0, "fenxing": 0, "close": 2871.136, "open": 2871.818, "day": "2019-05-23 10:45:00"}, {"volume": 318447800, "includeLow": 2870.509, "includeIndex": 160, "high": 2876.445, "includeHigh": 2873.071, "low": 2870.509, "includeTail": 1, "fenxing": 2, "close": 2876.056, "open": 2870.509, "day": "2019-05-23 10:50:00"}, {"volume": 466772300, "includeLow": 2875.764, "includeIndex": 162, "high": 2885.139, "includeHigh": 2885.139, "low": 2875.764, "includeTail": 0, "fenxing": 0, "close": 2883.444, "open": 2875.813, "day": "2019-05-23 10:55:00"}, {"volume": 283406300, "includeLow": 2876.231, "includeIndex": 162, "high": 2883.153, "includeHigh": 2885.139, "low": 2876.231, "includeTail": 1, "fenxing": 1, "close": 2876.755, "open": 2883.153, "day": "2019-05-23 11:00:00"}, {"volume": 240534300, "includeLow": 2872.303, "includeIndex": -1, "high": 2876.482, "includeHigh": 2876.482, "low": 2872.303, "includeTail": 0, "fenxing": 0, "close": 2872.587, "open": 2876.482, "day": "2019-05-23 11:05:00"}, {"volume": 235967000, "includeLow": 2868.699, "includeIndex": -1, "high": 2873.069, "includeHigh": 2873.069, "low": 2868.699, "includeTail": 0, "fenxing": 0, "close": 2869.41, "open": 2872.066, "day": "2019-05-23 11:10:00"}, {"volume": 218513800, "includeLow": 2867.045, "includeIndex": 166, "high": 2869.979, "includeHigh": 2869.979, "low": 2867.045, "includeTail": 0, "fenxing": 0, "close": 2869.132, "open": 2869.233, "day": "2019-05-23 11:15:00"}, {"volume": 179926100, "includeLow": 2867.045, "includeIndex": 166, "high": 2869.197, "includeHigh": 2869.197, "low": 2867.814, "includeTail": 1, "fenxing": 0, "close": 2868.87, "open": 2869.155, "day": "2019-05-23 11:20:00"}, {"volume": 205769000, "includeLow": 2865.71, "includeIndex": -1, "high": 2868.424, "includeHigh": 2868.424, "low": 2865.71, "includeTail": 0, "fenxing": 0, "close": 2865.884, "open": 2867.752, "day": "2019-05-23 11:25:00"}, {"volume": 268380600, "includeLow": 2862.722, "includeIndex": -1, "high": 2867.43, "includeHigh": 2867.43, "low": 2862.722, "includeTail": 0, "fenxing": 2, "close": 2867.258, "open": 2865.501, "day": "2019-05-23 11:30:00"}, {"volume": 257336700, "includeLow": 2863.675, "includeIndex": 170, "high": 2868.843, "includeHigh": 2868.843, "low": 2863.675, "includeTail": 0, "fenxing": 0, "close": 2863.894, "open": 2867.135, "day": "2019-05-23 13:05:00"}, {"volume": 233296900, "includeLow": 2863.675, "includeIndex": 170, "high": 2872.383, "includeHigh": 2872.383, "low": 2863.42, "includeTail": 0, "fenxing": 0, "close": 2869.345, "open": 2864.127, "day": "2019-05-23 13:10:00"}, {"volume": 173605300, "includeLow": 2866.723, "includeIndex": 170, "high": 2869.065, "includeHigh": 2872.383, "low": 2866.723, "includeTail": 1, "fenxing": 1, "close": 2868.444, "open": 2869.065, "day": "2019-05-23 13:15:00"}, {"volume": 180625700, "includeLow": 2866.331, "includeIndex": 173, "high": 2868.993, "includeHigh": 2868.993, "low": 2866.331, "includeTail": 0, "fenxing": 0, "close": 2868.646, "open": 2868.403, "day": "2019-05-23 13:20:00"}, {"volume": 295803200, "includeLow": 2862.414, "includeIndex": 173, "high": 2869.122, "includeHigh": 2868.993, "low": 2862.414, "includeTail": 1, "fenxing": 0, "close": 2862.691, "open": 2868.166, "day": "2019-05-23 13:25:00"}, {"volume": 314880400, "includeLow": 2862.094, "includeIndex": -1, "high": 2865.52, "includeHigh": 2865.52, "low": 2862.094, "includeTail": 0, "fenxing": 2, "close": 2865.16, "open": 2863.018, "day": "2019-05-23 13:30:00"}, {"volume": 301408000, "includeLow": 2864.89, "includeIndex": -1, "high": 2870.184, "includeHigh": 2870.184, "low": 2864.89, "includeTail": 0, "fenxing": 0, "close": 2870.184, "open": 2865.108, "day": "2019-05-23 13:35:00"}, {"volume": 311799800, "includeLow": 2866.04, "includeIndex": -1, "high": 2871.001, "includeHigh": 2871.001, "low": 2866.04, "includeTail": 0, "fenxing": 1, "close": 2866.376, "open": 2869.643, "day": "2019-05-23 13:40:00"}, {"volume": 267665200, "includeLow": 2865.131, "includeIndex": -1, "high": 2866.925, "includeHigh": 2866.925, "low": 2865.131, "includeTail": 0, "fenxing": 0, "close": 2865.435, "open": 2865.948, "day": "2019-05-23 13:45:00"}, {"volume": 331050400, "includeLow": 2863.525, "includeIndex": -1, "high": 2866.262, "includeHigh": 2866.262, "low": 2863.525, "includeTail": 0, "fenxing": 0, "close": 2863.525, "open": 2865.813, "day": "2019-05-23 13:50:00"}, {"volume": 477346600, "includeLow": 2859.738, "includeIndex": 180, "high": 2863.742, "includeHigh": 2863.742, "low": 2859.738, "includeTail": 0, "fenxing": 0, "close": 2861.673, "open": 2863.742, "day": "2019-05-23 13:55:00"}, {"volume": 262291200, "includeLow": 2859.738, "includeIndex": 180, "high": 2862.665, "includeHigh": 2862.665, "low": 2861.019, "includeTail": 1, "fenxing": 0, "close": 2861.097, "open": 2861.347, "day": "2019-05-23 14:00:00"}, {"volume": 295073400, "includeLow": 2859.333, "includeIndex": -1, "high": 2862.088, "includeHigh": 2862.088, "low": 2859.333, "includeTail": 0, "fenxing": 0, "close": 2859.333, "open": 2861.144, "day": "2019-05-23 14:05:00"}, {"volume": 483564700, "includeLow": 2854.976, "includeIndex": 183, "high": 2859.288, "includeHigh": 2859.288, "low": 2854.976, "includeTail": 0, "fenxing": 0, "close": 2857.617, "open": 2859.27, "day": "2019-05-23 14:10:00"}, {"volume": 299623900, "includeLow": 2854.976, "includeIndex": 183, "high": 2858.77, "includeHigh": 2858.77, "low": 2856.707, "includeTail": 1, "fenxing": 2, "close": 2857.935, "open": 2857.998, "day": "2019-05-23 14:15:00"}, {"volume": 323969400, "includeLow": 2856.768, "includeIndex": -1, "high": 2861.857, "includeHigh": 2861.857, "low": 2856.768, "includeTail": 0, "fenxing": 0, "close": 2861.703, "open": 2857.712, "day": "2019-05-23 14:20:00"}, {"volume": 288697000, "includeLow": 2861.641, "includeIndex": -1, "high": 2864.745, "includeHigh": 2864.745, "low": 2861.641, "includeTail": 0, "fenxing": 1, "close": 2862.017, "open": 2861.715, "day": "2019-05-23 14:25:00"}, {"volume": 261261700, "includeLow": 2857.638, "includeIndex": -1, "high": 2862.3, "includeHigh": 2862.3, "low": 2857.638, "includeTail": 0, "fenxing": 0, "close": 2857.792, "open": 2861.982, "day": "2019-05-23 14:30:00"}, {"volume": 394827200, "includeLow": 2853.1, "includeIndex": -1, "high": 2857.425, "includeHigh": 2857.425, "low": 2853.1, "includeTail": 0, "fenxing": 0, "close": 2853.459, "open": 2857.3, "day": "2019-05-23 14:35:00"}, {"volume": 404214900, "includeLow": 2852.697, "includeIndex": -1, "high": 2854.695, "includeHigh": 2854.695, "low": 2852.697, "includeTail": 0, "fenxing": 0, "close": 2853.278, "open": 2853.537, "day": "2019-05-23 14:40:00"}, {"volume": 663991500, "includeLow": 2847.613, "includeIndex": -1, "high": 2853.341, "includeHigh": 2853.341, "low": 2847.613, "includeTail": 0, "fenxing": 0, "close": 2847.939, "open": 2853.341, "day": "2019-05-23 14:45:00"}, {"volume": 513873200, "includeLow": 2846.956, "includeIndex": -1, "high": 2850.843, "includeHigh": 2850.843, "low": 2846.956, "includeTail": 0, "fenxing": 2, "close": 2849.536, "open": 2847.424, "day": "2019-05-23 14:50:00"}, {"volume": 585215600, "includeLow": 2848.588, "includeIndex": -1, "high": 2851.685, "includeHigh": 2851.685, "low": 2848.588, "includeTail": 0, "fenxing": 0, "close": 2851.438, "open": 2849.198, "day": "2019-05-23 14:55:00"}, {"volume": 543400600, "includeLow": 2851.551, "includeIndex": 193, "high": 2853.239, "includeHigh": 2853.239, "low": 2851.551, "includeTail": 0, "fenxing": 0, "close": 2852.515, "open": 2851.789, "day": "2019-05-23 15:00:00"}, {"volume": 1509061300, "includeLow": 2851.551, "includeIndex": 193, "high": 2866.766, "includeHigh": 2866.766, "low": 2847.836, "includeTail": 1, "fenxing": 0, "close": 2861.495, "open": 2847.836, "day": "2019-05-24 09:35:00"}, {"volume": 833435400, "includeLow": 2861.035, "includeIndex": -1, "high": 2870.773, "includeHigh": 2870.773, "low": 2861.035, "includeTail": 0, "fenxing": 0, "close": 2870.581, "open": 2861.035, "day": "2019-05-24 09:40:00"}, {"volume": 618686900, "includeLow": 2866.929, "includeIndex": -1, "high": 2871.856, "includeHigh": 2871.856, "low": 2866.929, "includeTail": 0, "fenxing": 1, "close": 2868.369, "open": 2870.362, "day": "2019-05-24 09:45:00"}, {"volume": 702356000, "includeLow": 2856.783, "includeIndex": 197, "high": 2868.124, "includeHigh": 2868.124, "low": 2856.783, "includeTail": 0, "fenxing": 0, "close": 2861.99, "open": 2868.124, "day": "2019-05-24 09:50:00"}, {"volume": 508129500, "includeLow": 2856.783, "includeIndex": 197, "high": 2863.021, "includeHigh": 2863.021, "low": 2858.448, "includeTail": 1, "fenxing": 2, "close": 2863.021, "open": 2861.543, "day": "2019-05-24 09:55:00"}, {"volume": 552279700, "includeLow": 2860.164, "includeIndex": -1, "high": 2868.198, "includeHigh": 2868.198, "low": 2860.164, "includeTail": 0, "fenxing": 1, "close": 2861.369, "open": 2862.884, "day": "2019-05-24 10:00:00"}, {"volume": 381784800, "includeLow": 2859.627, "includeIndex": -1, "high": 2862.306, "includeHigh": 2862.306, "low": 2859.627, "includeTail": 0, "fenxing": 0, "close": 2860.091, "open": 2861.808, "day": "2019-05-24 10:05:00"}, {"volume": 559147100, "includeLow": 2853.142, "includeIndex": -1, "high": 2860.112, "includeHigh": 2860.112, "low": 2853.142, "includeTail": 0, "fenxing": 0, "close": 2853.142, "open": 2859.919, "day": "2019-05-24 10:10:00"}, {"volume": 601028000, "includeLow": 2847.54, "includeIndex": -1, "high": 2855.025, "includeHigh": 2855.025, "low": 2847.54, "includeTail": 0, "fenxing": 2, "close": 2854.215, "open": 2852.554, "day": "2019-05-24 10:15:00"}, {"volume": 307707800, "includeLow": 2852.568, "includeIndex": 203, "high": 2855.584, "includeHigh": 2855.584, "low": 2852.568, "includeTail": 0, "fenxing": 0, "close": 2855.052, "open": 2854.128, "day": "2019-05-24 10:20:00"}, {"volume": 260487000, "includeLow": 2852.568, "includeIndex": 203, "high": 2856.406, "includeHigh": 2856.406, "low": 2852.356, "includeTail": 1, "fenxing": 1, "close": 2852.505, "open": 2855.294, "day": "2019-05-24 10:25:00"}, {"volume": 312941600, "includeLow": 2851.25, "includeIndex": -1, "high": 2855.412, "includeHigh": 2855.412, "low": 2851.25, "includeTail": 0, "fenxing": 0, "close": 2853.171, "open": 2852.822, "day": "2019-05-24 10:30:00"}, {"volume": 263523100, "includeLow": 2849.867, "includeIndex": -1, "high": 2853.235, "includeHigh": 2853.235, "low": 2849.867, "includeTail": 0, "fenxing": 0, "close": 2852.11, "open": 2853.107, "day": "2019-05-24 10:35:00"}, {"volume": 255793400, "includeLow": 2849.039, "includeIndex": -1, "high": 2852.343, "includeHigh": 2852.343, "low": 2849.039, "includeTail": 0, "fenxing": 2, "close": 2850.061, "open": 2852.343, "day": "2019-05-24 10:40:00"}, {"volume": 262630100, "includeLow": 2849.409, "includeIndex": 208, "high": 2855.297, "includeHigh": 2855.297, "low": 2849.409, "includeTail": 0, "fenxing": 0, "close": 2854.463, "open": 2849.409, "day": "2019-05-24 10:45:00"}, {"volume": 178238700, "includeLow": 2851.859, "includeIndex": 208, "high": 2854.465, "includeHigh": 2855.297, "low": 2851.859, "includeTail": 0, "fenxing": 0, "close": 2852.096, "open": 2854.291, "day": "2019-05-24 10:50:00"}, {"volume": 167187600, "includeLow": 2851.963, "includeIndex": 208, "high": 2855.119, "includeHigh": 2855.297, "low": 2851.963, "includeTail": 1, "fenxing": 0, "close": 2855.119, "open": 2851.996, "day": "2019-05-24 10:55:00"}, {"volume": 360605000, "includeLow": 2855.157, "includeIndex": -1, "high": 2863.595, "includeHigh": 2863.595, "low": 2855.157, "includeTail": 0, "fenxing": 0, "close": 2863.24, "open": 2855.214, "day": "2019-05-24 11:00:00"}, {"volume": 245358300, "includeLow": 2863.379, "includeIndex": -1, "high": 2865.052, "includeHigh": 2865.052, "low": 2863.379, "includeTail": 0, "fenxing": 1, "close": 2863.379, "open": 2863.764, "day": "2019-05-24 11:05:00"}, {"volume": 245333200, "includeLow": 2859.059, "includeIndex": -1, "high": 2864.006, "includeHigh": 2864.006, "low": 2859.059, "includeTail": 0, "fenxing": 0, "close": 2859.241, "open": 2863.905, "day": "2019-05-24 11:10:00"}, {"volume": 174330700, "includeLow": 2856.677, "includeIndex": -1, "high": 2859.627, "includeHigh": 2859.627, "low": 2856.677, "includeTail": 0, "fenxing": 0, "close": 2858.49, "open": 2859.355, "day": "2019-05-24 11:15:00"}, {"volume": 210487000, "includeLow": 2855.745, "includeIndex": -1, "high": 2858.594, "includeHigh": 2858.594, "low": 2855.745, "includeTail": 0, "fenxing": 2, "close": 2858.434, "open": 2857.111, "day": "2019-05-24 11:20:00"}, {"volume": 231531000, "includeLow": 2856.625, "includeIndex": -1, "high": 2858.926, "includeHigh": 2858.926, "low": 2856.625, "includeTail": 0, "fenxing": 1, "close": 2856.625, "open": 2858.508, "day": "2019-05-24 11:25:00"}, {"volume": 280668200, "includeLow": 2850.897, "includeIndex": -1, "high": 2856.435, "includeHigh": 2856.435, "low": 2850.897, "includeTail": 0, "fenxing": 0, "close": 2851.367, "open": 2856.328, "day": "2019-05-24 11:30:00"}, {"volume": 328201800, "includeLow": 2849.527, "includeIndex": -1, "high": 2851.503, "includeHigh": 2851.503, "low": 2849.527, "includeTail": 0, "fenxing": 0, "close": 2849.63, "open": 2851.503, "day": "2019-05-24 13:05:00"}, {"volume": 269793400, "includeLow": 2846.322, "includeIndex": -1, "high": 2850.286, "includeHigh": 2850.286, "low": 2846.322, "includeTail": 0, "fenxing": 2, "close": 2848.113, "open": 2850.234, "day": "2019-05-24 13:10:00"}, {"volume": 185695200, "includeLow": 2848.146, "includeIndex": 220, "high": 2850.834, "includeHigh": 2850.834, "low": 2848.146, "includeTail": 0, "fenxing": 0, "close": 2850.585, "open": 2848.63, "day": "2019-05-24 13:15:00"}, {"volume": 172012000, "includeLow": 2848.146, "includeIndex": 220, "high": 2851.136, "includeHigh": 2851.136, "low": 2847.661, "includeTail": 0, "fenxing": 0, "close": 2848.131, "open": 2850.105, "day": "2019-05-24 13:20:00"}, {"volume": 221813100, "includeLow": 2848.146, "includeIndex": 220, "high": 2851.218, "includeHigh": 2851.218, "low": 2847.104, "includeTail": 1, "fenxing": 0, "close": 2851.048, "open": 2848.172, "day": "2019-05-24 13:25:00"}, {"volume": 193178300, "includeLow": 2850.69, "includeIndex": -1, "high": 2854.159, "includeHigh": 2854.159, "low": 2850.69, "includeTail": 0, "fenxing": 0, "close": 2854.159, "open": 2850.898, "day": "2019-05-24 13:30:00"}, {"volume": 242765300, "includeLow": 2853.938, "includeIndex": -1, "high": 2857.431, "includeHigh": 2857.431, "low": 2853.938, "includeTail": 0, "fenxing": 0, "close": 2856.104, "open": 2854.126, "day": "2019-05-24 13:35:00"}, {"volume": 162502700, "includeLow": 2854.898, "includeIndex": 225, "high": 2857.453, "includeHigh": 2857.453, "low": 2854.898, "includeTail": 0, "fenxing": 0, "close": 2856.808, "open": 2856.42, "day": "2019-05-24 13:40:00"}, {"volume": 213668500, "includeLow": 2854.898, "includeIndex": 225, "high": 2858.257, "includeHigh": 2858.257, "low": 2853.881, "includeTail": 1, "fenxing": 1, "close": 2854.091, "open": 2857.131, "day": "2019-05-24 13:45:00"}, {"volume": 182013600, "includeLow": 2852.35, "includeIndex": -1, "high": 2855.052, "includeHigh": 2855.052, "low": 2852.35, "includeTail": 0, "fenxing": 2, "close": 2854.696, "open": 2854.785, "day": "2019-05-24 13:50:00"}, {"volume": 177235800, "includeLow": 2854.955, "includeIndex": -1, "high": 2857.563, "includeHigh": 2857.563, "low": 2854.955, "includeTail": 0, "fenxing": 1, "close": 2856.075, "open": 2855.241, "day": "2019-05-24 13:55:00"}, {"volume": 176871100, "includeLow": 2854.725, "includeIndex": -1, "high": 2855.995, "includeHigh": 2855.995, "low": 2854.725, "includeTail": 0, "fenxing": 2, "close": 2854.826, "open": 2855.691, "day": "2019-05-24 14:00:00"}, {"volume": 222794000, "includeLow": 2854.946, "includeIndex": -1, "high": 2858.38, "includeHigh": 2858.38, "low": 2854.946, "includeTail": 0, "fenxing": 1, "close": 2856.711, "open": 2854.946, "day": "2019-05-24 14:05:00"}, {"volume": 307744900, "includeLow": 2850.523, "includeIndex": -1, "high": 2857.216, "includeHigh": 2857.216, "low": 2850.523, "includeTail": 0, "fenxing": 0, "close": 2850.523, "open": 2857.118, "day": "2019-05-24 14:10:00"}, {"volume": 280990800, "includeLow": 2848.405, "includeIndex": 232, "high": 2851.53, "includeHigh": 2851.53, "low": 2848.405, "includeTail": 0, "fenxing": 0, "close": 2848.631, "open": 2850.592, "day": "2019-05-24 14:15:00"}, {"volume": 317875800, "includeLow": 2847.643, "includeIndex": 232, "high": 2851.93, "includeHigh": 2851.53, "low": 2847.643, "includeTail": 1, "fenxing": 2, "close": 2851.93, "open": 2849.011, "day": "2019-05-24 14:20:00"}, {"volume": 260396200, "includeLow": 2851.898, "includeIndex": -1, "high": 2855.991, "includeHigh": 2855.991, "low": 2851.898, "includeTail": 0, "fenxing": 0, "close": 2855.991, "open": 2852.153, "day": "2019-05-24 14:25:00"}, {"volume": 448089800, "includeLow": 2856.166, "includeIndex": 235, "high": 2863.868, "includeHigh": 2863.868, "low": 2856.166, "includeTail": 0, "fenxing": 0, "close": 2863.583, "open": 2856.331, "day": "2019-05-24 14:30:00"}, {"volume": 300718100, "includeLow": 2857.138, "includeIndex": 235, "high": 2863.836, "includeHigh": 2863.868, "low": 2857.138, "includeTail": 1, "fenxing": 1, "close": 2857.692, "open": 2863.778, "day": "2019-05-24 14:35:00"}, {"volume": 247498100, "includeLow": 2856.633, "includeIndex": -1, "high": 2858.454, "includeHigh": 2858.454, "low": 2856.633, "includeTail": 0, "fenxing": 0, "close": 2856.709, "open": 2857.684, "day": "2019-05-24 14:40:00"}, {"volume": 349442800, "includeLow": 2855.135, "includeIndex": -1, "high": 2857.114, "includeHigh": 2857.114, "low": 2855.135, "includeTail": 0, "fenxing": 0, "close": 2855.924, "open": 2857.114, "day": "2019-05-24 14:45:00"}, {"volume": 427318100, "includeLow": 2852.913, "includeIndex": -1, "high": 2855.958, "includeHigh": 2855.958, "low": 2852.913, "includeTail": 0, "fenxing": 0, "close": 2853.287, "open": 2855.306, "day": "2019-05-24 14:50:00"}, {"volume": 529523700, "includeLow": 2851.206, "includeIndex": 240, "high": 2853.297, "includeHigh": 2853.297, "low": 2851.206, "includeTail": 0, "fenxing": 0, "close": 2852.186, "open": 2853.297, "day": "2019-05-24 14:55:00"}, {"volume": 474704300, "includeLow": 2851.206, "includeIndex": 240, "high": 2853.273, "includeHigh": 2853.273, "low": 2851.606, "includeTail": 0, "fenxing": 0, "close": 2852.995, "open": 2852.256, "day": "2019-05-24 15:00:00"}, {"volume": 1185171500, "includeLow": 2840.715, "includeIndex": 240, "high": 2855.769, "includeHigh": 2853.273, "low": 2840.715, "includeTail": 0, "fenxing": 0, "close": 2840.952, "open": 2851.281, "day": "2019-05-27 09:35:00"}, {"volume": 906867100, "includeLow": 2840.282, "includeIndex": 240, "high": 2858.14, "includeHigh": 2853.273, "low": 2840.282, "includeTail": 1, "fenxing": 2, "close": 2854.98, "open": 2841.218, "day": "2019-05-27 09:40:00"}, {"volume": 562908600, "includeLow": 2851.547, "includeIndex": -1, "high": 2856.835, "includeHigh": 2856.835, "low": 2851.547, "includeTail": 0, "fenxing": 1, "close": 2856.835, "open": 2854.646, "day": "2019-05-27 09:45:00"}, {"volume": 480479000, "includeLow": 2848.907, "includeIndex": -1, "high": 2856.441, "includeHigh": 2856.441, "low": 2848.907, "includeTail": 0, "fenxing": 0, "close": 2849.651, "open": 2856.441, "day": "2019-05-27 09:50:00"}, {"volume": 396045000, "includeLow": 2846.923, "includeIndex": -1, "high": 2850.655, "includeHigh": 2850.655, "low": 2846.923, "includeTail": 0, "fenxing": 2, "close": 2850.319, "open": 2849.767, "day": "2019-05-27 09:55:00"}, {"volume": 356482100, "includeLow": 2848.709, "includeIndex": -1, "high": 2851.915, "includeHigh": 2851.915, "low": 2848.709, "includeTail": 0, "fenxing": 1, "close": 2850.369, "open": 2850.508, "day": "2019-05-27 10:00:00"}, {"volume": 313279100, "includeLow": 2846.542, "includeIndex": 248, "high": 2850.356, "includeHigh": 2850.356, "low": 2846.542, "includeTail": 0, "fenxing": 0, "close": 2847.289, "open": 2850.151, "day": "2019-05-27 10:05:00"}, {"volume": 316048100, "includeLow": 2846.542, "includeIndex": 248, "high": 2850.03, "includeHigh": 2850.03, "low": 2847.269, "includeTail": 0, "fenxing": 0, "close": 2848.449, "open": 2847.557, "day": "2019-05-27 10:10:00"}, {"volume": 269332400, "includeLow": 2846.542, "includeIndex": 248, "high": 2849.523, "includeHigh": 2849.523, "low": 2846.722, "includeTail": 1, "fenxing": 0, "close": 2847.195, "open": 2848.078, "day": "2019-05-27 10:15:00"}, {"volume": 284708800, "includeLow": 2844.323, "includeIndex": -1, "high": 2848.122, "includeHigh": 2848.122, "low": 2844.323, "includeTail": 0, "fenxing": 0, "close": 2844.323, "open": 2847.075, "day": "2019-05-27 10:20:00"}, {"volume": 389770000, "includeLow": 2839.868, "includeIndex": -1, "high": 2844.743, "includeHigh": 2844.743, "low": 2839.868, "includeTail": 0, "fenxing": 2, "close": 2843.524, "open": 2844.55, "day": "2019-05-27 10:25:00"}, {"volume": 270240500, "includeLow": 2843.056, "includeIndex": -1, "high": 2846.11, "includeHigh": 2846.11, "low": 2843.056, "includeTail": 0, "fenxing": 0, "close": 2844.955, "open": 2843.395, "day": "2019-05-27 10:30:00"}, {"volume": 285526900, "includeLow": 2843.686, "includeIndex": 254, "high": 2850.352, "includeHigh": 2850.352, "low": 2843.686, "includeTail": 0, "fenxing": 0, "close": 2849.709, "open": 2845.28, "day": "2019-05-27 10:35:00"}, {"volume": 236379000, "includeLow": 2846.178, "includeIndex": 254, "high": 2850.329, "includeHigh": 2850.352, "low": 2846.178, "includeTail": 1, "fenxing": 1, "close": 2846.178, "open": 2850.329, "day": "2019-05-27 10:40:00"}, {"volume": 253206700, "includeLow": 2844.932, "includeIndex": -1, "high": 2847.824, "includeHigh": 2847.824, "low": 2844.932, "includeTail": 0, "fenxing": 0, "close": 2846.297, "open": 2845.78, "day": "2019-05-27 10:45:00"}, {"volume": 204690800, "includeLow": 2843.57, "includeIndex": -1, "high": 2846.312, "includeHigh": 2846.312, "low": 2843.57, "includeTail": 0, "fenxing": 0, "close": 2843.57, "open": 2846.246, "day": "2019-05-27 10:50:00"}, {"volume": 248391100, "includeLow": 2841.666, "includeIndex": -1, "high": 2845.112, "includeHigh": 2845.112, "low": 2841.666, "includeTail": 0, "fenxing": 0, "close": 2843.629, "open": 2843.401, "day": "2019-05-27 10:55:00"}, {"volume": 234439700, "includeLow": 2839.891, "includeIndex": -1, "high": 2843.349, "includeHigh": 2843.349, "low": 2839.891, "includeTail": 0, "fenxing": 0, "close": 2840.352, "open": 2843.349, "day": "2019-05-27 11:00:00"}, {"volume": 202380300, "includeLow": 2838.703, "includeIndex": -1, "high": 2840.703, "includeHigh": 2840.703, "low": 2838.703, "includeTail": 0, "fenxing": 0, "close": 2839.776, "open": 2840.116, "day": "2019-05-27 11:05:00"}, {"volume": 399140200, "includeLow": 2833.036, "includeIndex": -1, "high": 2839.942, "includeHigh": 2839.942, "low": 2833.036, "includeTail": 0, "fenxing": 2, "close": 2839.298, "open": 2839.942, "day": "2019-05-27 11:10:00"}, {"volume": 244896300, "includeLow": 2838.954, "includeIndex": 262, "high": 2844.377, "includeHigh": 2844.377, "low": 2838.954, "includeTail": 0, "fenxing": 0, "close": 2842.983, "open": 2838.954, "day": "2019-05-27 11:15:00"}, {"volume": 149100000, "includeLow": 2840.135, "includeIndex": 262, "high": 2842.946, "includeHigh": 2844.377, "low": 2840.135, "includeTail": 1, "fenxing": 0, "close": 2841.356, "open": 2842.884, "day": "2019-05-27 11:20:00"}, {"volume": 283492200, "includeLow": 2840.887, "includeIndex": -1, "high": 2849.953, "includeHigh": 2849.953, "low": 2840.887, "includeTail": 0, "fenxing": 0, "close": 2849.953, "open": 2840.965, "day": "2019-05-27 11:25:00"}, {"volume": 561879100, "includeLow": 2850.776, "includeIndex": -1, "high": 2860.642, "includeHigh": 2860.642, "low": 2850.776, "includeTail": 0, "fenxing": 0, "close": 2860.509, "open": 2850.776, "day": "2019-05-27 11:30:00"}, {"volume": 624070000, "includeLow": 2860.734, "includeIndex": -1, "high": 2865.8, "includeHigh": 2865.8, "low": 2860.734, "includeTail": 0, "fenxing": 0, "close": 2863.504, "open": 2860.883, "day": "2019-05-27 13:05:00"}, {"volume": 406149100, "includeLow": 2863.35, "includeIndex": -1, "high": 2866.224, "includeHigh": 2866.224, "low": 2863.35, "includeTail": 0, "fenxing": 0, "close": 2864.711, "open": 2863.734, "day": "2019-05-27 13:10:00"}, {"volume": 660211200, "includeLow": 2864.417, "includeIndex": -1, "high": 2877.342, "includeHigh": 2877.342, "low": 2864.417, "includeTail": 0, "fenxing": 0, "close": 2877.342, "open": 2864.417, "day": "2019-05-27 13:15:00"}, {"volume": 416279400, "includeLow": 2873.367, "includeIndex": 269, "high": 2878.103, "includeHigh": 2878.103, "low": 2873.367, "includeTail": 0, "fenxing": 0, "close": 2873.55, "open": 2877.556, "day": "2019-05-27 13:20:00"}, {"volume": 426314000, "includeLow": 2873.508, "includeIndex": 269, "high": 2877.255, "includeHigh": 2878.103, "low": 2873.508, "includeTail": 1, "fenxing": 0, "close": 2876.943, "open": 2873.672, "day": "2019-05-27 13:25:00"}, {"volume": 574446200, "includeLow": 2876.701, "includeIndex": -1, "high": 2884.96, "includeHigh": 2884.96, "low": 2876.701, "includeTail": 0, "fenxing": 0, "close": 2884.96, "open": 2876.827, "day": "2019-05-27 13:30:00"}, {"volume": 542385800, "includeLow": 2882.749, "includeIndex": 272, "high": 2887.38, "includeHigh": 2887.38, "low": 2882.749, "includeTail": 0, "fenxing": 0, "close": 2883.233, "open": 2884.988, "day": "2019-05-27 13:35:00"}, {"volume": 378072700, "includeLow": 2882.892, "includeIndex": 272, "high": 2884.363, "includeHigh": 2887.38, "low": 2882.892, "includeTail": 1, "fenxing": 1, "close": 2883.509, "open": 2883.356, "day": "2019-05-27 13:40:00"}, {"volume": 365180500, "includeLow": 2878.882, "includeIndex": -1, "high": 2883.192, "includeHigh": 2883.192, "low": 2878.882, "includeTail": 0, "fenxing": 2, "close": 2878.882, "open": 2883.192, "day": "2019-05-27 13:45:00"}, {"volume": 217402800, "includeLow": 2879.06, "includeIndex": -1, "high": 2883.481, "includeHigh": 2883.481, "low": 2879.06, "includeTail": 0, "fenxing": 0, "close": 2882.745, "open": 2879.06, "day": "2019-05-27 13:50:00"}]} -------------------------------------------------------------------------------- /static/key.txt: -------------------------------------------------------------------------------- 1 | Ni22sQDNsxAGMywENGxQjY3kzYiBOWzMzNiNWN4IY2jFzNih -------------------------------------------------------------------------------- /static/kline.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 |