Beispiel #1
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
Beispiel #2
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 = generate_datetime(ts)
                    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
Beispiel #3
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)
Beispiel #4
0
    def subscribe(self, req: SubscribeRequest) -> None:
        """"""
        if req.symbol not in symbol_name_map:
            self.gateway.write_log(f"找不到该合约代码{req.symbol}")
            return

        # Create tick buf data
        tick = TickData(
            symbol=req.symbol,
            name=symbol_name_map.get(req.symbol, ""),
            exchange=Exchange.BINANCE,
            datetime=datetime.now(CHINA_TZ),
            gateway_name=self.gateway_name,
        )
        self.ticks[req.symbol.lower()] = tick

        # Create bar buf data
        bar = BarData(
            symbol=req.symbol,
            exchange=Exchange.BINANCE,
            datetime=datetime.now(CHINA_TZ),
            gateway_name=self.gateway_name,
            interval=Interval.MINUTE
        )

        self.bars[req.symbol.lower()] = bar

        self.last[req.symbol.lower()] = {}
        self.trades[req.symbol.lower()] = []
        # Close previous connection
        if self._active:
            self.stop()
            self.join()

        # Create new connection
        channels = []
        for ws_symbol in self.ticks.keys():
            # channels.append(ws_symbol + "@ticker")
            channels.append(ws_symbol + "@depth5@100ms")
            channels.append(ws_symbol + "@kline_1m")
            channels.append(ws_symbol + "@aggTrade")
        if self.server == "REAL":
            url = F_WEBSOCKET_DATA_HOST + "/".join(channels)
            if not self.usdt_base:
                url = D_WEBSOCKET_DATA_HOST + "/".join(channels)
        else:
            url = F_TESTNET_WEBSOCKET_DATA_HOST + "/".join(channels)
            if not self.usdt_base:
                url = D_TESTNET_WEBSOCKET_DATA_HOST + "/".join(channels)

        self.init(url, self.proxy_host, self.proxy_port)
        self.start()
Beispiel #5
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
Beispiel #6
0
    def query_history(self, req: HistoryRequest):
        """"""
        history = []
        interval = INTERVAL_VT2GATEIO[req.interval]

        params = {
            "contract": req.symbol,
            "limit": 2000,
            "interval": interval,
        }

        resp = self.request(
            method="GET",
            path="/api/v4/futures/usdt/candlesticks",
            params=params
        )

        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"获取历史数据为空"

            for d in data:
                bar = BarData(
                    symbol=req.symbol,
                    exchange=req.exchange,
                    datetime=generate_datetime(d["t"]),
                    interval=req.interval,
                    volume=d["v"],
                    open_price=float(d["o"]),
                    high_price=float(d["h"]),
                    low_price=float(d["l"]),
                    close_price=float(d["c"]),
                    gateway_name=self.gateway_name
                )
                history.append(bar)

            begin = generate_datetime(data[0]["t"])
            end = generate_datetime(data[-1]["t"])

            msg = f"获取历史数据成功,{req.symbol} - {req.interval.value},{begin} - {end}"

            self.gateway.write_log(msg)

        return history
Beispiel #7
0
    def query_history(self, req: HistoryRequest) -> List[BarData]:
        """"""
        # Create query params
        params = {
            "symbol": req.symbol,
            "period": INTERVAL_VT2HUOBI[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 = generate_datetime(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
Beispiel #8
0
 def to_bar(self):
     """
     Generate BarData object from DbBarData.
     """
     bar = BarData(
         symbol=self.symbol,
         exchange=Exchange(self.exchange),
         datetime=self.datetime.replace(tzinfo=DB_TZ),
         interval=Interval(self.interval),
         volume=self.volume,
         open_price=self.open_price,
         high_price=self.high_price,
         open_interest=self.open_interest,
         low_price=self.low_price,
         close_price=self.close_price,
         gateway_name="DB",
     )
     return bar
Beispiel #9
0
    def load_bars(self, strategy: StrategyTemplate, days: int,
                  interval: Interval):
        """"""
        vt_symbols = strategy.vt_symbols
        dts: Set[datetime] = set()
        history_data: Dict[Tuple, BarData] = {}

        # Load data from rqdata/gateway/database
        for vt_symbol in vt_symbols:
            data = self.load_bar(vt_symbol, days, interval)

            for bar in data:
                dts.add(bar.datetime)
                history_data[(bar.datetime, vt_symbol)] = bar

        # Convert data structure and push to strategy
        dts = list(dts)
        dts.sort()

        bars = {}

        for dt in dts:
            for vt_symbol in vt_symbols:
                bar = history_data.get((dt, vt_symbol), None)

                # If bar data of vt_symbol at dt exists
                if bar:
                    bars[vt_symbol] = bar
                # Otherwise, use previous data to backfill
                elif vt_symbol in bars:
                    old_bar = 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)
                    bars[vt_symbol] = bar

            self.call_strategy_func(strategy, strategy.on_bars, bars)
Beispiel #10
0
    def subscribe(self, req: SubscribeRequest):
        """"""
        if req.symbol not in symbol_name_map:
            self.gateway.write_log(f"找不到该合约代码{req.symbol}")
            return

        # Create tick buf data
        tick = TickData(
            symbol=req.symbol,
            name=symbol_name_map.get(req.symbol, ""),
            exchange=Exchange.BINANCE,
            datetime=datetime.now(CHINA_TZ),
            gateway_name=self.gateway_name,
        )
        self.ticks[req.symbol] = tick

        # Create bar buf data
        bar = BarData(
            symbol=req.symbol,
            exchange=Exchange.BINANCE,
            datetime=datetime.now(CHINA_TZ),
            gateway_name=self.gateway_name,
            interval=Interval.MINUTE
        )

        self.bars[req.symbol] = bar

        # Close previous connection
        if self._active:
            self.stop()
            self.join()

        # Create new connection
        channels = []
        for ws_symbol in self.ticks.keys():
            channels.append(ws_symbol + "@ticker")
            channels.append(ws_symbol + "@depth5")
            channels.append(ws_symbol + "@kline_1m")

        url = WEBSOCKET_DATA_HOST + "/".join(channels)
        self.init(url, self.proxy_host, self.proxy_port)
        self.start()
def get_binance_data(symbol: str, exchanges: str, start_time: str,
                     end_time: str):
    """
    爬取币安交易所的数据
    :param symbol: BTCUSDT.
    :param exchanges: 现货、USDT合约, 或者币币合约.
    :param start_time: 格式如下:2020-1-1 或者2020-01-01
    :param end_time: 格式如下:2020-1-1 或者2020-01-01
    :return:
    """

    api_url = ''
    save_symbol = symbol
    gate_way = 'BINANCES'

    if exchanges == 'spot':
        print("spot")
        limit = BINANCE_SPOT_LIMIT
        save_symbol = symbol.lower()
        gate_way = 'BINANCE'
        api_url = f'https://api.binance.com/api/v3/klines?symbol={symbol}&interval=1m&limit={limit}'

    elif exchanges == 'future':
        print('future')
        limit = BINANCE_FUTURE_LIMIT
        api_url = f'https://fapi.binance.com/fapi/v1/klines?symbol={symbol}&interval=1m&limit={limit}'

    elif exchanges == 'coin_future':
        print("coin_future")
        limit = BINANCE_FUTURE_LIMIT
        f'https://dapi.binance.com/dapi/v1/klines?symbol={symbol}&interval=1m&limit={limit}'

    else:
        raise Exception('交易所名称请输入以下其中一个:spot, future, coin_future')

    start_time = int(
        datetime.strptime(start_time, '%Y-%m-%d').timestamp() * 1000)
    end_time = int(datetime.strptime(end_time, '%Y-%m-%d').timestamp() * 1000)

    while True:
        try:
            print(start_time)
            url = f'{api_url}&startTime={start_time}'
            print(url)
            data = requests.get(url=url, timeout=10, proxies=proxies).json()
            """
            [
                [
                    1591258320000,      // 开盘时间
                    "9640.7",           // 开盘价
                    "9642.4",           // 最高价
                    "9640.6",           // 最低价
                    "9642.0",           // 收盘价(当前K线未结束的即为最新价)
                    "206",              // 成交量
                    1591258379999,      // 收盘时间
                    "2.13660389",       // 成交额(标的数量)
                    48,                 // 成交笔数
                    "119",              // 主动买入成交量
                    "1.23424865",      // 主动买入成交额(标的数量)
                    "0"                 // 请忽略该参数
                ]

            """

            buf = []

            for l in data:
                bar = BarData(symbol=save_symbol,
                              exchange=Exchange.BINANCE,
                              datetime=generate_datetime(l[0]),
                              interval=Interval.MINUTE,
                              volume=float(l[5]),
                              open_price=float(l[1]),
                              high_price=float(l[2]),
                              low_price=float(l[3]),
                              close_price=float(l[4]),
                              gateway_name=gate_way)
                buf.append(bar)

            database_manager.save_bar_data(buf)

            # 到结束时间就退出, 后者收盘价大于当前的时间.
            if (data[-1][0] > end_time
                ) or data[-1][6] >= (int(time.time() * 1000) - 60 * 1000):
                break

            start_time = data[-1][0]

        except Exception as error:
            print(error)
            time.sleep(10)
Beispiel #12
0
    def query_history(self, req: HistoryRequest) -> List[BarData]:
        """"""
        history = []
        limit = 1500
        start_time = int(datetime.timestamp(req.start))

        while True:
            # Create query params
            params = {
                "symbol": req.symbol,
                "interval": INTERVAL_VT2BINANCES[req.interval],
                "limit": limit,
                "startTime": start_time * 1000,         # convert to millisecond
            }

            # Add end time if specified
            if req.end:
                end_time = int(datetime.timestamp(req.end))
                params["endTime"] = end_time * 1000     # convert to millisecond

            # Get response from server
            if self.usdt_base:
                path = "/fapi/v1/klines"
            else:
                path = "/dapi/v1/klines"

            resp = self.request(
                "GET",
                path=path,
                data={"security": Security.NONE},
                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"获取历史数据为空,开始时间:{start_time}"
                    self.gateway.write_log(msg)
                    break

                buf = []

                for l in data:
                    bar = BarData(
                        symbol=req.symbol,
                        exchange=req.exchange,
                        datetime=generate_datetime(l[0]),
                        interval=req.interval,
                        volume=float(l[5]),
                        open_price=float(l[1]),
                        high_price=float(l[2]),
                        low_price=float(l[3]),
                        close_price=float(l[4]),
                        gateway_name=self.gateway_name
                    )
                    buf.append(bar)

                history.extend(buf)

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

                # Break if total data count less than limit (latest date collected)
                if len(data) < limit:
                    break

                # Update start time
                start_dt = bar.datetime + TIMEDELTA_MAP[req.interval]
                start_time = int(datetime.timestamp(start_dt))

        return history
Beispiel #13
0
    def query_history(self, req: HistoryRequest) -> List[BarData]:
        """"""
        history = []
        count = 2000
        start = req.start
        time_delta = TIMEDELTA_MAP[req.interval]

        # Convert symbol
        buf = [i for i in req.symbol if not i.isdigit()]
        symbol = "".join(buf)

        ws_symbol = f"{symbol}"

        while True:
            # Calculate end time
            end = start + time_delta * count

            # Create query params
            params = {
                "symbol": ws_symbol,
                "period": INTERVAL_VT2HUOBIS[req.interval],
                "from": int(start.timestamp()),
                "to": int(end.timestamp())
            }

            # Get response from server
            resp = self.request("GET",
                                "/swap-ex/market/history/kline",
                                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"获取历史数据为空"
                    self.gateway.write_log(msg)
                    break

                if not data["data"]:
                    msg = f"获取历史数据为空"
                    self.gateway.write_log(msg)
                    break

                buf = []
                print("download data:", data)
                for d in data["data"]:
                    dt = generate_datetime(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)
                    buf.append(bar)

                history.extend(buf)

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

                # Update start time
                start = bar.datetime

                # Break if data end reached
                if len(buf) < count:
                    break

        return history