class BinanceDatasource(Observable): ''' This class open a data stream on Binance for receiving in real time the aggregates trades on the trading pair specified at construction time. Definition: The Aggregate Trade Streams push trade information that is aggregated for a single taker order. ''' DECODE_PW = 'c2_pw%&_23' def __init__(self, tradingPair): ''' Constructor. :param tradingPair: example: 'BTCUSDT' ''' super().__init__() self.tradingPair = tradingPair self.socketManager = None self.connectionKey = None def startDataReception(self): ''' Start the Binance data stream. :return: ''' apiKeyMgr = ApiKeyFileGenerator() # obtain from file the binance encoded API keys. This file was created using # ApiKeyFileGenerator. with open(apiKeyMgr.FILE_PATH + 'bi.bin', 'rb') as handle: encryptedKeyList = pickle.load(handle) # decode the keys with the pw used to encode them api_key = apiKeyMgr.decode(self.DECODE_PW, encryptedKeyList[0]) api_secret_key = apiKeyMgr.decode(self.DECODE_PW, encryptedKeyList[1]) binanceClient = Client(api_key, api_secret_key) self.socketManager = BinanceSocketManager(binanceClient) # start any sockets here, i.e a trade socket self.connectionKey = self.socketManager.start_aggtrade_socket( self.tradingPair, self.notifyObservers) # then start the socket manager self.socketManager.start() def stopObservable(self): ''' Stop the Binance data stream. :return: ''' if self.socketManager: # self.socketManager == None if connection could not be established self.socketManager.stop_socket(self.connectionKey) # required for the program to exit try: reactor.stop() except ReactorNotRunning: # the case if connection could not be established pass super().stopObservable() def processData(self, data): ''' Process the raw data received from Binance before sending it to the Observer. :param data: raw data streamed by Binance in the form of a dictionary structured as { "e": "aggTrade", // Event type "E": 123456789, // Event time "s": "BNBBTC", // Symbol "a": 12345, // Aggregate trade ID "p": "0.001", // Price "q": "100", // Quantity "f": 100, // First trade ID "l": 105, // Last trade ID "T": 123456785, // Trade time "m": true, // Is the buyer the market maker? "M": true // Ignore. } :return: ''' timestampStr = data['T'] priceStr = data['p'] volumeStr = data['q'] #converting string data before writing them to the csv file timestampMilliSec = int(timestampStr) priceFloat = float(priceStr) volumeFloat = float(volumeStr) return timestampMilliSec, volumeFloat, priceFloat
class LiveTrading: def __init__(self, client:object, strategy:object, klines:dict={}): self.client:object = client self.strategy = strategy self.trades = [] self.verbose = False self.debug = False self.precision:dict = {} self.klines:dict = klines self.message_no:int = 0 for coin in self.strategy.tradeCoins: if self.verbose: print(f"Getting precision for {coin}") self.precision[coin] = self.get_precision(coin) self.klines[coin] = [] self.active_order:bool = False self.open_trade:bool = False self.balance:float = self.get_balance(self.strategy.baseCoin) self.starting_balance:float = self.balance print(f"\nStarting trading with the following:") print(f"Trade coins: {self.strategy.tradeCoins}") print(f"Starting {self.strategy.baseCoin}: {self.balance}") print(f"Indicator: {self.strategy.indicator}") print(f"Strategy: {self.strategy.strategy}") self.open_kline_sockets(self.strategy.tradeCoins) def get_balance(self, coin): return float(self.client.get_asset_balance(asset=coin)["free"]) def open_kline_sockets(self, coins:list): print(f"\nOpening kline socket for {coins}") self.bm = BinanceSocketManager(self.client) sockets = [] for coin in coins: sockets.append(f"{coin.lower()}{self.strategy.baseCoin.lower()}@kline_{self.strategy.interval}") self.kline_socket = self.bm.start_multiplex_socket(sockets, self.process_message) self.bm.start() @staticmethod def print_with_timestamp(message): print(f"\n{time.strftime('%H:%M:%S', time.localtime())} | {message}") def process_message(self, msg): msg = msg["data"] if self.verbose: self.print_with_timestamp(f"Recieved kline for {msg['s']}") if self.debug: print(msg) if (msg['e'] == "kline"): self.process_kline(msg['k']) elif msg['e'] == 'error': print("Socket error... restarting socket") self.bm.close() self.open_kline_sockets(self.strategy.tradeCoins) def process_kline(self, kline): if kline['x'] == True: self.message_no += 1 trade_coin = f"{kline['s'][:len(kline['s']) - len(self.strategy.baseCoin)]}" self.klines[trade_coin].append(self.kline_to_ohlcv(kline, self.verbose, self.debug)) if (self.verbose): self.print_with_timestamp(f"Obtained closed kline and converted to ohlcv. Count for {kline['s']}: {len(self.klines[trade_coin])}") if (self.debug): print(self.klines) if self.message_no == len(self.strategy.tradeCoins): self.message_no = 0 self.print_with_timestamp("Checking for any actions...") self.strategy.refresh(self.klines) # If the strategy is returning more trades than we have, there must be new ones if len(self.strategy.trades) > len(self.trades): new_trades = self.strategy.trades[len(self.trades):] print(f"New trades: {new_trades}") self.process_trades(new_trades) self.trades += new_trades def process_trades(self, trades): for trade in trades: if not trade.completed: if trade.action == "BUY": self.place_buy(trade.trade_coin, trade.price) elif trade.action == "SELL": self.place_sell(trade.trade_coin, trade.price) trade.completed = True def place_buy(self, coin, price): self.balance = self.get_balance(self.strategy.baseCoin) quantity = self.round_down((self.balance * 0.99) / float(price), self.precision[coin]) print(f"Buying {quantity} {coin} at {price}") order = self.client.create_order( symbol=f"{coin}{self.strategy.baseCoin}", side=SIDE_BUY, type=ORDER_TYPE_LIMIT, timeInForce=TIME_IN_FORCE_GTC, quantity=quantity, price=price ) print(order) def place_sell(self, coin, price): balance = self.get_balance(coin) quantity = self.round_down(balance, self.precision[coin]) if (quantity != 0): print(f"\nSelling {quantity} {coin} at {price}") order = self.client.create_order( symbol=f"{coin}{self.strategy.baseCoin}", side=SIDE_SELL, type=ORDER_TYPE_LIMIT, timeInForce=TIME_IN_FORCE_GTC, quantity=quantity, price=price ) print(order) else: print(f"Something went wrong. Bot is trying to sell 0 {coin}") def get_precision(self, coin): for filt in self.client.get_symbol_info(f"{coin}{self.strategy.baseCoin}")['filters']: if filt['filterType'] == 'LOT_SIZE': return int(round(-math.log(float(filt['stepSize']), 10), 0)) @staticmethod def round_down(n, decimals=0): return math.floor(n * (10 ** decimals)) / 10 ** decimals @staticmethod def kline_to_ohlcv(kline, verbose, debug): # This converts the kline from the socket stream to the ohclv data # so it is the same as the backtesting historical data returned from API # which is what a Strategy accepts ohlcv = [ # Open time kline['t'], # Open kline['o'], # High kline['h'], # Low kline['l'], # Close kline['c'], # Volume kline['v'], # Close time kline['T'], # Quote asset volume kline['q'], # Number of trades kline['n'], # Taker buy base asset volume kline['V'], # Taker buy quote asset volume kline['Q'], # Ignore kline['B'] ] if verbose: print("\nUnpacked closed kline to ohlcv") if debug: print(ohlcv) return ohlcv
def get_websocket_client(config, exchange_manager): ws_client = BinanceWebSocketClient(config, exchange_manager) ws_client.socket_manager = BinanceSocketManager(ws_client.client) return ws_client
res = json.loads(data) print(res) params.update({k: float(res[k]) for k in res}) print(params) except Exception as e: print(e) cmdThread = threading.Thread(target=monitorParams) cmdThread.start() tc = Client(keys['key'][0], keys['key'][1], tld='us') pm = PortfolioManager() bm = BinanceSocketManager(tc, context='us') om = OrderManager(tc) params = { 'ready': 0, 'posUpperLimit': 0, 'posLowerLimit': 0, 'spread': 10.1, 'buysellSkew': 0.0, 'alphaMultiplier': 0.0, 'positionSkew': 0.0 } def processmymsg(msg: dict): print(msg)
'O', # Statistics open time 'C', # Statistics close time 'F', # First trade ID 'L', # Last trade Id 'n', # Total number of trades ]), 'error': False } def btc_pairs_trade(msg): # define how to process incoming WebSocket messages if msg['e'] != 'error': log = pd.DataFrame({x: [msg[x]] for x in msg}) log.to_csv(pairs + '.csv') #, header = False, mode = 'a') else: price['error']: True # init and start the WebSocket bsm = BinanceSocketManager(client) conn_key = bsm.start_symbol_ticker_socket(pairs, btc_pairs_trade) bsm.start() while (True): if price['error']: # stop and restart socket bsm.stop_socket(conn_key) bsm.start() price['error'] = False
def start_user_monitor(self): self.bsm = BinanceSocketManager(self.client) self.conn_key = self.bsm.start_user_socket(self.process_user_update) self.bsm.start() self.log.notice( "Starting account monitor listener. Press Ctrl+C to exit.")
# withdraws = client.get_withdraw_history() # # # fetch list of ETH withdrawals # eth_withdraws = client.get_withdraw_history(asset='ETH') # # # get a deposit address for BTC # address = client.get_deposit_address(asset='BTC') # # start aggregated trade websocket for BNBBTC def process_message(msg): print("message type: {}".format(msg['e'])) print(msg) # do something from binance.websockets import BinanceSocketManager bm = BinanceSocketManager(client) bm.start_aggtrade_socket('ETHUSDT', process_message) bm.start() time.sleep(100000) # get historical kline data from any date range # fetch 1 minute klines for the last day up until now # klines = client.get_historical_klines("BNBBTC", Client.KLINE_INTERVAL_1MINUTE, "1 day ago UTC") # # # fetch 30 minute klines for the last month of 2017 # klines = client.get_historical_klines("ETHBTC", Client.KLINE_INTERVAL_30MINUTE, "1 Dec, 2017", "1 Jan, 2018") # # # fetch weekly klines since it listed # klines = client.get_historical_klines("NEOBTC", Client.KLINE_INTERVAL_1WEEK, "1 Jan, 2017")
def run(self): self.client = Client(api_key=self.config['BINANCE']['KEY'], api_secret=self.config['BINANCE']['SECRET']) if self.args.mode == "trading": logger.info( "START TRADE | symbol: {}, btc amount: {}, targets: {}, stoploss price: {}, trailing: {}, trailing price: {}" .format(self.args.symbol, self.args.btc_amount, self.args.targets, self.args.immediate_stoploss, self.args.use_trailing, self.args.trailing_stoploss)) bm = BinanceSocketManager(self.client) self.conn_key = bm.start_symbol_ticker_socket( self.args.symbol, self.process_message) bm.start() elif self.args.mode == "analysis": alltickers = self.client.get_ticker() interval = "1h" exchange = ccxt.binance({ 'apiKey': self.config['BINANCE']['KEY'], 'secret': self.config['BINANCE']['SECRET'] }) for ticker in alltickers: if float(ticker['priceChangePercent']) > 2 and ( "BTC" in ticker['symbol']): data_base = exchange.fetch_ohlcv( ticker['symbol'].split("BTC")[0] + "/BTC", interval, limit=100) df = pd.DataFrame(data_base, columns=[ 'date', 'open', 'high', 'low', 'close', 'volume' ]) df["date"] = pd.to_datetime( df["date"], unit='ms').dt.strftime('%Y-%m-%d %H:%M') self.save_analysis(df, ticker['symbol'], interval, ticker['priceChangePercent']) elif self.args.mode == "hamster": mongo_client = MongoClient('mongodb://localhost:27017/') db = mongo_client.projectlife self.previous_response = "initial" timeout = 30 exchanges = dict() exchanges['binance'] = ccxt.binance({ 'apiKey': self.config['BINANCE']['KEY'], 'secret': self.config['BINANCE']['SECRET'] }) exchanges['kucoin'] = ccxt.kucoin({ 'apiKey': self.config['KUCOIN']['KEY'], 'secret': self.config['KUCOIN']['SECRET'] }) exchanges['bittrex'] = ccxt.bittrex({ 'apiKey': self.config['BITTREX']['KEY'], 'secret': self.config['BITTREX']['SECRET'] }) exchanges['poloniex'] = ccxt.poloniex() def doWork(): responses = [] try: url = 'https://www.mininghamster.com/api/v2/' + self.config[ 'HAMSTER']['API'] responses = requests.get(url).json() if len(responses) > 0: for response in responses: symbol = response['market'].split( "BTC-")[1] + "/BTC" bid, ask = self.get_prices( exchanges[response['exchange']], symbol) if response['signalmode'] == "buy": result_buy = db.hamster.find_one({ "signalID": response['signalID'], "signalmode": "buy" }) if result_buy == None: response['buy_price'] = ask db.hamster.insert_one(response) self.send_telegram(str(response)) elif response['signalmode'] == "sell": result_sell = db.hamster.find_one({ "signalID": response['signalID'], "signalmode": "sell" }) if result_sell == None: result_buy = db.hamster.find_one({ "signalID": response['signalID'], "signalmode": "buy" }) if result_buy != None: response['sell_price'] = bid response['profit'] = self.pct_change( result_buy['buy_price'], bid) db.hamster.insert_one(response) self.send_telegram(str(response)) except BaseException as e: print(e) pass lx = task.LoopingCall(doWork) lx.start(timeout) reactor.run() elif self.args.mode == "datacollect": client = MongoClient('mongodb://localhost:27017/') db = client.projectlife self.db_collection = db[self.args.symbol] bm = BinanceSocketManager(self.client) self.conn_key = bm.start_symbol_ticker_socket( self.args.symbol, self.process_datacollect_message) bm.start()
class BinanceDataListener(ExchangeDataListener): PORTFOLIO_UPDATE_STRING = 'outboundAccountInfo' ORDER_UPDATE_STRING = 'executionReport' def __init__(self, exchangeClient, marketDataManager, marketRulesManager, portfolioManager, orderManager): super(BinanceDataListener, self).__init__(exchangeClient, marketDataManager, marketRulesManager, portfolioManager, orderManager) self.binanceSocket = BinanceSocketManager( self.exchangeClient.getRawClient()) self.binanceSocket.setDaemon(True) self.log.init(logForceDebug=False) def dispatchUserDataUpdate(self, msg): self.log.debug('User data message received: ' + str(msg)) if msg['e'] == self.PORTFOLIO_UPDATE_STRING: self.processPortfolioUpdate(msg) elif msg['e'] == self.ORDER_UPDATE_STRING: self.processOrderUpdate(msg) def parseOrderUpdate(self, msg): symbol = msg['s'] quoteAsset = SupportedQuoteAsset.getQuoteAsset( symbol, BINANCE_SUPPORTED_QUOTE_ASSET) baseAsset = symbol[:len(symbol) - len(quoteAsset)] orderResponse = OrderResponse( baseAsset=baseAsset, quoteAsset=quoteAsset, orderSide=BinanceOrderSideMapper.getCretenValue(msg['S']), orderType=BinanceOrderTypeMapper.getCretenValue(msg['o']), origQty=msg['q'], lastExecutedQty=msg['l'], sumExecutedQty=msg['z'], price=msg['p'], orderTmstmp=datetime.fromtimestamp(msg['T'] / 1000), orderState=BinanceOrderStateMapper.getCretenValue(msg['X']), clientOrderId=msg['c'], extOrderRef=msg['i'], rawData=msg) return orderResponse def parsePortfolioUpdate(self, msg): positions = [] for balance in msg['B']: asset = balance['a'] free = float(balance['f']) locked = float(balance['l']) # TODO do only for subscribed pairs positions.append(Position(asset, free, locked)) return positions def parseCandleUpdate(self, msg): symbol = msg['s'] quoteAsset = SupportedQuoteAsset.getQuoteAsset( symbol, BINANCE_SUPPORTED_QUOTE_ASSET) baseAsset = symbol[:len(symbol) - len(quoteAsset)] interval = msg['k']['i'] kline = msg['k'] cretenInterval = BinanceIntervalMapper.getCretenValue(interval) candle = Candle( baseAsset=baseAsset, quoteAsset=quoteAsset, interval=cretenInterval, openTime=datetime.fromtimestamp(int(kline['t']) / 1000), open=kline['o'], high=kline['h'], low=kline['l'], close=kline['c'], volume=kline['v'], closeTime=datetime.fromtimestamp(int(kline['T']) / 1000), quoteAssetVolume=kline['q'], tradesNb=kline['n'], takerBuyBaseAssetVol=kline['V'], takerBuyQuoteAssetVol=kline['Q'], isClosing=kline['x']) return candle def start(self): # subsribe candle listeners for candleSubscription in self.candleSubscriptions: binanceInterval = BinanceIntervalMapper.getBinanceValue( candleSubscription.cretenInterval) self.binanceSocket.start_kline_socket( candleSubscription.pair.getSymbol(), self.processCandleUpdate, binanceInterval) # subscribe user data listener self.binanceSocket.start_user_socket(self.dispatchUserDataUpdate) # start listening self.binanceSocket.start()
class Market: def __init__(self, symbol_ticker_callback: Callable[[float], None], order_traded_callback: Callable[[str, float, float], None], account_balance_callback: Callable[[AccountBalance], None], client_mode: str): self.symbol_ticker_callback: Callable[[float], None] = symbol_ticker_callback self.order_traded_callback: Callable[[str, float, float], None] = order_traded_callback self.account_balance_callback: Callable[ [AccountBalance], None] = account_balance_callback self.client_mode = client_mode # symbol must be passed as argument o get from configuration file self.symbol = 'BTCEUR' # set control flags self.is_symbol_ticker_on = False # when off symbol ticker socket U/S # create client depending on client_mode parameter self.client: Union[Client, FakeClient] self.client, self.simulator_mode = self.set_client(client_mode) # self.start_sockets() def start_sockets(self): if not self.simulator_mode: # sockets only started in binance mode (not in simulator mode) self._start_sockets() else: self.client.start_cmp_generator() pass log.info(f'client initiated in {self.client_mode} mode') # ********** callback functions ********** def binance_user_socket_callback(self, msg) -> None: # called from Binance API each time an order is traded and # each time the account balance changes event_type: str = msg['e'] if event_type == 'executionReport': if (msg['x'] == 'TRADE') and (msg["X"] == 'FILLED'): # order traded uid = str(msg['c']) order_price = float(msg['L']) bnb_commission = float(msg['n']) # trigger actions for traded order in session self.order_traded_callback(uid, order_price, bnb_commission) elif (msg['x'] == 'NEW') and (msg["X"] == 'NEW'): # order accepted (PLACE confirmation) # not used by the moment pass elif event_type == 'outboundAccountPosition': # account balance change balances = msg['B'] d = {} # create dictionary from msg to use in account balance instantiation for item in balances: # to avoid errors in case of having more assets if item['a'] in ['BTC', 'EUR', 'BNB']: # set precision if item['a'] in ['BTC', 'BNB']: p = 8 else: p = 2 ab = AssetBalance(name=item['a'], free=float(item['f']), locked=float(item['l']), tag='current', precision=p) d.update(ab.to_dict(symbol=self.symbol)) account_balance = AccountBalance(d=d) self.account_balance_callback(account_balance) def binance_symbol_ticker_callback(self, msg: Any) -> None: # called from Binance API each time the cmp is updated if msg['e'] == 'error': log.critical(f'symbol ticker socket error: {msg["m"]}') elif msg['e'] == '24hrTicker': # trigger actions for new market price cmp = float(msg['c']) self.symbol_ticker_callback(cmp) else: log.critical(f'event type not expected: {msg["e"]}') # ********** calls to binance api ********** def place_order(self, order: Order) -> Optional[dict]: # TODO: check and test it try: msg = self.client.create_order( symbol='BTCEUR', side=order.k_side, type=k_binance.ORDER_TYPE_LIMIT, timeInForce=k_binance.TIME_IN_FORCE_GTC, # TODO: check precision quantity=order.get_amount(precision=6), price=order.get_price_str(precision=2), newClientOrderId=order.uid) if msg: d = dict(binance_id=msg['orderId'], status=msg.get('status')) return d else: log.critical(f'error when placing order {order}') except (BinanceRequestException, BinanceAPIException, BinanceOrderException, BinanceOrderMinAmountException, BinanceOrderMinPriceException, BinanceOrderMinTotalException, BinanceOrderUnknownSymbolException, BinanceOrderInactiveSymbolException) as e: log.critical(e) except (ConnectionError, ReadTimeout) as e: log.critical(e) return None # msg['orderId'], msg['status'] == 'FILLED' or 'NEW' def get_symbol_info(self, symbol: str) -> Optional[dict]: # return dict with the required values for checking order values try: d = self.client.get_symbol_info(symbol) if d: base_precision = int(d.get('baseAssetPrecision')) # symbol 1 max_price = float(d.get('filters')[0].get('maxPrice')) min_price = float(d.get('filters')[0].get('minPrice')) max_qty = float(d.get('filters')[2].get('maxQty')) min_qty = float(d.get('filters')[2].get('minQty')) min_notional = float( d.get('filters')[3].get('minNotional')) # price * qty quote_precision = int(d.get('quoteAssetPrecision')) # symbol 2 return dict(base_precision=base_precision, max_price=max_price, min_price=min_price, max_qty=max_qty, min_qty=min_qty, min_notional=min_notional, quote_precision=quote_precision) else: log.critical(f'no symbol info from Binance for {symbol}') except (BinanceAPIException, BinanceRequestException) as e: log.critical(e) return None def get_asset_balance(self, asset: str, tag: str, p=8) -> AssetBalance: try: d = self.client.get_asset_balance(asset) free = float(d.get('free')) locked = float(d.get('locked')) return AssetBalance(name=asset, free=free, locked=locked, tag=tag, precision=p) except (BinanceAPIException, BinanceRequestException) as e: log.critical(e) def get_cmp(self, symbol: str) -> float: cmp = self.client.get_avg_price(symbol=symbol) return float(cmp['price']) def cancel_orders(self, orders: List[Order]): log.info('********** CANCELLING PLACED ORDER(S) **********') for order in orders: try: d = self.client.cancel_order(symbol='BTCEUR', origClientOrderId=order.uid) log.info(f'** ORDER CANCELLED IN BINANCE {order}') except (BinanceAPIException, BinanceRequestException) as e: log.critical(e) # ********** binance configuration methods ********** def set_client(self, client_mode) -> (Union[Client, FakeClient], bool): client: Union[Client, FakeClient] is_simulator_mode = False if client_mode == 'binance': api_keys = { "key": "JkbTNxP0s6x6ovKcHTWYzDzmzLuKLh6g9gjwHmvAdh8hpsOAbHzS9w9JuyYD9mPf", "secret": "IWjjdrYPyaWK4yMyYPIRhdiS0I7SSyrhb7HIOj4vjDcaFMlbZ1ygR6I8TZMUQ3mW" } client = Client(api_keys['key'], api_keys['secret']) elif client_mode == 'simulated': client = FakeClient( user_socket_callback=self.binance_user_socket_callback, symbol_ticker_callback=self.binance_symbol_ticker_callback, mode=FakeCmpMode.MODE_GENERATOR) is_simulator_mode = True else: log.critical(f'client_mode {client_mode} not accepted') sys.exit() return client, is_simulator_mode def _start_sockets(self): # init socket manager self._bsm = BinanceSocketManager(client=self.client) # symbol ticker socket self._symbol_ticker_s = self._bsm.start_symbol_ticker_socket( symbol=self.symbol, callback=self.binance_symbol_ticker_callback) # user socket self._user_s = self._bsm.start_user_socket( callback=self.binance_user_socket_callback) # start sockets self._bsm.start() def stop(self): self._bsm.stop_socket(self._symbol_ticker_s) self._bsm.stop_socket(self._user_s) # properly close the WebSocket, only if it is running # trying to stop it when it is not running, will raise an error if reactor.running: reactor.stop()
def stop_trading(self): bm = BinanceSocketManager(self.client) bm.stop_socket(self.conn_key) bm.close() reactor.stop()
class Binance(): binance = None client = Client("a", "b") # get market depth depth = client.get_order_book(symbol='BNBBTC') # place a test market buy order, to place an actual order use the create_order function order = client.create_test_order(symbol='BNBBTC', side=Client.SIDE_BUY, type=Client.ORDER_TYPE_MARKET, quantity=100) # get all symbol prices prices = client.get_all_tickers() # withdraw 100 ETH # check docs for assumptions around withdrawals from binance.exceptions import BinanceAPIException, BinanceWithdrawException try: result = client.withdraw(asset='ETH', address='<eth_address>', amount=100) except BinanceAPIException as e: print(e) except BinanceWithdrawException as e: print(e) else: print("Success") # fetch list of withdrawals withdraws = client.get_withdraw_history() # fetch list of ETH withdrawals eth_withdraws = client.get_withdraw_history(asset='ETH') # get a deposit address for BTC address = client.get_deposit_address(asset='BTC') # start aggregated trade websocket for BNBBTC def process_message(msg): print("message type: {}".format(msg['e'])) print(msg) # do something from binance.websockets import BinanceSocketManager bm = BinanceSocketManager(client) bm.start_aggtrade_socket('BNBBTC', process_message) bm.start() # get historical kline data from any date range # fetch 1 minute klines for the last day up until now klines = client.get_historical_klines("BNBBTC", Client.KLINE_INTERVAL_1MINUTE, "1 day ago UTC") # fetch 30 minute klines for the last month of 2017 klines = client.get_historical_klines("ETHBTC", Client.KLINE_INTERVAL_30MINUTE, "1 Dec, 2017", "1 Jan, 2018") # fetch weekly klines since it listed klines = client.get_historical_klines("NEOBTC", Client.KLINE_INTERVAL_1WEEK, "1 Jan, 2017")
operationsIndex += 1 return queryObject # Read configuration config = configparser.ConfigParser() config.read('config.ini') apiKey = config['authentication']['apikey'] apiSecret = config['authentication']['apisecret'] symbol = config['symbol']['name'] depth = config['symbol']['depth'] dbHost = config['datastore']['dbhost'] dbName = config['datastore']['dbname'] dbPassword = config['datastore']['dbpassword'] dbPort = config['datastore']['dbport'] dbUser = config['datastore']['dbuser'] # connect to database dbClient = influxdb.InfluxDBClient(host=dbHost, port=dbPort, username=dbUser, password=dbPassword, database=dbName) # Create connection and websocket to Binance API bnClient = BinanceClient(apiKey, apiSecret) wsManager = BinanceSocketManager(bnClient) connection = wsManager.start_depth_socket(symbol, writeToInflux, depth=depth) wsManager.start()
class BinanceExchangeService(ExchangeClientBase): """ Binance Exchange Services (Depends on 3rd party binance websockets library, python-binanc)e https://github.com/sammchardy/python-binance binance_response_mapping: ("s", "symbol"), ("E", "timestamp"), ("h", "high"), ("l", "low"), ("b", "bid"), ("B", "bid_volume"), ("a", "ask"), ("A", "ask_volume"), ("w", "w_av_price"), ("o", "open"), ("c", "close"), ("x", "previous_close"), ("p", "change"), ("P", "percentage"), ("v", "base_volume"), ("q", "quote_volume") """ _binance_item_getter, _binance_quote_keys = zip( *[("E", "timestamp"), ("h", "high"), ("l", "low"), ( "b", "bid"), ("B", "bid_volume"), ("a", "ask"), ( "A", "ask_volume"), ("v", "base_volume"), ("q", "target_volume"), ("o", "open"), ("c", "close"), ("x", "previous_close"), ("p", "change"), ("s", "ticker")]) _binance_item_getter = itemgetter(*_binance_item_getter) def __init__(self, **kwargs): ExchangeClientBase.__init__(self, "binance", **kwargs) symbol_infos = requests.get( "https://api.binance.com/api/v1/exchangeInfo").json()["symbols"] self.binance_symbol_mapping = { info["symbol"]: (info["baseAsset"], info["quoteAsset"]) for info in symbol_infos } self.binance_socket_manager = BinanceSocketManager( Client(KeyChain.get_key("binance"), KeyChain.get_secret("binance"))) def process_ticker_response(self, tickers_response): self.logger.debug( "Received ticker response {}".format(tickers_response), truncate=480) quotes = [] append_to_quotes = quotes.append for ticker_response in tickers_response: quote = dict( zip(self._binance_quote_keys, self._binance_item_getter(ticker_response))) quote["base"], quote["target"] = self.get_base_target( quote["ticker"]) append_to_quotes(quote) self.save_quotes(quotes) self.logger.info("Saved {} tickers".format(len(quotes))) def get_base_target(self, ticker): return self.binance_symbol_mapping[ticker] def start(self): super().start() self.binance_socket_manager.start_ticker_socket( self.process_ticker_response) self.binance_socket_manager.start() while not self.EXCHANGE_STOPPED: pass def stop(self): try: reactor.stop() # pylint: disable=E1101 self.binance_socket_manager.close() except ReactorNotRunning: pass super().stop()
from bson.objectid import ObjectId mongo_client = MongoClient('localhost', 27017) db = mongo_client.binance db.BTC.drop() collection = db.BTC client = Client( '5eCTxuKOs5VPCNZHVoeutoIV4fthRaGunndt1K77gqjK19lIuPar0Y8GzHrveVoE', 'BnF5gPIUfHVSRgwwinI8fku1sRIhteehlZdIiZEeZmAJihEUnB4xt0XUb5EXeJIr') prices = client.get_all_tickers() bm = BinanceSocketManager(client) class MyDict(dict): pass tick = {} localTime = 0 def process_message(tickers): global tick, collection, localTime if localTime == 0: localTime = int(int(tickers[0]['E']) / 1000)
:param values: Assets quantity :param token_usdt: Token pair price dict :return: list of asset values in USDT """ assets_in_usdt = [] for i, token in enumerate(assets): if token != 'USDT': assets_in_usdt.append( float(values[i]) * float(token_usdt[token + 'USDT'])) else: assets_in_usdt.append(float(values[i]) * 1) return assets_in_usdt # Streaming data for tokens in the portfolio bm = BinanceSocketManager(client) for tokenpair in token_pairs: conn_key = bm.start_symbol_ticker_socket(tokenpair, streaming_data_process) bm.start() time.sleep( 5) # To give sufficient time for all tokenpairs to establish connection app = dash.Dash(__name__, external_stylesheets=[dbc.themes.FLATLY]) server = app.server app.layout = html.Div([ html.Div([ html.Div([ dcc.Graph(id='figure-1', figure={ 'data': [
class AccountMonitor(object): def __init__(self, credentials=None, name="default"): """Create a Binance account monitor that can access account details If neither an initialized client nor valid credentials are passed, an attempt will be made to load credentials from cache, or prompt user for them. :param credentials: Binance API key and secret (optional) :param name: Nickname for this account. Optional, default value is "default" """ self.log = Logger(__name__.split(".", 1)[-1]) if not credentials: credentials = settings.get_credentials() self.client = Client(*credentials) self.exchange_info = exchange.Exchange(self.client) self.name = name self.trade_store = store.TradeStore(name) self.bsm: Optional[BinanceSocketManager] = None self.conn_key = None atexit.register(self._stop_user_monitor) def start_user_monitor(self): self.bsm = BinanceSocketManager(self.client) self.conn_key = self.bsm.start_user_socket(self.process_user_update) self.bsm.start() self.log.notice( "Starting account monitor listener. Press Ctrl+C to exit.") def _stop_user_monitor(self): if self.conn_key is not None: self.bsm.stop_socket(self.conn_key) self.conn_key = None self.log.notice("Account monitor has been shutdown") def process_user_update(self, msg: dict): update = EventUpdate.create(msg) if isinstance(update, OrderUpdate) and update.is_trade_event: self.trade_store.add_trade(update.trade) print(update.trade) settings.Blacklist.remove(update.symbol) def get_trade_history_for(self, symbols: List) -> None: """Get full trade history from the API for each symbol in `symbols` :param symbols: A single symbol pair, or a list of such pairs, which are listed on Binance :return: None """ # Get the minimum time to wait between requests to avoid being throttled/banned wait_time = 1.0 / self.exchange_info.max_request_freq(req_weight=5) limit = 1000 trades: List[Dict] = [] last_called = 0.0 for symbol in tqdm(symbols): tqdm.write(symbol, end="") # Print to console above the progress bar result = None params = {"symbol": symbol, "limit": limit} while result is None or len(result) == limit: # Wait a while if needed to avoid hitting API rate limits delta = time.perf_counter() - last_called if delta < wait_time: time.sleep(wait_time - delta) if result is not None: next_end_time = result[0]["time"] - 1 params.update({"endTime": next_end_time}) last_called = time.perf_counter() result = self.client.get_my_trades(**params) if not result: break trades.extend(result) tqdm.write(f" : {len(result)}", end="") tqdm.write("") if not trades: self.log.notice("No trades received for given symbols") return # Check if blacklist might need to be updated symbols_found = list(set([trade["symbol"] for trade in trades])) if symbols_found: settings.Blacklist.remove(symbols_found) # Write results to the store tax_trades = [ TaxTrade.from_historic_trades(result) for result in trades ] self.trade_store.update(tax_trades) self.log.notice(f"{len(trades)} trades retrieved and stored on disk") def get_all_trades(self, force_all=False): """Pull trade history for all symbols on Binance that are not blacklisted. If *force_all* is True, pull history regardless of blacklist """ blacklist = settings.Blacklist.get() if not force_all else None all_active = settings.read_symbols("active") if blacklist is not None: self.log.info(f"Skipping {blacklist} while getting all trades") all_active = [pair for pair in all_active if pair not in blacklist] self.get_trade_history_for(all_active)
import time from binance.client import Client # Import the Binance Client from binance.websockets import BinanceSocketManager # Import the Binance Socket Manager # Although fine for tutorial purposes, your API Keys should never be placed directly in the script like below. # You should use a config file (cfg or yaml) to store them and reference when needed. PUBLIC = '<YOUR-PUBLIC-KEY>' SECRET = '<YOUR-SECRET-KEY>' # Instantiate a Client client = Client(api_key=PUBLIC, api_secret=SECRET) # Instantiate a BinanceSocketManager, passing in the client that you instantiated bm = BinanceSocketManager(client) # This is our callback function. For now, it just prints messages as they come. def handle_message(msg): print("price ",msg['p'], " time ", msg['E']) #print(msg) # Start trade socket with 'ETHBTC' and use handle_message to.. handle the message. #market = 'ETHBTC' market = 'BTCUSDT' conn_key = bm.start_trade_socket(market, handle_message) # then start the socket manager print ("start stream") bm.start() # let some data flow.. time.sleep(5)
# global diminishing_returns # global current_balance while not balance: get_balances() time.sleep(1) while not prices: get_prices(balance) time.sleep(1) while not volatility: get_volatility(symbol) time.sleep(1) # while not binance_orders: get_orders() time.sleep(1) if balance and prices: bm = BinanceSocketManager( client) # start any sockets here, i.e a trade socket conn_key = bm.start_trade_socket( symbol, process_message) # then start the socket manager while not connected: if timer >= 60: timer = 60 bm.start() time.sleep(timer) timer += 3 timing_1s = time.time() timing_1m = time.time() while True: # print(time.time()) if time.time() - timing_1s > 1.0:
class BinanceStore(with_metaclass(MetaSingleton, object)): _GRANULARITIES = { (TimeFrame.Minutes, 1): '1m', (TimeFrame.Minutes, 3): '3m', (TimeFrame.Minutes, 5): '5m', (TimeFrame.Minutes, 15): '15m', (TimeFrame.Minutes, 30): '30m', (TimeFrame.Minutes, 60): '1h', (TimeFrame.Minutes, 120): '2h', (TimeFrame.Minutes, 240): '4h', (TimeFrame.Minutes, 360): '6h', (TimeFrame.Minutes, 480): '8h', (TimeFrame.Minutes, 720): '12h', (TimeFrame.Days, 1): '1d', (TimeFrame.Days, 3): '3d', (TimeFrame.Weeks, 1): '1w', (TimeFrame.Months, 1): '1M', } BrokerCls = None # Broker class will autoregister DataCls = None # Data class will auto register @classmethod def getdata(cls, *args, **kwargs): """Returns ``DataCls`` with args, kwargs""" return cls.DataCls(*args, **kwargs) @classmethod def getbroker(cls, *args, **kwargs): """Returns broker with *args, **kwargs from registered ``BrokerCls``""" return cls.BrokerCls(*args, **kwargs) def __init__(self, api_key, api_secret, coin_refer, coin_target, retries=5): self.binance = Client(api_key, api_secret) self.binance_socket = BinanceSocketManager(self.binance) self.coin_refer = coin_refer self.coin_target = coin_target self.retries = retries self._precision = None self._step_size = None self._cash = 0 self._value = 0 self.get_balance() def retry(method): @wraps(method) def retry_method(self, *args, **kwargs): for i in range(self.retries): time.sleep(500 / 1000) # Rate limit try: return method(self, *args, **kwargs) except BinanceAPIException: if i == self.retries - 1: raise return retry_method @retry def cancel_order(self, order_id): try: self.binance.cancel_order(symbol=self.symbol, orderId=order_id) except BinanceAPIException as api_err: if api_err.code == -2011: # Order filled return else: raise api_err except Exception as err: raise err @retry def create_order(self, side, type, size, price): return self.binance.create_order(symbol=self.symbol, side=side, type=type, timeInForce=TIME_IN_FORCE_GTC, quantity=self.format_quantity(size), price=self.strprecision(price)) @retry def close_open_orders(self): orders = self.binance.get_open_orders(symbol=self.symbol) for o in orders: self.cancel_order(o['orderId']) def format_quantity(self, size): precision = self.step_size.find('1') - 1 if precision > 0: return '{:0.0{}f}'.format(size, precision) return floor(int(size)) @retry def get_asset_balance(self, asset): balance = self.binance.get_asset_balance(asset) return float(balance['free']), float(balance['locked']) def get_balance(self): free, locked = self.get_asset_balance(self.coin_target) self._cash = free self._value = free + locked def get_interval(self, timeframe, compression): return self._GRANULARITIES.get((timeframe, compression)) def get_precision(self): symbol_info = self.get_symbol_info(self.symbol) self._precision = symbol_info['baseAssetPrecision'] def get_step_size(self): symbol_info = self.get_symbol_info(self.symbol) for f in symbol_info['filters']: if f['filterType'] == 'LOT_SIZE': self._step_size = f['stepSize'] @retry def get_symbol_info(self, symbol): return self.binance.get_symbol_info(symbol) @property def precision(self): if not self._precision: self.get_precision() return self._precision def start_socket(self): if self.binance_socket.is_alive(): return self.binance_socket.daemon = True self.binance_socket.start() @property def step_size(self): if not self._step_size: self.get_step_size() return self._step_size def stop_socket(self): self.binance_socket.close() reactor.stop() self.binance_socket.join() def strprecision(self, value): return '{:.{}f}'.format(value, self.precision) @property def symbol(self): return '{}{}'.format(self.coin_refer, self.coin_target)
class DataCatcher: # Функция для обработки потока ордерной книги def orderbook_callback(self, query): pair = query['stream'].split('@')[0] # Записываем все, что можем вытащить из ордербука, в хранилище for side in ('asks', 'bids'): for level, (price, quantity) in enumerate(query['data'][side]): self.storage[pair + '_' + side + '_orderbook_price_level_' + str(level)] = price self.storage[pair + '_' + side + '_orderbook_quantity_level_' + str(level)] = quantity # Функция для обработки свечей def kline_callback(self, query): pair = query['stream'].split('@')[0] # Если свеча еще не завершена (данные неполные), ничего не делаем if not query['data']['k']['x']: return name_dict = { 'open_price': 'o', 'close_price': 'c', 'high_price': 'h', 'low_price': 'l', 'base_volume': 'v', 'trade_number': 'n', 'quote_volume': 'q', 'taker_base_volume': 'V', 'taker_quote_volume': 'Q', 'update_time': 'T' } for here in name_dict: self.storage[pair + '_kline_' + here] = query['data']['k'][name_dict[here]] # Функция, которая вызывается, когда мы ловим сообщение def general_callback(self, query): stream_type = query['stream'].split('@')[1] # Ниже мы определяем, какой поток какая функция обрабатывает и запускаем # обработку в отдельном потоке, чтобы не тормозить stream_callbacks = { 'kline_1m': self.kline_callback, 'depth20': self.orderbook_callback } action = threading.Thread(target=stream_callbacks[stream_type], args=(query, )) action.start() def init_streams(self): # Считываем из настроек, какие мы рассматриваем крипты и потоки и инициализируем потоки with open('settings/pairs.txt') as file: self.pairs = file.readlines() self.pairs = [el[:-1] for el in self.pairs] with open('settings/streams.txt') as file: streams = file.readlines() streams = [el[:-1] for el in streams] for pair in self.pairs: for stream in streams: self.streams.append(pair + stream) # saver - функция, вызываемая каждую секунду и сохраняющая данные # timeout - через сколько вырубать обработку, period - длина одного тика def __init__(self, saver=None, storage=None, timeout=23 * 60 * 60, period=1., process_inside=True): self.timeout = timeout self.period = period self.manager = multiprocessing.Manager() # storage - куда мы сохраняем данные if storage is None: self.storage = self.manager.dict() else: self.storage = storage self.pairs = [] self.streams = [] self.init_streams() self.start_time = time.time() self.client = init_client() # Сокет, который все слушает (запускаем в отдельном процессе) self.main_socket = BinanceSocketManager(self.client) self.connection_key = self.main_socket.start_multiplex_socket( self.streams, self.general_callback) self.process_inside = process_inside if self.process_inside: self.socket_process = multiprocessing.Process( target=self.main_socket.run) self.data_saver = saver self.timer = RepeatTimer(self.period, self.give_data) logging.info('DataCatcher initialization successful') # Функция завершения работы def finish(self): logging.info('finishing listening') self.timer.cancel() self.main_socket.stop_socket(self.connection_key) self.main_socket.close() self.socket_process.terminate() # Функция передачи данных saver-у def give_data(self): # Смотри комментарии к kline_callback for pair in self.pairs: self.storage[pair + '_kline_time_since_update'] = time.time() * 1000 - \ self.storage[pair + '_kline_update_time'] self.storage['time'] = time.time() self.data_saver.push_data(self.storage) def start(self): logging.info('started listening') if self.process_inside: self.socket_process.start() # Ждем 2 минуты, чтобы все успело прийти logging.info('waiting for 2 minutes') time.sleep(120.) logging.info('started transferring data') timeout_timer = threading.Timer(self.timeout, self.finish) timeout_timer.start() if self.data_saver is not None: self.timer.start() self.socket_process.join()
# current price of CRYPTO pulled through the websocket CURRENT_PRICE = {} def ticker_socket(msg): '''Open a stream for financial information for CRYPTO''' if msg['e'] != 'error': global CURRENT_PRICE CURRENT_PRICE['{0}'.format(msg['s'])] = msg['c'] else: print('error') # connect to the websocket client and start the socket bsm = BinanceSocketManager(client) for coin in keywords: conn_key = bsm.start_symbol_ticker_socket(coin+PAIRING, ticker_socket) bsm.start() '''For the amount of CRYPTO to trade in USDT''' lot_size = {} '''Find step size for each coin For example, BTC supports a volume accuracy of 0.000001, while XRP only 0.1 ''' for coin in keywords: try:
# 1499040000000, # Open time # "0.01634790", # Open # "0.80000000", # High # "0.01575800", # Low # "0.01577100", # Close # "148976.11427815", # Volume # 1499644799999, # Close time # "2434.19055334", # Quote asset volume # 308, # Number of trades # "1756.87402397", # Taker buy base asset volume # "28.46694368", # Taker buy quote asset volume # "17928899.62484339" # Can be ignored # ]] bm = BinanceSocketManager(client) actual_prices = [] loop_event = [False] def socket_connect(): loop_event.clear() loop_event.append(True) # start any sockets here, i.e a trade socket global conn_key conn_key = bm.start_trade_socket('BNBBTC', process_message) # then start the socket manager bm.start() def socket_stop(): loop_event.clear()
class Bntream(): def __init__(self) -> None: self.chat_ids = [] self.client = Client(BN_API_KEY, BN_API_SECRET) self.bm = BinanceSocketManager(self.client) self.volumes = [] self.stored = 0 self.last_average = 0 self.volume_count = 0 self.sell_updates = 0 self.buy_updates = 0 self.conn_key = "" self.conn_mt_key = "" self.green_count = {} self.red_count = {} self.velocity = {} self.velocity_previous = {} self.miniticker = {} def process_message(self, msg): try: stream, data = msg['stream'], msg['data'] taker_buy_vol = float(data["k"]["Q"]) is_end = data["k"]["x"] symbol = stream.lower().replace("usdt@kline_1m", "") if is_end == True: open_price = float(data["k"]["o"]) close_price = float(data["k"]["c"]) if stream in self.velocity: self.velocity_previous[stream] = self.velocity[stream] self.velocity[stream] = (close_price - open_price) / 1 # 1min if close_price > open_price: if stream in self.green_count: self.green_count[stream] = self.green_count[stream] + 1 else: self.green_count[stream] = 1 self.red_count[stream] = 0 logging.error("PUMP UP!") else: if stream in self.red_count: self.red_count[stream] = self.red_count[stream] + 1 else: self.red_count[stream] = 1 self.green_count[stream] = 0 logging.error("DUMP Down!") data_db = r.get(COIN_DATA_KEY.format("AUDIO")) if data_db is not None: js = json.loads(data_db.decode("utf-8")) if "Q" in js: if js["Q"] is None: js = {"Q": [taker_buy_vol]} else: if len(js["Q"]) > 1: last_VOL = float(js["Q"][-1]) if last_VOL > 0: diff = 100 * (taker_buy_vol - last_VOL) / last_VOL else: diff = 0 if abs(diff) > 50000: bot_key = TELEGRAM_BOT chat_id = self.chat_ids[0] text = stream.replace( "usdt@kline_1m", "").upper( ) + " VOLUME RAPID CHANGE " + str( round(float(diff), 1)) + "%" send_message_url = f'https://api.telegram.org/bot{bot_key}/sendMessage?chat_id={chat_id}&text={text}' resp = requests.post(send_message_url) if len(js["Q"]) > 50: js["Q"] = js["Q"][:25] js["Q"].append(taker_buy_vol) else: js = {"Q": [taker_buy_vol]} else: js = {"Q": [taker_buy_vol]} r.set(COIN_DATA_KEY.format("AUDIO"), json.dumps(js)) self.stored = self.stored + 1 elif stream in self.green_count and self.green_count[ stream] > 1 and self.velocity[ stream] > self.velocity_previous[stream]: if symbol in self.miniticker: high_to_low_diff = float( self.miniticker[symbol]["h"]) - float( self.miniticker[symbol]["l"]) high_to_price_diff = float( self.miniticker[symbol]["h"]) - float(data["k"]["c"]) low_to_price_diff = float(data["k"]["c"]) - float( self.miniticker[symbol]["l"]) bot_key = TELEGRAM_BOT chat_id = self.chat_ids[0] ratio = self.velocity[stream] / self.velocity_previous[ stream] text = f"""{symbol} {self.green_count[stream]} GREEN 24hr High - 24hr Low: {round(high_to_low_diff, 4)} 24hr High - Price: {round(high_to_price_diff, 4)} Price - 24hr Low: {round(low_to_price_diff, 4)} Velocity: {round(ratio,1)} Buy Vol: {round(float(taker_buy_vol),1)} """ send_message_url = f'https://api.telegram.org/bot{bot_key}/sendMessage?chat_id={chat_id}&text={text}' resp = requests.post(send_message_url) self.green_count[stream] = 0 elif stream in self.red_count and self.red_count[ stream] > 1 and self.velocity[ stream] < self.velocity_previous[stream]: high_to_low_diff = float(self.miniticker[symbol]["h"]) - float( self.miniticker[symbol]["l"]) high_to_price_diff = float( self.miniticker[symbol]["h"]) - float(data["k"]["c"]) low_to_price_diff = float(data["k"]["c"]) - float( self.miniticker[symbol]["l"]) bot_key = TELEGRAM_BOT chat_id = self.chat_ids[0] ratio = self.velocity[stream] / self.velocity_previous[stream] text = f"""{symbol} {self.red_count[stream]} RED 24hr High - 24hr Low: {round(high_to_low_diff, 4)} 24hr High - Price: {round(high_to_price_diff, 4)} Price - 24hr Low: {round(low_to_price_diff, 4)} Velocity: {round(ratio,1)} Buy Vol: {round(float(taker_buy_vol),1)} """ send_message_url = f'https://api.telegram.org/bot{bot_key}/sendMessage?chat_id={chat_id}&text={text}' resp = requests.post(send_message_url) self.red_count[stream] = 0 except Exception as e: logging.error("BN Stream process error:" + str(e)) # do something def process_miniticker(self, msg): try: stream, data = msg['stream'], msg['data'] # { # "e": "24hrMiniTicker", // Event type # "E": 123456789, // Event time # "s": "BNBBTC", // Symbol # "c": "0.0025", // Close price # "o": "0.0010", // Open price # "h": "0.0025", // High price # "l": "0.0010", // Low price # "v": "10000", // Total traded base asset volume # "q": "18" // Total traded quote asset volume # } symbol = data["s"].lower().replace("usdt", "") self.miniticker[symbol] = data except Exception as e: logging.error("BN MT Stream process error:" + str(e)) def add_chat_id(self, chat_id): if chat_id not in self.chat_ids: self.chat_ids.append(chat_id) def remove_chat_id(self, chat_id): if chat_id in self.chat_ids: self.chat_ids.remove(chat_id) def start(self): self.conn_key = self.bm.start_multiplex_socket([ 'audiousdt@kline_1m', 'bnbusdt@kline_1m', 'grtusdt@kline_1m', 'btcusdt@kline_1m' ], self.process_message) self.conn_mt_key = self.bm.start_multiplex_socket([ 'audiousdt@miniTicker', 'bnbusdt@miniTicker', 'grtusdt@miniTicker', 'btcusdt@miniTicker' ], self.process_miniticker) # self.conn_key = self.bm.start_kline_socket('AUDIOUSDT', self.process_message, interval=KLINE_INTERVAL_1MINUTE) # self.conn_key = self.bm.start_aggtrade_socket('BNBBTC', self.process_message) self.bm.start() def stop(self): self.bm.stop_socket(self.conn_key) self.bm.stop_socket(self.conn_mt_key)
elif statusCode == "EXPIRED": return "Просрочен" elif statusCode == "REJECTED": return "Отклонен" elif statusCode == "FILLED": return "Исполнен" elif statusCode == "PARTIALLY_FILLED": return "Частично исполнен" else: return "Статус неизвестен(?)" messageSender = MessageSender(MessageType.TELEGRAM) messageSender.setTelegramRecipient(TelegramRecipient.ARBITRAGE_GROUP) #messageSender.setTelegramRecipient(TelegramRecipient.KOROVAEV_USER) clientArbitrageExmo = BinanceClient( "cpVoAC6GOvchaOtNKEBevnKypS2ruQoz5VMoCZHmF2GqoiVkaQiHGO8eFObwXkPn", "xaLFuFrLUL89pnXRTwKcLggT7HgLD3rcKSzWGza6ZHE9twsvD5HsQqwrRGJHGWQO") clientArbitrageCexIO = BinanceClient( "3AXtPzcT9Hrbt0il8DGhlnY8oqSwVDc8XGOOaRYC9PL2mehTGyZz984NvYG561yn", "oyo7KC54D02uCZkfP7Sm7IdW0rHp3LSVhs7sboc8opkkkHTFc4ie0EXP5VN0EpTz") bmExmo = BinanceSocketManager(clientArbitrageExmo) key_user = bmExmo.start_user_socket(UserExmoEventCallback) # then start the socket manager bmExmo.start() bmCex = BinanceSocketManager(clientArbitrageCexIO) key_user2 = bmCex.start_user_socket(UserCEXEventCallback) # then start the socket manager bmCex.start() print("OrderChecker started!")
async def produce_account_events(): client = Client("", "") bm = BinanceSocketManager(client) kline_key = bm.start_multiplex_socket(["ethbtc@kline_1m"], process_kline)
# withdraw 100 ETH # check docs for assumptions around withdrawals from binance.exceptions import BinanceApiException, BinanceWithdrawException try: result = client.withdraw(asset='ETH', address='<eth_address>', amount=100) except BinanceApiException as e: print(e) except BinanceWithdrawException as e: print(e) else: print("Success") # fetch list of withdrawals withdraws = client.get_withdraw_history() # get a deposit address address = client.get_deposit_address('BTC') # start trade websocket def process_message(msg): print("message type:" + msg[e]) print(msg) # do something from binance.websockets import BinanceSocketManager bm = BinanceSocketManager(client) bm.start_trade_socket(symbol='BNBBTC') bm.start()
msg = 'listening %s' % next(spinner) sys.stdout.write(msg) sys.stdout.flush() sys.stdout.write('\b' * len(msg)) #time.sleep(1) #--------------------------------------------------------------------------- if __name__ == '__main__': db = set_db('localhost') cred = list(db.api_keys.find())[0] killer = GracefulKiller() print("Connecting to Binance websocket client...") client = Client(cred['key'], cred['secret']) bnc_wss = BinanceSocketManager(client) connect_klines(bnc_wss, pairs) print("{} connections created.".format(len(conn_keys))) bnc_wss.start() print('Connected.') print('Press Ctrl+C to quit') timer_1m = Timer(name='pairs', expire='every 1 clock min utc') while True: if timer_1m.remain(quiet=True) == 0: pairs = detect_pair_change() timer_1m.reset(quiet=True) if killer.kill_now:
from binance.client import Client from binance.websockets import BinanceSocketManager def process_message(msg): if msg['e'] == 'error': # close and restart the socket print('Socket error') else: # process message normally print('Message received') print(msg) if __name__ == '__main__': api_key = '' api_secret = '' client = Client(api_key, api_secret) bm = BinanceSocketManager(client) # start any sockets here, i.e a trade socket conn_key = bm.start_trade_socket('BTCUSDT', process_message) # then start the socket manager bm.start()
def _threading_listen(self, currency, po): bm = BinanceSocketManager(self.client) bm.start_trade_socket(currency, po.start_observing) bm.start()