import requests class ExchangeInfo: def __get__( self, *args ): return self.value def __set__( self, obj, value=None ): if value is None: value = self.get_exchange_info() self.value = value def get_exchange_info( self ): url = 'https://api.binance.com/api/v3/exchangeInfo' r = requests.get( url ) print( f'Call to Binance' ) if not str( r.status_code ).startswith( '2' ): raise RuntimeError( 'Meh, handle for errors however you want' ) return r.json() class BinanceSymbols: exchange_info = ExchangeInfo() def __init__( self, exchange_info=None ): self.exchange_info = exchange_info def get_exchange_info( self ): return self.exchange_info def get_symbol_info( self, symbol:str='' ) -> dict: if not symbol: raise RuntimeError( 'Either a symbol, or previously collected symbol info must be passed to Symbols.get_filters()' ) for market in self.exchange_info[ 'symbols' ]: if market[ 'symbol'] == symbol: return market raise ValueError( f'Could not find info for provided symbol: { symbol }' ) def get_filters( self, symbol_info:dict=None, symbol:str=None ) -> list: if not symbol_info: symbol_info = self.get_symbol_info( symbol ) return symbol_info[ 'filters' ] def get_filter( self, filter_type, **kwargs ): try: filters = kwargs[ 'filters' ] except: filters = self.get_filters( **kwargs ) if filters: for _filter in filters: if _filter[ 'filterType' ] == filter_type: return _filter raise ValueError( f'Could not find filter of type: { filter_type } in { filters }' ) def get_min_notional( self, **kwargs ) -> dict: return self.get_filter( 'MIN_NOTIONAL', **kwargs ) def get_lot_size( self, **kwargs ) -> dict: return self.get_filter( 'LOT_SIZE', **kwargs ) def get_step_size( self, **kwargs ) -> str: return self.get_lot_size( **kwargs )[ 'stepSize' ] def get_min_notional_and_lot_size( self, **kwargs ) -> dict: symbol_info = self.get_symbol_info( **kwargs ) params = { 'filters': self.get_filters( symbol_info=symbol_info ) } return { 'min_notional':self.get_min_notional( **params ), 'lot_size':self.get_lot_size( **params ), 'step_size':self.get_step_size( **params ) } def main(): binance_symbols = BinanceSymbols() symbols = { 'BTCUSDT', 'VETUSDT', 'OMGBTC' } for symbol in symbols: info = binance_symbols.get_min_notional_and_lot_size( symbol=symbol ) print( f'\n{symbol=}, {info=}') if __name__ == '__main__': main()