def get_exchanges_supporting_mutual_quotes(exchanges, quotes): """ Returns the exchanges that mutually support the given quote currencies. :param exchanges: a list of exchanges (as Exchange) :param quotes: a list of quote currencies (as str) :return: a list of exchanges """ check_isinstance_list(exchanges) check_isinstance_list(quotes) exchange_ids_holder = [] exchange_holder = {} for quote in quotes: exchanges_support = get_exchanges_supporting_quote(exchanges, quote) for exchange in exchanges_support: if not (exchange.id in exchange_ids_holder): exchange_holder[exchange.id] = exchange exchange_ids_holder.append( set(get_all_exchange_ids(exchanges_support))) quotes_intersection = set.intersection(*exchange_ids_holder) exchanges_out = [] for exchange_id in quotes_intersection: exchanges_out.append(exchange_holder[exchange_id]) return exchanges_out
def get_exchanges_supporting_mutual_pairs(exchanges, pairs): """ Returns the exchanges that mutually support the given pairs. :param exchanges: a list of exchanges (as Exchange) :param pairs: a list of pairs (as str) :return: a list of exchanges """ check_isinstance_list(exchanges) check_isinstance_list(pairs) exchange_ids_holder = [] exchange_holder = {} for pair in pairs: exchanges_support = get_exchanges_supporting_pair(exchanges, pair) for exchange in exchanges_support: if not (exchange.id in exchange_ids_holder): exchange_holder[exchange.id] = exchange exchange_ids_holder.append( set(get_all_exchange_ids(exchanges_support))) pairs_intersection = set.intersection(*exchange_ids_holder) exchanges_out = [] for exchange_id in pairs_intersection: exchanges_out.append(exchange_holder[exchange_id]) return exchanges_out
def get_exchanges_supporting_pair(exchanges, pair): """ Returns the exchanges that support a given pair. :param exchanges: the exchanges that should be reviewed :param pair: a pair (as str) :return: a list of exchanges """ check_isinstance_list(exchanges) check_isinstance_string(pair) exchanges_out = [] try: is_pair_available_at_exchange(exchanges[0], pair) except: exchanges = load_markets_threaded(exchanges) for exchange in exchanges: try: if is_pair_available_at_exchange(exchange, pair): exchanges_out.append(exchange) except: print("Exchange not loadable: {}".format(exchange)) return exchanges_out
def get_exchanges_supporting_quote(exchanges, quote): """ Returns the exchanges that support a given quote currency. :param exchanges: the exchanges that should be reviewed :param quote: a quote (as str) :return: a list of exchanges """ check_isinstance_list(exchanges) check_isinstance_string(quote) exchanges_out = [] try: is_quote_available_at_exchange(exchanges[0], quote) except: exchanges = load_markets_threaded(exchanges) for exchange in exchanges: try: if is_quote_available_at_exchange(exchange, quote): exchanges_out.append(exchange) except: print("Exchange not loadable: {}".format(exchange)) return exchanges_out
def get_exchanges_as_list(exchanges_ids): """Returns the specified exchanges as a list.""" check_isinstance_list(exchanges_ids) exchanges = [] for exchange in exchanges_ids: exchanges.append(getattr(ccxt, exchange)()) return exchanges
def get_exchanges_supporting_currency(exchanges, currency): """ Returns the exchanges that support a given currency. :param exchanges: the exchanges that should be reviewed :param currency: a currency (as str) :return: a list of exchanges """ check_isinstance_list(exchanges) check_isinstance_string(currency) exchanges_out = [] # TODO: This is not the best solution ... improve this. try: is_currency_available_at_exchange(exchanges[0], currency) except: exchanges = load_markets_threaded(exchanges) for exchange in exchanges: try: if is_currency_available_at_exchange(exchange, currency): exchanges_out.append(exchange) except: print("Exchange not loadable: {}".format(exchange)) return exchanges_out
def get_currency_withdraw_fee_exchanges_pairs(exchanges, currencies=None): """ Returns a nested dictionary (currency: exchange: fee) of all given exchanges and currencies (or all possible currencies). :param exchanges: a list of exchanges :param currencies: a list of currencies :return: nested dictionary (currency: exchange) """ check_isinstance_list(exchanges) pairs = {} if currencies is None: has_currencies = has_withdraw_fees_for_any_its_currencies for exchange in exchanges: if has_currencies(exchange): withdraw = exchange.fees['funding']['withdraw'] for currency, price in withdraw.items(): if price != 0: pairs.setdefault(currency, {})[exchange.id] = price else: has_currencies = has_withdraw_fees_for_any_given_currency for exchange in exchanges: if has_currencies(exchange, currencies): withdraw = exchange.fees['funding']['withdraw'] for currency, price in withdraw.items(): if price != 0: pairs.setdefault(currency, {})[exchange.id] = price return pairs
def get_exchange_deposit_currency_fees_pairs(exchanges, currencies=None): """ Returns a nested dictionary (exchange: currency: fee) of all given exchanges and currencies (or all possible currencies). :param exchanges: a list of exchanges :param currencies: a list of currencies :return: nested dictionary (exchange: currency) """ check_isinstance_list(exchanges) pairs = {} if currencies is None: has_currencies = has_deposit_fees_for_any_its_currencies else: has_currencies = has_deposit_fees_for_any_given_currency for exchange in exchanges: currencies_out = {} if has_currencies(exchange): deposit = exchange.fees['funding']['deposit'] for currency, price in deposit.items(): if price != 0: currencies_out[currency] = price pairs[exchange.id] = currencies_out return pairs
def get_exchanges_with_funding_fees(exchanges): # TODO: This is not correct. Just because there is an entry doesn't mean it has fees. Could be 0... """Returns a list of exchanges that have funding fees.""" check_isinstance_list(exchanges) exchanges_with_funding_fees = [] for exchange in exchanges: if has_funding_fees(exchange): exchanges_with_funding_fees.append(exchange) return exchanges_with_funding_fees
def get_all_supported_currencies(exchanges): # TODO: Docstring check_isinstance_list(exchanges) currencies = set() for exchange in exchanges: currencies.update(get_all_currencies_at_exchange(exchange)) return currencies
def get_maker_fee_from_exchanges(exchanges): check_isinstance_list(exchanges) fees = {} for exchange in exchanges: fee = get_maker_fee_from_exchange(exchange) fees[exchange.id] = fee return fees
def get_tier_based_taker_fees_from_exchanges(exchanges): check_isinstance_list(exchanges) fees_out = {} for exchange in exchanges: fee = get_tier_based_taker_fees_from_exchange(exchange) if fee: fees_out[exchange.id] = fee return fees_out
def get_exchanges_with_trading_fees(exchanges): check_isinstance_list(exchanges) maker = set(get_exchanges_with_maker_fee(exchanges)) taker = set(get_exchanges_with_taker_fee(exchanges)) if maker == taker: return maker else: diff = taker - maker maker.update(diff) return maker
def get_exchanges_by_id(ids): # TODO: make a check that the ids actually correspond to exchanges. """ Returns a list of exchange based on the id-strings. :param ids: list of exchange-ids (as str) :return: list of exchanges (as Exchange) """ check_isinstance_list(ids) ids_out = [] for id in ids: ids_out.append(get_exchange_by_id(id)) return ids_out
def get_maker_fee_from_exchanges_deep(exchanges): check_isinstance_list(exchanges) exchanges = get_exchanges_with_maker_fee(exchanges) ex_tier = get_exchanges_with_tier_based_fees(exchanges) ex_normal = get_exchanges_without_tier_based_fees(exchanges) fees_tier = get_tier_based_maker_fees_from_exchanges(ex_tier) fees_normal = get_maker_fee_from_exchanges(ex_normal) fees_out = {**fees_tier, **fees_normal} return fees_out
def are_quotes_available_at_exchange(exchange, quotes): """ Checks if the specified quotes are available at the given exchange. :param exchange: an exchange (as Exchange) :param quote: a list of quote currencies (as str) :return: Boolean """ check_isinstance_exchange(exchange) check_isinstance_list(quotes) mask = [] for quote in quotes: mask.append(is_quote_available_at_exchange(exchange, quote)) return mask
def exchanges_in_ccxt(exchange_list, extended_search=False, number_results=5): """ Tries to find the given exchanges in ccxt. If it has an exact match, this one will be returned, otherwise fuzzy search through all possibilities will be made. :param exchange_list: list of given exchange-names. :param extended_search: use fuzzy search. :param number_results: number of printed results of fuzzy search. """ check_isinstance_list(exchange_list) for exchange in exchange_list: exchange_in_ccxt(exchange, extended_search=extended_search, number_results=number_results)
def are_bases_available_at_exchange(exchange, bases): """ Checks if the specified bases are available at the given exchange. :param exchange: an exchange (as Exchange) :param base: a list of base currencies (as str) :return: Boolean """ check_isinstance_exchange(exchange) check_isinstance_list(bases) mask = [] for base in bases: mask.append(is_base_available_at_exchange(exchange, base)) return mask
def get_exchanges_without_maker_fee(exchanges, as_str=False): check_isinstance_list(exchanges) ex_out = [] for exchange in exchanges: if not has_maker_fee(exchange): ex_out.append(exchange) if as_str: ex_str_out = [] for exchange in ex_out: ex_str_out.append(exchange.id) return ex_str_out return ex_out
def get_exchanges_without_tier_based_fees(exchanges, as_str=False): check_isinstance_list(exchanges) ex_out = [] for exchange in exchanges: if not fee_is_tier_based(exchange): ex_out.append(exchange) if as_str: ex_str_out = [] for exchange in ex_out: ex_str_out.append(exchange.id) return ex_str_out return ex_out
def get_exchanges_with_percentage_fee(exchanges, as_str=False): check_isinstance_list(exchanges) ex_out = [] for exchange in exchanges: if has_percentage_fee(exchange): ex_out.append(exchange) if as_str: ex_str_out = [] for exchange in ex_out: ex_str_out.append(exchange.id) return ex_str_out return ex_out
def has_deposit_fees_for_any_given_currency(exchange, currencies): """ Checks if the given exchange supports the deposit of the specified currencies. :param exchange: an exchange (as Exchange) :param currencies: a list of currencies (as str) :return: True/False """ check_isinstance_exchange(exchange) check_isinstance_list(currencies) for currency in currencies: if has_deposit_fee_for_currency(exchange, currency): return True return False
def are_currencies_available_at_exchange(exchange, currencies): """ Checks if the specified currencies are available at the given exchange. :param exchange: an exchange (as Exchange) :param currencies: a list of currencies (as str) :return: a list of Boolean values """ check_isinstance_exchange(exchange) check_isinstance_list(currencies) mask = [] for currency in currencies: mask.append(is_currency_available_at_exchange(exchange, currency)) return mask
def get_exchanges_with_currency_withdraw_fee(exchanges, currency): """ Returns the exchanges that support the withdraw of the specified currency. :param exchanges: a list of exchanges (as Exchange) :param currency: a currency (as str) :return: a list of exchanges """ check_isinstance_list(exchanges) check_isinstance_string(currency) exchange_out = [] for exchange in exchanges: if has_withdraw_fee_for_currency(exchange, currency): exchange_out.append(exchange) return exchange_out
def get_currencies_with_deposit_fee_at_exchanges(exchanges): """ Returns all currencies that have a fee associated with them on any of the given exchanges. This list is not exclusive. :param exchanges: a list of exchanges :return: a list of currencies """ check_isinstance_list(exchanges) deposits = set() for exchange in exchanges: try: for currency, price in exchange.fees['funding']['deposit'].items(): if price != 0: deposits.update([currency]) except (KeyError, TypeError, AttributeError) as e: print(exchange.id, e) return deposits
def get_exchanges_with_currencies_withdraw_fees(exchanges, currencies): """ Returns a list of exchanges that support any of the given currencies. This is not an exclusive operation! :param exchanges: a list of exchanges (as Exchange) :param currencies: a list of currencies (as str) :return: a list of exchanges """ check_isinstance_list(exchanges) check_isinstance_list(currencies) exchange_out = [] for exchange in exchanges: for currency in currencies: if has_withdraw_fee_for_currency(exchange, currency): exchange_out.append(exchange) break return exchange_out
def load_markets_threaded(exchanges, nr_Threads=20, debug=False, pkl_path="markets.pkl"): """ To interact with an exchange, its markets need to be loaded first. Since the i/o times of various exchanges differ drastically (in worst case a request may take up to 30 seconds), the request are split into a number of threads to get the data in parallel (up to 10x speed increase). :param exchanges: a list of exchanges (as Exchange) :param debug: loads exchanges from disk for quicker development. :param pkl_path: the path to the pkl-file. :return: the exchanges """ # TODO: remove debug arg if debug: return load_exchanges_from_pickle(pkl_path) check_isinstance_list(exchanges) start = time.time() print("Starting threaded polling.") if nr_Threads > len(exchanges): nr_Threads = len(exchanges) pool = Pool(nr_Threads) exchanges = pool.map(__load_markets_sub, exchanges) end = time.time() print("{} Threads required {:2}s for {} exchanges.".format( nr_Threads, (end - start), len(exchanges))) # Remove NoneType-Exchanges (where no data could be pulled) exchanges_clean = [x for x in exchanges if x != None] print("{} exchanges were not able to provide data and where removed" .format((len(exchanges)-len(exchanges_clean)))) return exchanges_clean
def get_exchnages_supporting_bases(exchanges, bases): """ Returns the exchanges that support any of the given base currencies. :param exchanges: a list of exchanges (as Exchange) :param bases: a list of base currencies (as str) :return: a list of exchanges """ check_isinstance_list(bases) check_isinstance_list(exchanges) exchange_ids_holder = set() exchanges_holder = [] for base in bases: exchanges_support = get_exchanges_supporting_base(exchanges, base) for exchange in exchanges_support: if not (exchange.id in exchange_ids_holder): exchanges_holder.append(exchange) exchange_ids_holder.update(get_all_exchange_ids(exchanges_support)) return exchanges_holder
def get_exchanges_supporting_quotes(exchanges, quotes): """ Returns the exchanges that support any of the given quote currencies. :param exchanges: the exchanges that should be reviewed :param quotes: a list of quote currencies (as str) :return: a list of exchanges """ check_isinstance_list(quotes) check_isinstance_list(exchanges) exchange_ids_holder = set() exchanges_holder = [] for quote in quotes: exchanges_support = get_exchanges_supporting_quote(exchanges, quote) for exchange in exchanges_support: if not (exchange.id in exchange_ids_holder): exchanges_holder.append(exchange) exchange_ids_holder.update(get_all_exchange_ids(exchanges_support)) return exchanges_holder
def get_exchanges_supporting_pairs(exchanges, pairs): """ Returns the exchanges that support any of the given pairs. :param exchanges: the exchanges that should be reviewed :param pairs: a list of pairs (as str) :return: a list of exchanges """ check_isinstance_list(pairs) check_isinstance_list(exchanges) exchange_ids_holder = set() exchanges_holder = [] for pair in pairs: exchanges_support = get_exchanges_supporting_pair(exchanges, pair) for exchange in exchanges_support: if not (exchange.id in exchange_ids_holder): exchanges_holder.append(exchange) exchange_ids_holder.update(get_all_exchange_ids(exchanges_support)) return exchanges_holder