Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
 def get_websocket_client(config, exchange_manager):
     ws_client = BinanceWebSocketClient(config, exchange_manager)
     ws_client.socket_manager = BinanceSocketManager(ws_client.client)
     return ws_client
Ejemplo n.º 4
0
            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)
Ejemplo n.º 5
0
        '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
Ejemplo n.º 6
0
 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.")
Ejemplo n.º 7
0
# 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")
Ejemplo n.º 8
0
    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()
Ejemplo n.º 9
0
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()
Ejemplo n.º 10
0
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()
Ejemplo n.º 11
0
 def stop_trading(self):
     bm = BinanceSocketManager(self.client)
     bm.stop_socket(self.conn_key)
     bm.close()
     reactor.stop()
Ejemplo n.º 12
0
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()
Ejemplo n.º 14
0
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()
Ejemplo n.º 15
0
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)
Ejemplo n.º 16
0
    :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': [
Ejemplo n.º 17
0
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)
Ejemplo n.º 18
0
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)
Ejemplo n.º 19
0
# 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:
Ejemplo n.º 20
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)
Ejemplo n.º 21
0
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:
Ejemplo n.º 23
0
#     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()
Ejemplo n.º 24
0
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)
Ejemplo n.º 25
0
    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!")
Ejemplo n.º 26
0
async def produce_account_events():
    client = Client("", "")
    bm = BinanceSocketManager(client)
    kline_key = bm.start_multiplex_socket(["ethbtc@kline_1m"], process_kline)
Ejemplo n.º 27
0
# 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()
Ejemplo n.º 28
0
    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:
Ejemplo n.º 29
0
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()
Ejemplo n.º 30
0
 def _threading_listen(self, currency, po):
     bm = BinanceSocketManager(self.client)
     bm.start_trade_socket(currency, po.start_observing)
     bm.start()