Exemplo n.º 1
0
    def update_bars_backward(self, n):
        if self.data_source == 'HK':
            with self.chart.updating() as chart:
                symbol = self.symbol_line.text()
                start = chart._manager.get_bar(chart.last_ix).datetime
                data = self._querier[start:n:symbol]

                for d in data:
                    b = BarData('KRData', symbol, Exchange.HKFE, d.datetime, None,
                                d.volume, 0, d.open, d.high, d.low, d.close)
                    chart.update_bar(b)
        elif self.data_source == 'IB':
            with self.chart.updating() as chart:
                symbol = self.symbol_line.text()
                barType = {'1min': '1 min', '5min': '5 mins', '15min': '15 mins', '30min': '30 mins', '60min': '60 mins', '1day': '1 day'}.get(self.period,'1 min')
                minutes = {'1min': 1, '5min': 5, '15min': 15, '30min': 30, '60min': 60, '1day': 1440}.get(self.period, 1)
                start = chart._manager.get_bar(chart.last_ix).datetime
                per_bar_period = dt.timedelta(minutes=minutes)
                if dt.datetime.now() - start <= per_bar_period:
                    return
                n = min(60, n)
                contract = self._querier.verifyContract(symbol)
                data = self._querier.get_bars_from_ib(contract, barType=barType, start=start, end=start + per_bar_period * n)
                for _, d in data.iterrows():
                    b = BarData('KRData', symbol, Exchange.HKFE, d.datetime, None,
                                d.volume, 0, d.open, d.high, d.low, d.close)
                    chart.update_bar(b)
Exemplo n.º 2
0
    def on_tick(self, tick: TickData):
        """收到行情TICK推送(必须由用户继承实现)"""
        # 聚合为1分钟K线
        tickMinute = tick.datetime.minute

        if tickMinute != self.barMinute:
            if self.bar:
                self.on_bar(self.bar)

            bar = BarData(datetime=tick.datetime,
                          exchange=tick.exchange,
                          gateway_name=tick.gateway_name,
                          symbol=tick.symbol)

            # bar.vt_symbol = tick.vt_symbol
            # bar.symbol = tick.symbol
            # bar.exchange = tick.exchange

            bar.open_price = tick.last_price
            bar.high_price = tick.last_price
            bar.low_price = tick.last_price
            bar.close_price = tick.last_price

            # bar.date = tick.date
            # bar.time = tick.time
            bar.datetime = tick.datetime  # K线的时间设为第一个Tick的时间

            self.bar = bar  # 这种写法为了减少一层访问,加快速度
            self.barMinute = tickMinute  # 更新当前的分钟
        else:  # 否则继续累加新的K线
            bar = self.bar  # 写法同样为了加快速度

            bar.high_price = max(bar.high_price, tick.last_price)
            bar.low_price = min(bar.low_price, tick.last_price)
            bar.close_price = tick.last_price
Exemplo n.º 3
0
def load_bar_data(
    spread: SpreadData,
    interval: Interval,
    start: datetime,
    end: datetime,
    pricetick: float = 0
):
    """"""
    # Load bar data of each spread leg
    leg_bars: Dict[str, Dict] = {}

    for vt_symbol in spread.legs.keys():
        symbol, exchange = extract_vt_symbol(vt_symbol)

        bar_data: List[BarData] = database_manager.load_bar_data(
            symbol, exchange, interval, start, end
        )

        bars: Dict[datetime, BarData] = {bar.datetime: bar for bar in bar_data}
        leg_bars[vt_symbol] = bars

    # Calculate spread bar data
    spread_bars: List[BarData] = []

    for dt in bars.keys():
        spread_price = 0
        spread_value = 0
        spread_available = True

        for leg in spread.legs.values():
            leg_bar = leg_bars[leg.vt_symbol].get(dt, None)

            if leg_bar:
                price_multiplier = spread.price_multipliers[leg.vt_symbol]
                spread_price += price_multiplier * leg_bar.close_price
                spread_value += abs(price_multiplier) * leg_bar.close_price
            else:
                spread_available = False

        if spread_available:
            if pricetick:
                spread_price = round_to(spread_price, pricetick)

            spread_bar = BarData(
                symbol=spread.name,
                exchange=exchange.LOCAL,
                datetime=dt,
                interval=interval,
                open_price=spread_price,
                high_price=spread_price,
                low_price=spread_price,
                close_price=spread_price,
                gateway_name="SPREAD",
            )
            spread_bar.value = spread_value
            spread_bars.append(spread_bar)

    return spread_bars
Exemplo n.º 4
0
    def query_history(self, req: HistoryRequest):
        """"""
        self.write_log("FUTU Gateway:开始下载")
        print(f"FUTU download{req.symbol}")
        print(f"req.startdate:{req.start} - {req.end}")
        code = convert_symbol_vt2futu(req.symbol, req.exchange)
        start = req.start.strftime("%Y-%m-%d")
        end = req.end.strftime("%Y-%m-%d")

        ret, data, self.page_req_key = self.quote_ctx.request_history_kline(
            code,
            start=start,
            end=end,
            ktype=INTERVAL_KLINE_VT2FUTU[req.interval],
            max_count=1)
        dt = datetime.strptime(data.ix[0].time_key, "%Y-%m-%d %H:%M:%S")
        data_bar = BarData(gateway_name=self.gateway_name,
                           symbol=req.symbol,
                           exchange=req.exchange,
                           datetime=dt,
                           interval=req.interval,
                           volume=float(data.volume),
                           open_price=data.open,
                           high_price=data.high,
                           low_price=data.low,
                           close_price=data.close)
        self.history_list.append(data_bar)
        while self.page_req_key is not None:
            ret, data, self.page_req_key = self.quote_ctx.request_history_kline(
                code,
                start=start,
                end=end,
                ktype=INTERVAL_KLINE_VT2FUTU[req.interval],
                max_count=1000,
                page_req_key=self.page_req_key)
            # data append
            for index, df in data.iterrows():
                print(index, " df", df.time_key)
                dt = datetime.strptime(df.time_key, "%Y-%m-%d %H:%M:%S")
                data_bar = BarData(gateway_name=self.gateway_name,
                                   symbol=req.symbol,
                                   exchange=req.exchange,
                                   datetime=dt,
                                   interval=req.interval,
                                   volume=float(df.volume),
                                   open_price=df.open,
                                   high_price=df.high,
                                   low_price=df.low,
                                   close_price=df.close)
                self.history_list.append(data_bar)

        history = self.history_list
        self.history_list = []
        return history
    def query_history(self, req: HistoryRequest) -> Optional[List[BarData]]:

        symbol = req.symbol
        exchange = req.exchange
        interval = req.interval
        start = req.start
        end = req.end

        if exchange not in self.ex:
            print('不是Tushare支持的交易所')
            return None

        if interval == Interval.DAILY:
            if exchange in [
                    Exchange.SHFE, Exchange.CZCE, Exchange.CFFEX, Exchange.DCE,
                    Exchange.INE
            ]:
                df = self.pro.fut_daily(ts_code=self.to_ts_symbol(
                    symbol, exchange),
                                        asset='FT',
                                        start_date=start.strftime('%Y%m%d'),
                                        end_date=end.strftime('%Y%m%d'))
            elif exchange in [Exchange.SSE, Exchange.SZSE]:
                df = self.pro.daily(ts_code=self.to_ts_symbol(
                    symbol, exchange),
                                    start_date=start.strftime('%Y%m%d'),
                                    end_date=end.strftime('%Y%m%d'))
        else:
            df = self.pro.pro_bar(
                ts_code=self.to_ts_symbol(symbol, exchange),
                asset='FT' if exchange in [
                    Exchange.SHFE, Exchange.CZCE, Exchange.CFFEX, Exchange.DCE,
                    Exchange.INE
                ] else
                ('E' if exchange in [Exchange.SSE, Exchange.SZSE] else None),
                start_date=start.strftime('%Y%m%d'),
                end_date=end.strftime('%Y%m%d'),
                freq='60min' if interval == Interval.HOUR else
                ('1min' if interval == Interval.MINUTE else None))
        df = df.sort_index()

        data: List[BarData] = []

        if df is not None:
            for ix, row in df.iterrows():
                date = datetime.strptime(row.trade_date, '%Y%m%d')
                bar = BarData(
                    symbol=symbol,
                    exchange=exchange,
                    interval=interval,
                    datetime=date,
                    open_price=row['open'],
                    high_price=row['high'],
                    low_price=row['low'],
                    close_price=row['close'],
                    volume=row['amount'],
                    gateway_name='TS',
                )
                data.append(bar)
        return data
Exemplo n.º 6
0
    def load_bar_data(
        self,
        symbol: str,
        exchange: Exchange,
        interval: Interval,
        start: datetime,
        end: datetime
    ) -> List[BarData]:
        """读取K线数据"""
        filter = {
            "symbol": symbol,
            "exchange": exchange.value,
            "interval": interval.value,
            "datetime": {
                "$gte": start,
                "$lte": end
            }
        }

        c: Cursor = self.bar_collection.find(filter)

        bars = []
        for d in c:
            d["exchange"] = Exchange(d["exchange"])
            d["interval"] = Interval(d["interval"])
            d["gateway_name"] = "DB"
            d.pop("_id")

            bar = BarData(**d)
            bars.append(bar)

        return bars
Exemplo n.º 7
0
    def query_history(self, req: HistoryRequest,
                      frequency: int) -> Optional[List[BarData]]:
        """
        Query history bar data from TqSdk.
        """
        if self.symbols is None:
            return None

        symbol = req.symbol
        exchange = req.exchange
        interval = req.interval
        start = req.start
        end = req.end

        tq_symbol = self.to_tq_symbol(symbol, exchange)
        if tq_symbol not in self.symbols:
            return None

        # 若未从上层load_bar传入frequency,则返回空值
        if not frequency:
            return None

        # For querying night trading period data
        end += timedelta(minutes=1)

        # 获取最新的数据,无法指定日期
        df = self.api.get_kline_serial(tq_symbol, frequency,
                                       10000).sort_values(by=["datetime"])

        # 转换为东八区时间
        df["datetime"] = pd.to_datetime(df["datetime"] + TIME_UTC8)

        data: List[BarData] = []

        if frequency == 60:
            frequency = "1m"
        else:
            frequency = f"{frequency}s"

        if df is not None:
            for ix, row in df.iterrows():
                dt = CHINA_TZ.localize(
                    row.datetime.to_pydatetime().replace(tzinfo=None))

                bar = BarData(
                    symbol=symbol,
                    exchange=exchange,
                    interval=frequency,
                    datetime=dt,
                    open_price=row["open"],
                    high_price=row["high"],
                    low_price=row["low"],
                    close_price=row["close"],
                    volume=row["volume"],
                    open_interest=row.get("open_oi", 0),
                    gateway_name="TQ",
                )
                data.append(bar)

        return data
Exemplo n.º 8
0
    def historicalData(self, reqId: int, ib_bar: IbBarData):
        """
        Callback of history data update.
        """
        # When requesting daily and weekly history data, the date format is "%Y%m%d"
        if len(ib_bar.date) > 8:
            dt = datetime.strptime(ib_bar.date, "%Y%m%d %H:%M:%S")
        else:
            dt = datetime.strptime(ib_bar.date, "%Y%m%d")
        dt = self.local_tz.localize(dt)

        bar = BarData(
            symbol=self.history_req.symbol,
            exchange=self.history_req.exchange,
            datetime=dt,
            interval=self.history_req.interval,
            volume=ib_bar.volume,
            open_price=ib_bar.open,
            high_price=ib_bar.high,
            low_price=ib_bar.low,
            close_price=ib_bar.close,
            gateway_name=self.gateway_name
        )

        self.history_buf.append(bar)
Exemplo n.º 9
0
    def new_bars(self, dt: datetime) -> None:
        """"""
        self.datetime = dt

        bars: Dict[str, BarData] = {}
        for vt_symbol in self.vt_symbols:
            bar = self.history_data.get((dt, vt_symbol), None)

            # If bar data of vt_symbol at dt exists
            if bar:
                # Update bar data for crossing order
                self.bars[vt_symbol] = bar

                # Put bar into dict for strategy.on_bars update
                bars[vt_symbol] = bar
            # Otherwise, use previous close to backfill
            elif vt_symbol in self.bars:
                old_bar = self.bars[vt_symbol]

                bar = BarData(symbol=old_bar.symbol,
                              exchange=old_bar.exchange,
                              datetime=dt,
                              open_price=old_bar.close_price,
                              high_price=old_bar.close_price,
                              low_price=old_bar.close_price,
                              close_price=old_bar.close_price,
                              gateway_name=old_bar.gateway_name)
                self.bars[vt_symbol] = bar

        self.cross_limit_order()
        self.strategy.on_bars(bars)

        if self.strategy.inited:
            self.update_daily_close(self.bars, dt)
Exemplo n.º 10
0
    def importDataToVnpyDB(df: pd.DataFrame, stkid: str) -> None:
        bar_data = []
        TW_TZ = pytz.timezone("Asia/Taipei")

        if df is None:
            return print("資料不存在")

        for index, row in df.iterrows():
            bar = BarData(symbol=stkid,
                          exchange=Exchange.LOCAL,
                          datetime=TW_TZ.localize(row['ts'].to_pydatetime()) -
                          timedelta(minutes=1),
                          interval=Interval.MINUTE,
                          volume=row.Volume,
                          open_price=row.Open,
                          high_price=row.High,
                          low_price=row.Low,
                          close_price=row.Close,
                          gateway_name="Sinopac")

            bar_data.append(bar)

        database = get_database()
        database.save_bar_data(bar_data)
        print(
            f"股票代號:{stkid}|{bar_data[0].datetime}-{bar_data[-1].datetime} 歷史數據匯入成功,總共{len(bar_data)}筆資料"
        )
Exemplo n.º 11
0
def move_df_to_sql(imported_data: pd.DataFrame):
    bars = []
    start = None
    count = 0

    for row in imported_data.itertuples():

        bar = BarData(
            symbol=row.symbol,
            exchange=row.exchange,
            datetime=row.dtime,
            interval=row.interval,
            volume=row.volume,
            open_price=row.open,
            high_price=row.high,
            low_price=row.low,
            close_price=row.close,
            open_interest=row.o_interest,
            gateway_name="DB",
        )
        bars.append(bar)

        # do some statistics
        count += 1
        if not start:
            start = bar.datetime
    end = bar.datetime

    # insert into database
    database_manager.save_bar_data(bars)
    print(f'Insert Bar: {count} from {start} - {end}')
Exemplo n.º 12
0
    def load_bar_data(self, filter: dict) -> List[BarData]:
        """加载历史数据"""

        if self.bar_collection.count_documents(filter) == 0:
            self.output("无符合条件的历史数据")
            return

        else:
            bars = []

            c: Cursor = self.bar_collection.find(filter)

            for d in c:
                d["exchange"] = Exchange(d["exchange"])
                d["interval"] = Interval(d["interval"])
                d["gateway_name"] = "DB"
                d.pop("_id")

                bar = BarData(**d)
                bars.append(bar)

                bars = sorted(bars, key=lambda bar: bar.datetime)

            self.output(
                f"已从{self.history_db.name}库{self.bar_collection.name}集合加载{bars[0].datetime}至{bars[-1].datetime}K线数据{len(bars)}条"
            )

            return bars
Exemplo n.º 13
0
    def query_bar_from_rq(self, vt_symbol: str, interval: Interval,
                          start: datetime, end: datetime):
        """
        Query bar data from RQData.
        """
        symbol, exchange_str = vt_symbol.split(".")
        if symbol.upper() not in self.rq_symbols:
            return None

        df = self.rq_client.get_price(
            symbol.upper(),
            frequency=interval.value,
            fields=["open", "high", "low", "close", "volume"],
            start_date=start,
            end_date=end)

        data = []
        for ix, row in df.iterrows():
            bar = BarData(symbol=symbol,
                          exchange=Exchange(exchange_str),
                          interval=interval,
                          datetime=row.name.to_pydatetime(),
                          open_price=row["open"],
                          high_price=row["high"],
                          low_price=row["low"],
                          close_price=row["close"],
                          volume=row["volume"],
                          gateway_name="RQ")
            data.append(bar)

        return data
Exemplo n.º 14
0
    def run_backtesting_load_data_df(self):
        # Use the first [days] of history data for initializing strategy
        self.load_bar_end_timestamp = self.history_data_df['datetime'].min() + Day(self.days)
        load_bar_df = self.history_data_df[self.history_data_df['datetime'] <= self.load_bar_end_timestamp]
        for ix in range(len(load_bar_df)):
            x = load_bar_df.iloc[ix, :]
            bar = BarData(
                symbol=x.loc['symbol'],
                exchange=Exchange(x.loc['exchange']),
                datetime=self.datetime_set_timezone(x.loc['datetime'].to_pydatetime()),
                interval=Interval(x.loc['interval']),
                volume=x.loc['volume'],
                open_price=x.loc['open_price'],
                high_price=x.loc['high_price'],
                open_interest=x.loc['open_interest'],
                low_price=x.loc['low_price'],
                close_price=x.loc['close_price'],
                gateway_name="DB",
            )

            self.datetime = bar.datetime
            # fangyang self.callback 是 strategyTemplate里面的 on_bar
            # self.callback 是在下面的 load_bar(self)函数中赋值的,去策略模板中掉的load_bar/tick
            # 这里将数据推送进我们的策略
            try:
                self.callback(bar)
            except Exception:
                self.output("触发异常,回测终止")
                self.output(traceback.format_exc())
                return
Exemplo n.º 15
0
    def arrangePrice(bars:['BarData'],basePrice:float)->['BarData']:

        barList = []
        new_open_price = basePrice
        for bar in bars:
            open_price = bar.open_price
            close_price = bar.close_price
            high_price = bar.high_price
            low_price = bar.low_price
            close_price = close_price * new_open_price / open_price
            high_price = high_price * new_open_price / open_price
            low_price = low_price * new_open_price / open_price
            open_price = new_open_price

            barList.append( BarData(
                symbol=bar.symbol,
                exchange=Exchange.SSE,
                datetime=bar.datetime,
                interval=Interval.WEEKLY,
                volume=bar.volume,
                open_price=open_price,
                high_price=high_price,
                low_price=low_price,
                close_price=close_price,
                gateway_name='arrangePrice'
            ))
            new_open_price = close_price
        return barList
Exemplo n.º 16
0
    def new_bars(self, dt: datetime) -> None:
        """"""
        self.datetime = dt

        # self.bars.clear()
        for vt_symbol in self.vt_symbols:
            bar = self.history_data.get((dt, vt_symbol), None)

            # If bar data of vt_symbol at dt exists
            if bar:
                self.bars[vt_symbol] = bar
            # Otherwise, use previous data to backfill
            elif vt_symbol in self.bars:
                old_bar = self.bars[vt_symbol]

                bar = BarData(symbol=old_bar.symbol,
                              exchange=old_bar.exchange,
                              datetime=dt,
                              open_price=old_bar.close_price,
                              high_price=old_bar.close_price,
                              low_price=old_bar.close_price,
                              close_price=old_bar.close_price,
                              gateway_name=old_bar.gateway_name)
                self.bars[vt_symbol] = bar

        self.cross_limit_order()
        self.strategy.on_bars(self.bars)

        self.update_daily_close(self.bars, dt)
Exemplo n.º 17
0
 def to_bar_data(self, item,
                 symbol: str,
                 exchange: Exchange,
                 interval: Interval,
                 datetime_head: str,
                 open_head: str,
                 high_head: str,
                 low_head: str,
                 close_head: str,
                 volume_head: str,
                 open_interest_head: str
                 ):
     bar = BarData(
         symbol=symbol,
         exchange=exchange,
         datetime=item[datetime_head].to_pydatetime(),
         interval=interval,
         volume=item[volume_head],
         open_interest=item[open_interest_head],
         open_price=item[open_head],
         high_price=item[high_head],
         low_price=item[low_head],
         close_price=item[close_head],
         gateway_name="DB"
     )
     return bar
Exemplo n.º 18
0
    def get_oldest_bar_data(self, symbol: str, exchange: "Exchange",
                            interval: "Interval") -> Optional["BarData"]:
        query = ("select first(close_price), * from bar_data"
                 " where vt_symbol=$vt_symbol"
                 " and interval=$interval")

        bind_params = {
            "vt_symbol": generate_vt_symbol(symbol, exchange),
            "interval": interval.value
        }

        result = influx_client.query(query, bind_params=bind_params)
        points = result.get_points()

        bar = None
        for d in points:
            dt = datetime.strptime(d["time"], "%Y-%m-%dT%H:%M:%SZ")

            bar = BarData(symbol=symbol,
                          exchange=exchange,
                          interval=interval,
                          datetime=dt.replace(tzinfo=DB_TZ),
                          open_price=d["open_price"],
                          high_price=d["high_price"],
                          low_price=d["low_price"],
                          close_price=d["close_price"],
                          volume=d["volume"],
                          open_interest=d["open_interest"],
                          gateway_name="DB")

        return bar
Exemplo n.º 19
0
    def save_to_database(data: List[dict], vt_symbol: str, rq_interval: str):
        interval = INTERVAL_RQ2VT.get(rq_interval)
        if not rq_interval:
            return None

        symbol, exchange = extract_vt_symbol(vt_symbol)
        exchange = Exchange(exchange)
        dt_format = "%Y-%m-%d %H:%M:%S"

        res_list: List[BarData] = []
        if data is not None:
            for row in data:
                bar = BarData(symbol=symbol,
                              exchange=exchange,
                              interval=interval,
                              datetime=datetime.strptime(
                                  row['datetime'], dt_format),
                              open_price=row["open"],
                              high_price=row["high"],
                              low_price=row["low"],
                              close_price=row["close"],
                              volume=row["volume"],
                              gateway_name="RQ_WEB")
                res_list.append(bar)
        database_manager.save_bar_data(res_list)
Exemplo n.º 20
0
    def query_history(self, req: HistoryRequest):
        """"""
        buf = {}
        end_time = None

        for i in range(10):
            path = f"/api/spot/v3/instruments/{req.symbol}/candles"

            # Create query params
            params = {"granularity": INTERVAL_VT2OKEX[req.interval]}

            if end_time:
                end = datetime.strptime(end_time, "%Y-%m-%dT%H:%M:%S.%fZ")
                start = end - TIMEDELTA_MAP[req.interval] * 200

                params["start"] = start.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
                params["end"] = end.strftime("%Y-%m-%dT%H:%M:%S.%fZ")

            # Get response from server
            resp = self.request("GET", path, params=params)

            # Break if request failed with other status code
            if resp.status_code // 100 != 2:
                msg = f"获取历史数据失败,状态码:{resp.status_code},信息:{resp.text}"
                self.gateway.write_log(msg)
                break
            else:
                data = resp.json()
                if not data:
                    msg = f"获取历史数据为空"
                    break

                for l in data:
                    ts, o, h, l, c, v = l
                    dt = datetime.strptime(ts, "%Y-%m-%dT%H:%M:%S.%fZ")
                    bar = BarData(symbol=req.symbol,
                                  exchange=req.exchange,
                                  datetime=dt,
                                  interval=req.interval,
                                  volume=float(v),
                                  open_price=float(o),
                                  high_price=float(h),
                                  low_price=float(l),
                                  close_price=float(c),
                                  gateway_name=self.gateway_name)
                    buf[bar.datetime] = bar

                begin = data[-1][0]
                end = data[0][0]
                msg = f"获取历史数据成功,{req.symbol} - {req.interval.value},{begin} - {end}"
                self.gateway.write_log(msg)

                # Update start time
                end_time = begin

        index = list(buf.keys())
        index.sort()

        history = [buf[i] for i in index]
        return history
Exemplo n.º 21
0
def move_df_to_sql(data_df:pd.DataFrame):
    bars = []
    start = None
    count = 0

    for row in data_df.itertuples():

        bar = BarData(
            symbol=row.symbol.upper(),
            exchange=exchange_dict[row.exchange],
            datetime=row.datetime,
            interval=interval_dict[row.interval],
            volume=float(row.volume),
            open_price=float(row.open),
            high_price=float(row.high),
            low_price=float(row.low),
            close_price=float(row.close),
            open_interest=float(row.open_interest),
            gateway_name="DB",
        )


        bars.append(bar)

        # do some statistics
        count += 1
        if not start:
            start = bar.datetime
    end = bar.datetime

    # insert into database
    print(bars)
    sql_manager.save_bar_data(bars)
    print(f'插入{count} 根bar 从 {start} 到 {end}')
Exemplo n.º 22
0
    def load_bar_data(self, symbol: str, exchange: Exchange,
                      interval: Interval, start: datetime,
                      end: datetime) -> List[BarData]:
        """"""
        s: ModelSelect = (
            DbBarData.select().where((DbBarData.symbol == symbol)
                                     & (DbBarData.exchange == exchange.value)
                                     & (DbBarData.interval == interval.value)
                                     & (DbBarData.datetime >= start)
                                     & (DbBarData.datetime <= end)).order_by(
                                         DbBarData.datetime))

        bars: List[BarData] = []
        for db_bar in s:
            bar = BarData(symbol=db_bar.symbol,
                          exchange=Exchange(db_bar.exchange),
                          datetime=db_bar.datetime.astimezone(DB_TZ),
                          interval=Interval(db_bar.interval),
                          volume=db_bar.volume,
                          turnover=db_bar.turnover,
                          open_interest=db_bar.open_interest,
                          open_price=db_bar.open_price,
                          high_price=db_bar.high_price,
                          low_price=db_bar.low_price,
                          close_price=db_bar.close_price,
                          gateway_name="DB")
            bars.append(bar)

        return bars
Exemplo n.º 23
0
    def query_history(self, req: HistoryRequest):
        """"""
        # Convert symbol
        contract_type = symbol_type_map.get(req.symbol, "")
        buf = [i for i in req.symbol if not i.isdigit()]
        symbol = "".join(buf)

        ws_contract_type = CONTRACT_TYPE_MAP[contract_type]
        ws_symbol = f"{symbol}_{ws_contract_type}"

        # Create query params
        params = {
            "symbol": ws_symbol,
            "period": INTERVAL_VT2HBDM[req.interval],
            "size": 2000
        }

        # Get response from server
        resp = self.request(
            "GET",
            "/market/history/kline",
            params=params
        )

        # Break if request failed with other status code
        history = []

        if resp.status_code // 100 != 2:
            msg = f"获取历史数据失败,状态码:{resp.status_code},信息:{resp.text}"
            self.gateway.write_log(msg)
        else:
            data = resp.json()
            if not data:
                msg = f"获取历史数据为空"
                self.gateway.write_log(msg)
            else:
                for d in data["data"]:
                    dt = datetime.fromtimestamp(d["id"])
                    
                    bar = BarData(
                        symbol=req.symbol,
                        exchange=req.exchange,
                        datetime=dt,
                        interval=req.interval,
                        volume=d["vol"],
                        open_price=d["open"],
                        high_price=d["high"],
                        low_price=d["low"],
                        close_price=d["close"],
                        gateway_name=self.gateway_name
                    )
                    history.append(bar)

                begin = history[0].datetime
                end = history[-1].datetime
                msg = f"获取历史数据成功,{req.symbol} - {req.interval.value},{begin} - {end}"
                self.gateway.write_log(msg)

        return history
Exemplo n.º 24
0
    def import_data_from_csv(
        self,
        file_path: str,
        symbol: str,
        exchange: Exchange,
        interval: Interval,
        datetime_head: str,
        open_head: str,
        high_head: str,
        low_head: str,
        close_head: str,
        volume_head: str,
        open_interest_head: str,
        datetime_format: str
    ) -> Tuple:
        """"""
        with open(file_path, "rt") as f:
            buf = [line.replace("\0", "") for line in f]

        reader = csv.DictReader(buf, delimiter=",")

        bars = []
        start = None
        count = 0

        for item in reader:
            if datetime_format:
                dt = datetime.strptime(item[datetime_head], datetime_format)
            else:
                dt = datetime.fromisoformat(item[datetime_head])

            open_interest = item.get(open_interest_head, 0)

            bar = BarData(
                symbol=symbol,
                exchange=exchange,
                datetime=dt,
                interval=interval,
                volume=float(item[volume_head]),
                open_price=float(item[open_head]),
                high_price=float(item[high_head]),
                low_price=float(item[low_head]),
                close_price=float(item[close_head]),
                open_interest=float(open_interest),
                gateway_name="DB",
            )

            bars.append(bar)

            # do some statistics
            count += 1
            if not start:
                start = bar.datetime

        # insert into database
        database_manager.save_bar_data(bars)

        end = bar.datetime
        return start, end, count
Exemplo n.º 25
0
    def update_bar(self, bar: BarData):
        if not self.window_bar:
            # Generate timestamp for bar data
            if self.interval == Interval.MINUTE:
                dt = bar.datetime.replace(second=0, microsecond=0)
            else:
                dt = bar.datetime.replace(minute=0, second=0, microsecond=0)

            self.window_bar = BarData(symbol=bar.symbol,
                                      exchange=bar.exchange,
                                      datetime=dt,
                                      gateway_name=bar.gateway_name,
                                      open_price=bar.open_price,
                                      high_price=bar.high_price,
                                      low_price=bar.low_price)
        # Otherwise, update high/low price into window bar
        else:
            self.window_bar.high_price = max(self.window_bar.high_price,
                                             bar.high_price)
            self.window_bar.low_price = min(self.window_bar.low_price,
                                            bar.low_price)

        # Update close price/volume into window bar
        self.window_bar.close_price = bar.close_price
        self.window_bar.volume += int(bar.volume)
        self.window_bar.open_interest = bar.open_interest

        # Check if window bar completed
        finished = False

        if self.interval == Interval.MINUTE:
            # # x-minute bar
            # if not (bar.datetime.minute + 1) % self.window:
            #     finished = True
            if self.last_bar and bar.datetime.minute != self.last_bar.datetime.minute:
                self.interval_count += 1
                if not self.interval_count % self.window:
                    finished = True
                    self.interval_count = 0

        elif self.interval == Interval.HOUR:
            if self.last_bar and bar.datetime.hour != self.last_bar.datetime.hour:
                # 1-hour bar
                if self.window == 1:
                    finished = True
                # x-hour bar
                else:
                    self.interval_count += 1

                    if not self.interval_count % self.window:
                        finished = True
                        self.interval_count = 0

        if finished:
            self.on_window_bar(self.window_bar)
            self.window_bar = None

        # Cache last bar object
        self.last_bar = bar
Exemplo n.º 26
0
    def on_bar(self, bar: BarData):
        """收到Bar推送(必须由用户继承实现)"""
        # 如果当前是一个5分钟走完
        # ZL: 通过改变 +1 可以实现非标时间bar
        if (bar.datetime.minute + 1) % 5 == 0:
            # 如果已经有聚合5分钟K线
            if self.fiveBar:
                # 将最新分钟的数据更新到目前5分钟线中
                fiveBar = self.fiveBar
                fiveBar.high_price = max(fiveBar.high_price, bar.high_price)
                fiveBar.low_price = min(fiveBar.low_price, bar.low_price)
                fiveBar.close_price = bar.close_price

                # 推送5分钟线数据
                self.onFiveBar(fiveBar)

                # 清空5分钟线数据缓存
                self.fiveBar = None
        else:
            # 如果没有缓存则新建
            if not self.fiveBar:
                # fiveBar = BarData()
                fiveBar = BarData(datetime=bar.datetime,
                                  exchange=bar.exchange,
                                  gateway_name=bar.gateway_name,
                                  symbol=bar.symbol)

                # fiveBar.vtSymbol = bar.vtSymbol
                # fiveBar.symbol = bar.symbol
                # fiveBar.exchange = bar.exchange

                fiveBar.open_price = bar.open_price
                fiveBar.high_price = bar.high_price
                fiveBar.low_price = bar.low_price
                fiveBar.close_price = bar.close_price

                # fiveBar.date = bar.datetime
                # fiveBar.time = bar.time
                fiveBar.datetime = bar.datetime

                self.fiveBar = fiveBar
            else:
                fiveBar = self.fiveBar
                fiveBar.high_price = max(fiveBar.high_price, bar.high_price)
                fiveBar.low_price = min(fiveBar.low_price, bar.low_price)
                fiveBar.close_price = bar.close_price
Exemplo n.º 27
0
    def query_data(self):
        # self.clearData()
        self.chart.clear_all()
        start = self.datetime_from.dateTime().toPyDateTime()
        end = self.datetime_to.dateTime().toPyDateTime()
        symbol = self.symbol_line.text()

        if self.data_source == 'HK':
            query_set1 = self._querier[120:start:symbol]
            query_set2 = self._querier[start:end:symbol]
            query_set3 = self._querier[end:120:symbol]
            data1 = self._querier.to_df(query_set1)
            data2 = self._querier.to_df(query_set2)
            data3 = self._querier.to_df(query_set3)
            datas = pd.concat([data1, data2, data3])

        elif self.data_source == 'IB':
            contract = self._querier.verifyContract(symbol)
            barType = {'1min': '1 min', '5min': '5 mins', '15min': '15 mins', '30min': '30 mins', '60min': '60 mins', '1day': '1 day'}.get(self.period,'1 min')
            datas = self._querier.get_bars_from_ib(contract, barType=barType, start=start, end=end)


        if self.review_mode == 'backtest':
            executions = self.executions
        elif self.review_mode == 'live':
            acc_id = self.account_line.text()
            if acc_id:
                fills = IBTrade(acc_id)[start:end:symbol]
                fills = fills.order_by('execution.time')

                executions = [{'datetime': f.execution.time + dt.timedelta(hours=8), 'price': f.execution.price,
                      'size': f.execution.shares, 'direction': 'long' if f.execution.side == 'BOT' else 'short'} for f in
                     fills]
            else:
                executions = []

        if executions:
            datas = _concat_executions(datas, executions)

        self.datas = datas
        barList = []
        tradeList = []
        for _, d in datas.iterrows():
            b = BarData('KRData', symbol, Exchange.HKFE, d.datetime, None,
                        d.volume, 0, d.open, d.high, d.low, d.close)
            barList.append(b)

        for e in executions:
            t = TradeData('KRData', symbol, Exchange.HKFE, '', '',
                          Direction.LONG if e['direction'] == 'long' else Direction.SHORT,
                          Offset.NONE,
                          e['price'],
                          e['size'],
                          e['datetime'] if isinstance(e['datetime'], dt.datetime) else parser.parse(e['datetime'])
                          )
            tradeList.append(t)

        self.chart.update_all(barList, tradeList, [])
Exemplo n.º 28
0
    def __fill_bardatas(self, symbol, exchange, interval, bars):
        """
        填充 BarData 结构体
        :param bars: 
        :return: BarData 列表
        """
        if not bars:
            return None
        tu = TimeUtils()
        bardatas = []
        for bar in bars:
            dt = tu.convert_datetime(bar[0] // 1000)
            _bar = BarData(symbol=symbol,
                           exchange=exchange,
                           datetime=dt,
                           interval=interval,
                           gateway_name="OKEX")
            _bar.open_price = bar[1]
            _bar.high_price = bar[2]
            _bar.low_price = bar[3]
            _bar.close_price = bar[4]
            _bar.volume = bar[5]
            bardatas.append(_bar)

        return bardatas
Exemplo n.º 29
0
    def update_tick(self, tick: TickData):
        """
        Update new tick data into generator.
        把新的tick数据更新到生成器
        """
        # flag 是否是新的一分钟
        new_minute = False

        # Filter tick data with 0 last price
        # 过滤掉 最新价格为0的数据
        if not tick.last_price:
            return

        if not self.bar:
            # bar里为空,那么是新的min
            new_minute = True
        # elif self.bar.datetime.minute != tick.datetime.minute:
        # 调整 时间窗口,避开高峰时间 蒋越希  修改 2019年9月11日11:03:31
        elif (tick.datetime.second >= 50) and (self.last_tick.datetime.second <
                                               50):
            # 判断是否走完当前分钟
            self.bar.datetime = self.bar.datetime.replace(second=0,
                                                          microsecond=0)
            # 把老的bar更新一下,开启新的一分钟
            self.on_bar(self.bar)

            new_minute = True

        if new_minute:
            # 如果是新的分钟,则生成新的bar
            self.bar = BarData(symbol=tick.symbol,
                               exchange=tick.exchange,
                               interval=Interval.MINUTE,
                               datetime=tick.datetime,
                               gateway_name=tick.gateway_name,
                               open_price=tick.last_price,
                               high_price=tick.last_price,
                               low_price=tick.last_price,
                               close_price=tick.last_price,
                               open_interest=tick.open_interest)
        else:
            # 高 price
            self.bar.high_price = max(self.bar.high_price, tick.last_price)
            # 低 price
            self.bar.low_price = min(self.bar.low_price, tick.last_price)
            # 收 price
            self.bar.close_price = tick.last_price
            # 当前持仓量
            self.bar.open_interest = tick.open_interest
            self.bar.datetime = tick.datetime

        if self.last_tick:
            # 统计出bar里的成交量
            volume_change = tick.volume - self.last_tick.volume
            self.bar.volume += max(volume_change, 0)

        self.last_tick = tick
Exemplo n.º 30
0
    def query_history(self, req: HistoryRequest):
        """
        Query history bar data from JQData.
        """
        symbol = req.symbol
        exchange = req.exchange
        interval = req.interval
        start = req.start
        end = req.end

        jq_symbol = self.to_jq_symbol(symbol, exchange)
        # if jq_symbol not in self.symbols:
        #     return None

        jq_interval = INTERVAL_VT2JQ.get(interval)
        if not jq_interval:
            return None

        # For adjust timestamp from bar close point (RQData) to open point (VN Trader)
        adjustment = INTERVAL_ADJUSTMENT_MAP_JQ.get(interval)

        # For querying night trading period data
        # end += timedelta(1)
        now = datetime.now()
        if end >= now:
            end = now
        elif end.year == now.year and end.month == now.month and end.day == now.day:
            end = now

        df = jq.get_price(
            jq_symbol,
            frequency=jq_interval,
            fields=["open", "high", "low", "close", "volume"],
            start_date=start,
            end_date=end,
            skip_paused=True
        )

        data: List[BarData] = []

        if df is not None:
            for ix, row in df.iterrows():
                bar = BarData(
                    symbol=symbol,
                    exchange=exchange,
                    interval=interval,
                    datetime=row.name.to_pydatetime() - adjustment,
                    open_price=row["open"],
                    high_price=row["high"],
                    low_price=row["low"],
                    close_price=row["close"],
                    volume=row["volume"],
                    gateway_name="JQ"
                )
                data.append(bar)

        return data