import ccxt def static_var(varname, value): def decorate(func): setattr(func, varname, value) return func return decorate max_digits = 18 current_assets = { "ETH": int(2.00000000 * 10**max_digits), "BTC": int(1.23000000 * 10**max_digits), "ZEC": int(2.00000000 * 10**max_digits), "SC" : int(2.000000000 * 10**max_digits), } repartition_pertenthousand = { "BTC": 2857, "ZEC": 3701, "DOGE": 1805, "DGB": 1015, "SC": 623, } market = ccxt.poloniex() def formatted_price(value): return round(value / 10**max_digits, 8) @static_var("cache", {}) def get_ticker(c1, c2, market): def invert(ticker): return { "bid": float(1/ticker["ask"]), "ask": float(1/ticker["bid"]), } if (c1, c2, market.__class__) in get_ticker.cache: return get_ticker.cache[(c1, c2, market.__class__)] if (c2, c1, market.__class__) in get_ticker.cache: return invert(get_ticker.cache[(c2, c1, market.__class__)]) try: get_ticker.cache[(c1, c2, market.__class__)] = market.fetch_ticker("{}/{}".format(c1, c2)) except ccxt.ExchangeError: try: get_ticker.cache[(c2, c1, market.__class__)] = market.fetch_ticker("{}/{}".format(c2, c1)) except ccxt.ExchangeError: get_ticker.cache[(c1, c2, market.__class__)] = None return get_ticker(c1, c2, market) def assets_value(assets, market, base_currency="BTC"): repartition_in_base_currency = {} for currency, asset_value in assets.items(): if currency == base_currency: repartition_in_base_currency[currency] = asset_value else: asset_ticker = get_ticker(currency, base_currency, market) if asset_ticker is None: raise Exception("This asset is not available in the chosen market") repartition_in_base_currency[currency] = int(asset_ticker["bid"] * asset_value) return repartition_in_base_currency def dispatch_assets(base_currency_value, repartition_pertenthousand, market, base_currency="BTC"): sum_pertenthousand = sum([v for k, v in repartition_pertenthousand.items()]) repartition_in_base_currency = {} for currency, ptt in repartition_pertenthousand.items(): repartition_in_base_currency[currency] = int(ptt * base_currency_value / sum_pertenthousand) return repartition_in_base_currency def give_orders(current_assets, repartition_pertenthousand, market, base_currency="BTC"): value_in_base = assets_value(current_assets, market, base_currency=base_currency) total_base_value = sum([ v for k, v in value_in_base.items()]) new_repartition = dispatch_assets(total_base_value, repartition_pertenthousand, market, base_currency=base_currency) mouvements = {} for key in set(value_in_base.keys()).union(set(new_repartition.keys())): mouvements[key] = value_in_base.get(key, 0) - new_repartition.get(key, 0) print("assets before repartition:") for currency, value in current_assets.items(): print("holding {} {}".format( formatted_price(value), currency)) print("------------") for currency, value in mouvements.items(): if currency == base_currency: continue asset_ticker = get_ticker(currency, base_currency, market) if value > 0: action = "sell" currency_price = int(value / asset_ticker["bid"]) else: action = "buy" currency_price = int(value / asset_ticker["ask"]) if value != 0: print("need to {} {} {}'s worth of {}, i.e. {} {}".format( action, formatted_price(abs(value)), base_currency, currency, formatted_price(abs(currency_price)), currency)) print("------------\nassets after repartition:") for currency, value in new_repartition.items(): print("holding {} {}".format(formatted_price(value), currency)) give_orders(current_assets, repartition_pertenthousand, market)