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
Example #2
0
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