当我尝试使用“GET”方法从 Binance 获取历史蜡烛时,使用 Binance 的加密交易机器人,回调 > 绑定方法出错

Posted

技术标签:

【中文标题】当我尝试使用“GET”方法从 Binance 获取历史蜡烛时,使用 Binance 的加密交易机器人,回调 > 绑定方法出错【英文标题】:Crypto trading bot with Binance, Error from callback > bound method, when I am trying to get historical candles from Binance using the "GET" method 【发布时间】:2021-07-27 01:38:24 【问题描述】:

机器人从 www.testnet.binancefuture.com 获取某些数据> 我得到的信息是买卖、历史蜡烛、合同、余额、下单、取消和订单状态。回调方法为 on_open、on_error、on_close 和 on_message + Channel 订阅。这是代码和错误

BinanceFuturesClient 类:

def __init__(self, public_key, secret_key, testnet):
    if testnet:
        self.base_url = "https://testnet.binancefuture.com"
        self.wss_url = "wss://stream.binancefuture.com/ws"
    else:
        self.base_url = "https://fapi.binance.com"
        self.wss_url = "wss://fstream.binance.com/ws"

    self.public_key = public_key
    self.secret_key = secret_key

    self.headers = 'X-MBX-APIKEY': self.public_key

    self.prices = dict()

    self.id = 1
    self.ws = None

    t = threading.Thread(target=self.start_ws)
    t.start()

    logger.info("Binance Futures Client successfully initialized")

def generate_signature(self, data):
    return hmac.new(self.secret_key.encode(), urlencode(data).encode(), hashlib.sha256).hexdigest()

def make_request(self, method, endpoint, data):
    if method == "GET":
        response = requests.get(self.base_url + endpoint, params=data, headers=self.headers)
    elif method == 'POST':
        response = requests.post(self.base_url + endpoint, params=data, headers=self.headers)
    elif method == 'DELETE':
        response = requests.delete(self.base_url + endpoint, params=data, headers=self.headers)
    else:
        raise ValueError()

    if response.status_code == 200:
        return response.json()
    else:
        logger.error('Error while making %s request to %s: %s(error code %s)',
                     method, endpoint, response.json(), response.status_code)
        return None

def get_contracts(self):
    exchange_info = self.make_request("GET", "/fapi/v1/exchangeInfo", None)

    contracts = dict()

    if exchange_info is not None:
        for contract_data in exchange_info['symbols']:
            contracts[contract_data['pair']] = contract_data

    return contracts

def get_historical_candles(self, symbol, interval):
    data = dict()
    data['symbol'] = symbol
    data['interval'] = interval
    data['limit'] = 1000

    raw_candles = self.make_request("GET", "/fapi/v1/klines", data)

    candles = []

    if raw_candles is not None:
        for c in raw_candles:
            candles.append([c[0], float(c[1]), float(c[2]), float(c[3]), float(c[4]), float(c[5])])

    return candles

def get_bid_ask(self, symbol):
    data = dict()
    data['symbol'] = symbol
    ob_data = self.make_request("GET", "/fapi/v1/ticker/bookTicker", data)

    if ob_data is not None:
        if symbol not in self.prices:
            self.prices[symbol] = 'bid': float(ob_data['bidPrice']), 'ask': float(ob_data['askPrice'])
        else:
            self.prices[symbol]['bid'] = float(ob_data['bidPrice'])
            self.prices[symbol]['ask'] = float(ob_data['askPrice'])

        return self.prices[symbol]

def get_balances(self):
    data = dict()
    data['timestamp'] = int(time.time() * 1000)
    data['signature'] = self.generate_signature(data)

    balances = dict()

    account_data = self.make_request("GET", "/fapi/v1/account", data)

    if account_data is not None:
        for a in account_data['assets']:
            balances[a['asset']] = a

    return balances

def place_order(self, symbol, side, quantity, order_type, price=None, tif=None):
    data = dict()
    data['symbol'] = symbol
    data['side'] = side
    data['quantity'] = quantity
    data['type'] = order_type

    if price is not None:
        data['price'] = price

    if tif is not None:
        data['timeInForce'] = tif

    data['timestamp'] = int(time.time() * 1000)
    data['signature'] = self.generate_signature(data)

    order_status = self.make_request("POST", "/fapi/v1/order", data)

    return order_status

def cancel_order(self, symbol, order_id):
    data = dict()
    data['symbol'] = symbol
    data['orderId'] = order_id

    data['timestamp'] = int(time.time() * 1000)
    data['signature'] = self.generate_signature(data)

    order_status = self.make_request("DELETE", "/fapi/v1/order", data)

    return order_status

def get_order_status(self, symbol, order_id):
    data = dict()
    data['timestamp'] = int(time.time() * 1000)
    data['symbol'] = symbol
    data['orderId'] = order_id
    data['signature'] = self.generate_signature(data)

    order_status = self.make_request("GET", "/fapi/v1/order", data)

    return order_status

def start_ws(self):
    ws = websocket.WebSocketApp(self.wss_url, on_open=self.on_open, on_close=self.on_close,
                                on_error=self.on_error, on_message=self.on_message)

    ws.run_forever()

def on_close(self, ws):
    logger.warning("Binance websocket connection closed")

def on_error(self, ws, msg):
    logger.error("Binance connection error: %s", msg)

def on_open(self, ws):
    logger.info("Binance connection opened")

    self.subscribe_channel("BTCUSDT")

def on_message(self, ws, msg):
    print(msg)

def subscribe_channel(self, symbol):
    data = dict()
    data['method'] = "SUBSCRIBE"
    data['params'] = []
    data['params'].append(symbol.lower() + "@bookTicker")
    data['id'] = self.id

    print(data, type(data))
    print(json.dumps(data), type(json.dumps(data)))

    self.ws.send(json.dumps(data))

    self.id += 1

数据后的错误:

2021-05-04 16:51:55,683 INFO :: Binance Futures 客户端成功初始化 'method': 'SUBSCRIBE', 'params': ['btcusdt@bookTicker'], 'id': 1 "method": "SUBSCRIBE", "params": ["btcusdt@bookTicker"], "id": 1 2021-05-04 16:51:56,833 INFO :: Binance 连接打开 2021-05-04 16:51:56,834 错误 :: 来自回调的错误 > 的绑定方法 BinanceFuturesClient.on_open>>:“NoneType”对象没有属性“发送”

【问题讨论】:

【参考方案1】:

如下修改你的代码;

def start_ws(self):
self.ws = websocket.WebSocketApp(self.wss_url, on_open=self.on_open, on_close=self.on_close,
                            on_error=self.on_error, on_message=self.on_message)

self.ws.run_forever()

【讨论】:

以上是关于当我尝试使用“GET”方法从 Binance 获取历史蜡烛时,使用 Binance 的加密交易机器人,回调 > 绑定方法出错的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Binance API,通过股票代码简单 GET 价格

使用 Python(最好是请求)从 Binance API 获取烛台/Kline 数据以获取 JSON 数据

邮递员 GET 请求 Binance API

如何使用 Dart 签署 Binance HTTP 请求

我正在尝试从 post 方法获取令牌,但我得到 json 响应 "Get/Method?Not Allowed" 我为此使用 POST 方法

在 Python 中为 Binance API 输入参数