async def quote_symbols(api: BinanceAPI): """ Get all */quote and quote/BUSD symbols """ async with aiohttp.ClientSession() as client: exinfo, tickers = await asyncio.gather( api.exchange_info(client), api.ticker_24h(client, single=False)) dtickers = {val['symbol']: val for val in tickers} qsymbols = {} for symbol in exinfo['symbols']: if symbol['status'] != 'TRADING' or \ not symbol['isSpotTradingAllowed'] or \ not symbol['quoteOrderQtyMarketAllowed']: continue # inject ticker data inside a symbol symbol['ticker'] = dtickers[symbol['symbol']] if symbol['quoteAsset'] == api.env.qcoin: qsymbols[symbol['baseAsset']] = symbol elif symbol['quoteAsset'] == 'BUSD' and \ symbol['baseAsset'] == api.env.qcoin: qsymbols[api.env.qcoin] = symbol return qsymbols
async def setup(api: BinanceAPI) -> (dict, float): """ main parameter setup return exchange info and quote amount to sell """ env = api.env def set_stdin(prompt: str, default): if not env.override: return default ret = input(prompt) return ret if ret else default prompt = f'Enter quote coin symbol (coin to trade for) [default: {env.qcoin}]: ' env.qcoin = set_stdin(prompt, env.qcoin).upper() async with aiohttp.ClientSession() as client: info, lbals = await asyncio.gather(api.exchange_info(client), api.balances(client)) symbols, src_symbols, usd_symbol = api.quote_symbols(info) bals = filter_balances(lbals, [env.qcoin] + env.src_coins) if env.qcoin not in bals: raise CException('Quote coin is invalid') qbal, qloc = bals[env.qcoin] del bals[env.qcoin] print( f'Your free balance for {env.qcoin} is {ffmt(qbal)} (locked: {ffmt(qloc)})' ) def_qty = env.buy_perc / 100 * qbal if env.usd_value: # fixed USD quote balance feature usd_price = await quote_qty_from_usd(client, api, usd_symbol) qqty = env.usd_value / usd_price while qqty > qbal: diff = 1.02 * (qqty - qbal) qbal += await buy_from_source(client, api, src_symbols, bals, diff) else: prompt = f'Enter {env.qcoin} amount to sell ' + \ f'[default: {ffmt(def_qty)} ({env.buy_perc:.2f}%)]: ' qqty = float(set_stdin(prompt, def_qty)) if qqty <= 0: raise CException( f'Cannot sell non-positive amount of {env.qcoin}') if qqty > qbal: raise CException('Insufficient quote balance') prompt = f'Enter sell type (LIMIT|MARKET) [default: {env.sell_type.name}]: ' env.sell_type = SellType(set_stdin(prompt, env.sell_type)) prompt = f'Enter desired profit in % [default: {env.profit:.2f}]: ' env.profit = float(set_stdin(prompt, env.profit)) if env.profit <= 0: CColors.wprint( 'You have set a non-positive profit. Proceeding may net you a loss!' ) prompt = f'Enter stop level in % to manage risk [default: {env.stop:.2f}]: ' env.stop = float(set_stdin(prompt, env.stop)) if not -100 <= env.stop < env.profit: raise CException('Stop percentage must be lower than profits!') print('---- SELECTED OPTIONS ----') print(f'Selected quote coin: {env.qcoin}') print(f'Selected quote amount to sell: {ffmt(qqty)} {env.qcoin} ' + \ f'(available: {ffmt(qbal)} {env.qcoin})') print(f'Selected sell strategy: {env.sell_type.name}') print(f'Selected target profit: {env.profit:.2f}%') print(f'Selected stop percentage: {env.stop:.2f}%') print('--------------------------') return symbols, qqty