class BinanceInterface(ExchangeInterface): def __init__(self, settings, logger, on_tick_callback=None): super().__init__(settings, logger, on_tick_callback) self.symbol = settings.SYMBOL self.client = RequestClient(api_key=settings.API_KEY, secret_key=settings.API_SECRET) self.ws = SubscriptionClient(api_key=settings.API_KEY, secret_key=settings.API_SECRET) self.orders = {} self.positions = {} self.candles: List[Candlestick] = [] self.last = 0 self.open = False self.listen_key = "" self.init() def init(self): self.logger.info("loading market data. this may take a moment") self.initOrders() self.initPositions() self.logger.info("got all data. subscribing to live updates.") self.listen_key = self.client.start_user_data_stream() self.ws.subscribe_user_data_event(self.listen_key, self.callback, self.error) subbarsIntervall = CandlestickInterval.MIN1 if self.settings.MINUTES_PER_BAR <= 60 else CandlestickInterval.HOUR1 self.ws.subscribe_candlestick_event(self.symbol, subbarsIntervall, self.callback, self.error) self.open = True self.lastUserDataKeep = time.time() self.logger.info("ready to go") def callback(self, data_type: 'SubscribeMessageType', event: 'any'): gotTick = False # refresh userdata every 15 min if self.lastUserDataKeep < time.time() - 15 * 60: self.lastUserDataKeep = time.time() self.client.keep_user_data_stream() # TODO: implement! (update bars, orders and account) if data_type == SubscribeMessageType.RESPONSE: pass # what to do herE? elif data_type == SubscribeMessageType.PAYLOAD: if event.eventType == "kline": # {'eventType': 'kline', 'eventTime': 1587064627164, 'symbol': 'BTCUSDT', # 'data': <binance_f.model.candlestickevent.Candlestick object at 0x0000016B89856760>} if event.symbol == self.symbol: candle: Candlestick = event.data if len(self.candles) > 0: if candle.startTime <= self.candles[ 0].startTime and candle.startTime > self.candles[ -1].startTime: # somewhere inbetween to replace for idx in range(0, len(self.candles)): if candle.startTime == self.candles[ idx].startTime: self.candles[idx] = candle break elif candle.startTime > self.candles[0].startTime: self.candles.insert(0, candle) gotTick = True else: self.candles.append(candle) gotTick = True elif (event.eventType == "ACCOUNT_UPDATE"): # {'eventType': 'ACCOUNT_UPDATE', 'eventTime': 1587063874367, 'transactionTime': 1587063874365, # 'balances': [<binance_f.model.accountupdate.Balance object at 0x000001FAF470E100>,...], # 'positions': [<binance_f.model.accountupdate.Position object at 0x000001FAF470E1C0>...]} usdBalance = 0 for b in event.balances: bal: Balance = b if bal.asset == "USDT": usdBalance = bal.walletBalance for p in event.positions: pos: Position = p if pos.symbol not in self.positions.keys(): self.positions[pos.symbol] = AccountPosition( pos.symbol, avgEntryPrice=float(pos.entryPrice), quantity=float(pos.amount), walletBalance=usdBalance if "USDT" in pos.symbol else 0) else: accountPos = self.positions[pos.symbol] accountPos.quantity = float(pos.amount) accountPos.avgEntryPrice = float(pos.entryPrice) if "USDT" in pos.symbol: accountPos.walletBalance = usdBalance elif (event.eventType == "ORDER_TRADE_UPDATE"): # {'eventType': 'ORDER_TRADE_UPDATE', 'eventTime': 1587063513592, 'transactionTime': 1587063513589, # 'symbol': 'BTCUSDT', 'clientOrderId': 'web_ybDNrTjCi765K3AvOMRK', 'side': 'BUY', 'type': 'LIMIT', # 'timeInForce': 'GTC', 'origQty': 0.01, 'price': 6901.0, 'avgPrice': 0.0, 'stopPrice': 0.0, # 'executionType': 'NEW', 'orderStatus': 'NEW', 'orderId': 2705199704, 'lastFilledQty': 0.0, # 'cumulativeFilledQty': 0.0, 'lastFilledPrice': 0.0, 'commissionAsset': None, 'commissionAmount': None, # 'orderTradeTime': 1587063513589, 'tradeID': 0, 'bidsNotional': 138.81, 'asksNotional': 0.0, # 'isMarkerSide': False, 'isReduceOnly': False, 'workingType': 'CONTRACT_PRICE'} sideMulti = 1 if event.side == 'BUY' else -1 order: Order = Order(orderId=event.clientOrderId, stop=event.stopPrice, limit=event.price, amount=event.origQty * sideMulti) order.exchange_id = event.orderId #FIXME: how do i know stop triggered on binance? #order.stop_triggered = order.executed_amount = event.cumulativeFilledQty * sideMulti order.executed_price = event.avgPrice order.tstamp = event.transactionTime order.execution_tstamp = event.orderTradeTime prev: Order = self.orders[ order. exchange_id] if order.exchange_id in self.orders.keys( ) else None if prev is not None: if prev.tstamp > order.tstamp or abs( prev.executed_amount) > abs(order.executed_amount): # already got newer information, probably the info of the stop order getting # triggered, when i already got the info about execution self.logger.info("ignoring delayed update for %s " % (prev.id)) if order.stop_price is None: order.stop_price = prev.stop_price if order.limit_price is None: order.limit_price = prev.limit_price prev = order if not prev.active and prev.execution_tstamp == 0: prev.execution_tstamp = datetime.utcnow().timestamp() self.orders[order.exchange_id] = prev self.logger.info("received order update: %s" % (str(order))) else: self.logger.warn("Unknown Data in websocket callback") if gotTick and self.on_tick_callback is not None: self.on_tick_callback() # got something new def error(self, e: 'BinanceApiException'): self.exit() self.logger.error(e.error_code + e.error_message) def initOrders(self): apiOrders = self.client.get_open_orders() for o in apiOrders: order = self.convertOrder(o) if order.active: self.orders[order.exchange_id] = order def convertOrder(self, apiOrder: binance_f.model.Order) -> Order: direction = 1 if apiOrder.side == OrderSide.BUY else -1 order = Order(orderId=apiOrder.clientOrderId, amount=apiOrder.origQty * direction, limit=apiOrder.price, stop=apiOrder.stopPrice) order.executed_amount = apiOrder.executedQty * direction order.executed_price = apiOrder.avgPrice order.active = apiOrder.status in ["NEW", "PARTIALLY_FILLED"] order.exchange_id = apiOrder.orderId return order def initPositions(self): balance = self.client.get_balance() usdBalance = 0 for bal in balance: if bal.asset == "USDT": usdBalance = bal.balance api_positions = self.client.get_position() self.positions[self.symbol] = AccountPosition(self.symbol, 0, 0, 0) if api_positions is not None: for pos in api_positions: self.positions[pos.symbol] = AccountPosition( pos.symbol, avgEntryPrice=pos.entryPrice, quantity=pos.positionAmt, walletBalance=usdBalance if "USDT" in pos.symbol else 0) self.logger.info("starting with %.2f in wallet and pos %.2f @ %.2f" % (self.positions[self.symbol].walletBalance, self.positions[self.symbol].quantity, self.positions[self.symbol].avgEntryPrice)) def exit(self): self.ws.unsubscribe_all() self.open = False def internal_cancel_order(self, order: Order): if order.exchange_id in self.orders.keys(): self.orders[order.exchange_id].active = False self.client.cancel_order(symbol=self.symbol, origClientOrderId=order.id) def internal_send_order(self, order: Order): order_type = OrderType.MARKET if order.limit_price is not None: if order.stop_price is not None: order_type = OrderType.STOP else: order_type = OrderType.LIMIT else: order_type = OrderType.STOP_MARKET resultOrder: binance_f.model.Order = self.client.post_order( symbol=self.symbol, side=OrderSide.BUY if order.amount > 0 else OrderSide.SELL, ordertype=order_type, timeInForce=TimeInForce.GTC, quantity=abs(order.amount), price=order.limit_price, stopPrice=order.stop_price, newClientOrderId=order.id) order.exchange_id = resultOrder.orderId def internal_update_order(self, order: Order): self.cancel_order(order) # stupid binance can't update orders self.send_order(order) def get_orders(self) -> List[Order]: return list(self.orders.values()) def get_bars(self, timeframe_minutes, start_offset_minutes) -> List[Bar]: tf = CandlestickInterval.MIN1 if timeframe_minutes <= 60 else CandlestickInterval.HOUR1 bars = self.client.get_candlestick_data(symbol=self.symbol, interval=tf, limit=1000) return self._aggregate_bars(reversed(bars), timeframe_minutes, start_offset_minutes) def recent_bars(self, timeframe_minutes, start_offset_minutes) -> List[Bar]: return self._aggregate_bars(self.bars, timeframe_minutes, start_offset_minutes) def _aggregate_bars(self, bars, timeframe_minutes, start_offset_minutes) -> List[Bar]: subbars = [] for b in bars: subbars.append(self.convertBar(b)) return process_low_tf_bars(subbars, timeframe_minutes, start_offset_minutes) def convertBar(self, apiBar: binance_f.model.candlestick.Candlestick): return Bar(tstamp=apiBar.openTime / 1000, open=apiBar.open, high=apiBar.high, low=apiBar.low, close=apiBar.close, volume=apiBar.volume) def get_instrument(self, symbol=None): if symbol is None: symbol = self.symbol instr: binance_f.model.exchangeinformation.ExchangeInformation = self.client.get_exchange_information( ) for symb in instr.symbols: if symb.symbol == symbol: baseLength = len(symb.baseAsset) lotSize = 0 tickSize = 0 for filter in symb.filters: if filter['filterType'] == 'LOT_SIZE': lotSize = filter['stepSize'] if filter['filterType'] == 'PRICE_FILTER': tickSize = filter['tickSize'] return Symbol( symbol=symb.symbol, isInverse=symb.baseAsset != symb.symbol[:baseLength], lotSize=lotSize, tickSize=tickSize, makerFee=0.02, takerFee=0.04) return None def get_position(self, symbol=None): if symbol is None: symbol = self.symbol return self.positions[symbol] if symbol in self.positions.keys( ) else None def is_open(self): return self.open def check_market_open(self): return self.open # TODO: is that the best we can do? def update_account(self, account: Account): pass
from binance_f import RequestClient from binance_f.constant.test import * from binance_f.base.printobject import * from binance_f.model.constant import * request_client = RequestClient(api_key=g_api_key, secret_key=g_secret_key) result = request_client.cancel_order(symbol="BTCUSDT", orderId=534333508) PrintBasic.print_obj(result)
def open_position_binance_futures(pair, take_profit, stop_loss, pair_change, quantity, leverage, side): global STOP_LOSS global TARGET global STOP_LOSS_REACHED global STOP_LOSS_ORDER_ID global TAKE_PROFIT_ORDER_ID request_client = RequestClient(api_key=API_KEY, secret_key=SECRET_KEY) # Cancel previous take profit and stop loss orders try: if (TAKE_PROFIT_ORDER_ID): request_client.cancel_order(symbol=pair, orderId=TAKE_PROFIT_ORDER_ID) except: print( red.bold('Take profit order id {} could not be cancelled'.format( TAKE_PROFIT_ORDER_ID))) try: if (STOP_LOSS_ORDER_ID): request_client.cancel_order(symbol=pair, orderId=STOP_LOSS_ORDER_ID) except: print( red.bold( 'Stop loss profit order id {} could not be cancelled'.format( STOP_LOSS_ORDER_ID))) STOP_LOSS_ORDER_ID = None TAKE_PROFIT_ORDER_ID = None # Change leverage try: request_client.change_initial_leverage(pair, leverage) except: print(red.bold('error changing leverage')) try: margin_type = request_client.change_margin_type( symbol=pair, marginType=FuturesMarginType.ISOLATED) except: print(red.bold('error changing margin type')) # Request info of all symbols to retrieve precision exchange_info = request_client.get_exchange_information() price_precision = 0 for item in exchange_info.symbols: if (item.symbol == pair): precision = item.quantityPrecision price_precision = item.pricePrecision # Create order quantity_rounded = float(quantity * leverage) / float(pair_change) quantity_with_precision = "{:0.0{}f}".format(quantity_rounded, precision) stop_loss = "{:0.0{}f}".format(stop_loss, price_precision) take_profit = "{:0.0{}f}".format(take_profit, price_precision) STOP_LOSS = stop_loss STOP_LOSS_REACHED = False TARGET = take_profit print( white.bold( '\n\tOpening future position {} at market ({}) with quantity: {} {} with take profit on: {} and stop loss: {}' .format(side, pair_change, quantity_with_precision, pair, take_profit, stop_loss))) order_side = OrderSide.BUY if (side == MarketSide.SHORT): order_side = OrderSide.SELL result = request_client.post_order(symbol=pair, side=order_side, quantity=quantity_with_precision, ordertype=OrderType.MARKET, positionSide="BOTH") orderId = result.orderId print(green.bold('\n\t\t✓ Market order created.')) # Set take profit and stop loss orders try: order_side = OrderSide.SELL if (side == MarketSide.SHORT): order_side = OrderSide.BUY result = request_client.post_order(symbol=pair, side=order_side, stopPrice=stop_loss, closePosition=True, ordertype=OrderType.STOP_MARKET, positionSide="BOTH", timeInForce="GTC") STOP_LOSS_ORDER_ID = result.orderId print( green.bold( '\n\t\t✓ Stop market order at: {} created.'.format(stop_loss))) result = request_client.post_order( symbol=pair, side=order_side, stopPrice=take_profit, closePosition=True, ordertype=OrderType.TAKE_PROFIT_MARKET, positionSide="BOTH", timeInForce="GTC") TAKE_PROFIT_ORDER_ID = result.orderId print( green.bold('\n\t\t✓ Take profit market at: {} creted.'.format( take_profit))) except: # Cancel order if something did not work as expected request_client.cancel_order(symbol=pair, orderId=orderId) print( red.bold( '\n\t\t x Something did not work as expected. Cancelling order' ))
class BinanceInterface(ExchangeInterface): def __init__(self, settings, logger, on_tick_callback=None): super().__init__(settings, logger, on_tick_callback) self.symbol: str = settings.SYMBOL self.client = RequestClient(api_key=settings.API_KEY, secret_key=settings.API_SECRET, url="https://fapi.binance.com") self.ws = BinanceWebsocket(wsURL="wss://fstream.binance.com/ws", api_key=settings.API_KEY, api_secret=settings.API_SECRET, logger=logger, callback=self.callback) # for binance the key is the internal id (not the exchange id) cause we can't update order but have to cancel # and reopen with same id. that leads to different exchange id, but we need to know its the same. self.orders = {} self.positions = {} self.symbol_object: Symbol = None self.candles: List[Candlestick] = [] self.last = 0 self.listen_key = "" self.lastUserDataKeep = None self.wantedResponses = 0 # needed to wait for realtime if self.is_open(): self.init() def init(self): self.logger.info("loading market data. this may take a moment") self.initOrders() self.initPositions() self.symbol_object = self.get_instrument() self.logger.info("got all data. subscribing to live updates.") self.listen_key = self.client.start_user_data_stream() self.lastUserDataKeep = time.time() self.wantedResponses = 2 subInt = CandlestickInterval.MIN1 if self.settings.MINUTES_PER_BAR <= 60 else CandlestickInterval.HOUR1 self.ws.subscribe_candlestick_event(self.symbol.lower(), subInt) self.ws.subscribe_user_data_event(self.listen_key) waitingTime = 0 while self.wantedResponses > 0 and waitingTime < 100: waitingTime += 1 time.sleep(0.1) if self.wantedResponses > 0: self.logger.error("got no response to subscription. outa here") self.ws.exit() else: self.logger.info("ready to go") def callback(self, data_type: 'SubscribeMessageType', event: 'any'): gotTick = False fromAccount = False # refresh userdata every 5 min if self.lastUserDataKeep < time.time() - 5 * 60: self.lastUserDataKeep = time.time() self.client.keep_user_data_stream() if data_type == SubscribeMessageType.RESPONSE: self.wantedResponses -= 1 # tell the waiting init that we got it. otherwise we might be too fast elif data_type == SubscribeMessageType.PAYLOAD: if event.eventType == "kline": # {'eventType': 'kline', 'eventTime': 1587064627164, 'symbol': 'BTCUSDT', # 'data': <binance_f.model.candlestickevent.Candlestick object at 0x0000016B89856760>} if event.symbol == self.symbol: candle: Candlestick = event.data if len(self.candles) > 0: if self.candles[ 0].startTime >= candle.startTime > self.candles[ -1].startTime: # somewhere inbetween to replace for idx in range(0, len(self.candles)): if candle.startTime == self.candles[ idx].startTime: self.candles[idx] = candle break elif candle.startTime > self.candles[0].startTime: self.candles.insert(0, candle) gotTick = True else: self.candles.append(candle) gotTick = True self.last = self.candles[0].close elif event.eventType == "ACCOUNT_UPDATE": # {'eventType': 'ACCOUNT_UPDATE', 'eventTime': 1587063874367, 'transactionTime': 1587063874365, # 'balances': [<binance_f.model.accountupdate.Balance object at 0x000001FAF470E100>,...], # 'positions': [<binance_f.model.accountupdate.Position object at 0x000001FAF470E1C0>...]} usdBalance = 0 gotTick = True fromAccount = True for b in event.balances: bal: Balance = b if bal.asset == "USDT": usdBalance = bal.walletBalance for p in event.positions: pos: Position = p if pos.symbol not in self.positions.keys(): self.positions[pos.symbol] = AccountPosition( symbol=pos.symbol, avgEntryPrice=float(pos.entryPrice), quantity=float(pos.amount), walletBalance=usdBalance if "USDT" in pos.symbol else 0) else: accountPos = self.positions[pos.symbol] accountPos.quantity = float(pos.amount) accountPos.avgEntryPrice = float(pos.entryPrice) if "USDT" in pos.symbol: accountPos.walletBalance = usdBalance elif event.eventType == "ORDER_TRADE_UPDATE": # {'eventType': 'ORDER_TRADE_UPDATE', 'eventTime': 1587063513592, 'transactionTime': 1587063513589, # 'symbol': 'BTCUSDT', 'clientOrderId': 'web_ybDNrTjCi765K3AvOMRK', 'side': 'BUY', 'type': 'LIMIT', # 'timeInForce': 'GTC', 'origQty': 0.01, 'price': 6901.0, 'avgPrice': 0.0, 'stopPrice': 0.0, # 'executionType': 'NEW', 'orderStatus': 'NEW', 'orderId': 2705199704, 'lastFilledQty': 0.0, # 'cumulativeFilledQty': 0.0, 'lastFilledPrice': 0.0, 'commissionAsset': None, 'commissionAmount': None, # 'orderTradeTime': 1587063513589, 'tradeID': 0, 'bidsNotional': 138.81, 'asksNotional': 0.0, # 'isMarkerSide': False, 'isReduceOnly': False, 'workingType': 'CONTRACT_PRICE'} gotTick = True fromAccount = True sideMulti = 1 if event.side == 'BUY' else -1 order: Order = Order( orderId=event.clientOrderId, stop=event.stopPrice if event.stopPrice > 0 else None, limit=event.price if event.price > 0 else None, amount=event.origQty * sideMulti) order.exchange_id = event.orderId # trigger of a stoplimit in Binance means "update for order -> expired" then "update -> as limit" order.stop_triggered = event.type == "LIMIT" and event.stopPrice > 0 order.executed_amount = event.cumulativeFilledQty * sideMulti order.executed_price = event.avgPrice order.tstamp = event.transactionTime order.execution_tstamp = event.orderTradeTime / 1000 order.active = event.orderStatus in ["NEW", "PARTIALLY_FILLED"] prev: Order = self.orders[ order.id] if order.id in self.orders.keys() else None if prev is not None: if prev.tstamp > order.tstamp or abs( prev.executed_amount) > abs(order.executed_amount): # already got newer information, probably the info of the stop order getting # triggered, when i already got the info about execution self.logger.info("ignoring delayed update for %s " % prev.id) if order.stop_price is None: order.stop_price = prev.stop_price if order.limit_price is None: order.limit_price = prev.limit_price prev = order if not prev.active and prev.execution_tstamp == 0: prev.execution_tstamp = datetime.utcnow().timestamp() self.orders[order.id] = prev self.logger.info("received order update: %s" % (str(order))) else: self.logger.warn("Unknown Data in websocket callback") if gotTick and self.on_tick_callback is not None: self.on_tick_callback( fromAccountAction=fromAccount) # got something new def initOrders(self): apiOrders = self.client.get_open_orders() for o in apiOrders: order = self.convertOrder(o) if order.active: self.orders[order.id] = order def resyncOrders(self): self.orders = {} self.initOrders() @staticmethod def convertOrder(apiOrder: binance_f.model.Order) -> Order: direction = 1 if apiOrder.side == OrderSide.BUY else -1 order = Order( orderId=apiOrder.clientOrderId, amount=apiOrder.origQty * direction, limit=apiOrder.price if apiOrder.price > 0 else None, stop=apiOrder.stopPrice if apiOrder.stopPrice > 0 else None) order.executed_amount = apiOrder.executedQty * direction order.executed_price = apiOrder.avgPrice order.active = apiOrder.status in ["NEW", "PARTIALLY_FILLED"] order.exchange_id = apiOrder.orderId return order def initPositions(self): balance = self.client.get_balance() usdBalance = 0 for bal in balance: if bal.asset == "USDT": usdBalance = bal.balance api_positions = self.client.get_position() self.positions[self.symbol] = AccountPosition( self.symbol, avgEntryPrice=0, quantity=0, walletBalance=usdBalance if "USDT" in self.symbol else 0) if api_positions is not None: for pos in api_positions: self.positions[pos.symbol] = AccountPosition( pos.symbol, avgEntryPrice=pos.entryPrice, quantity=pos.positionAmt, walletBalance=usdBalance if "USDT" in pos.symbol else 0) self.logger.info("starting with %.2f in wallet and pos %.2f @ %.2f" % (self.positions[self.symbol].walletBalance, self.positions[self.symbol].quantity, self.positions[self.symbol].avgEntryPrice)) def exit(self): self.ws.exit() self.client.close_user_data_stream() def internal_cancel_order(self, order: Order): if order.id in self.orders.keys(): self.orders[order.id].active = False self.client.cancel_order(symbol=self.symbol, origClientOrderId=order.id) def internal_send_order(self, order: Order): if order.stop_price is not None and ( self.last - order.stop_price) * order.amount >= 0: order.stop_price = None # already triggered if order.limit_price is not None: order.limit_price = round(order.limit_price, self.symbol_object.pricePrecision) if order.stop_price is not None: order.stop_price = round(order.stop_price, self.symbol_object.pricePrecision) order_type = OrderType.STOP else: order_type = OrderType.LIMIT elif order.stop_price is not None: order.stop_price = round(order.stop_price, self.symbol_object.pricePrecision) order_type = OrderType.STOP_MARKET else: order_type = OrderType.MARKET order.amount = round(order.amount, self.symbol_object.quantityPrecision) quantityFormat = "{:." + str( self.symbol_object.quantityPrecision) + "f}" priceFormat = "{:." + str(self.symbol_object.pricePrecision) + "f}" # yes have to send the price and quantity in as str (although it wants float) cause otherwise it converts it # inernally and that sometimes f**k up the precision (0.023 -> 0.02299999999) resultOrder: binance_f.model.Order = self.client.post_order( symbol=self.symbol, side=OrderSide.BUY if order.amount > 0 else OrderSide.SELL, ordertype=order_type, timeInForce=TimeInForce.GTC if order_type in [OrderType.LIMIT, OrderType.STOP] else None, quantity=quantityFormat.format(abs(order.amount)), price=priceFormat.format(order.limit_price) if order.limit_price is not None else None, stopPrice=priceFormat.format(order.stop_price) if order.stop_price is not None else None, newClientOrderId=order.id) order.exchange_id = resultOrder.orderId def internal_update_order(self, order: Order): self.cancel_order(order) # stupid binance can't update orders self.on_tick_callback(True) # triggers a reset of the tick-delay. # otherwise we risk a tick to be calced after the cancel, before the new order self.send_order(order) def get_orders(self) -> List[Order]: return list(self.orders.values()) def get_bars(self, timeframe_minutes, start_offset_minutes) -> List[Bar]: tf = CandlestickInterval.MIN1 if timeframe_minutes <= 60 else CandlestickInterval.HOUR1 bars = self.client.get_candlestick_data(symbol=self.symbol, interval=tf, limit=1000) subbars = [] for b in reversed(bars): subbars.append(self.convertBar(b)) return process_low_tf_bars(subbars, timeframe_minutes, start_offset_minutes) def recent_bars(self, timeframe_minutes, start_offset_minutes) -> List[Bar]: subbars = [] for b in self.candles: subbars.append(self.convertBarevent(b)) return process_low_tf_bars(subbars, timeframe_minutes, start_offset_minutes) @staticmethod def convertBar(apiBar: binance_f.model.candlestick.Candlestick): return Bar(tstamp=apiBar.openTime / 1000, open=float(apiBar.open), high=float(apiBar.high), low=float(apiBar.low), close=float(apiBar.close), volume=float(apiBar.volume)) @staticmethod def convertBarevent(apiBar: binance_f.model.candlestickevent.Candlestick): return Bar(tstamp=apiBar.startTime / 1000, open=float(apiBar.open), high=float(apiBar.high), low=float(apiBar.low), close=float(apiBar.close), volume=float(apiBar.volume)) @staticmethod def barArrayToBar(b): return Bar(tstamp=b[0] / 1000, open=float(b[1]), high=float(b[2]), low=float(b[3]), close=float(b[4]), volume=float(b[5])) def get_instrument(self, symbol=None): if symbol is None: symbol = self.symbol instr: binance_f.model.exchangeinformation.ExchangeInformation = self.client.get_exchange_information( ) for symb in instr.symbols: if symb.symbol == symbol: baseLength = len(symb.baseAsset) lotSize = 1 tickSize = 1 for filterIt in symb.filters: if filterIt['filterType'] == 'LOT_SIZE': lotSize = float(filterIt['stepSize']) if filterIt['filterType'] == 'PRICE_FILTER': tickSize = float(filterIt['tickSize']) return Symbol( symbol=symb.symbol, isInverse=symb.baseAsset != symb.symbol[:baseLength], lotSize=lotSize, tickSize=tickSize, makerFee=0.02, takerFee=0.04, pricePrecision=symb.pricePrecision, quantityPrecision=symb.quantityPrecision) return None def get_position(self, symbol=None): if symbol is None: symbol = self.symbol return self.positions[symbol] if symbol in self.positions.keys( ) else None def is_open(self): return not self.ws.exited def check_market_open(self): return self.is_open() def update_account(self, account: Account): pos = self.positions[self.symbol] account.open_position = pos account.equity = pos.walletBalance account.usd_equity = account.equity
def Cancel_order(buyId): request_client = RequestClient(api_key=g_api_key, secret_key=g_secret_key) result = request_client.cancel_order(symbol="BTCUSDT", orderId=buyId) return result