X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=script.py;h=187ff73024de4ecf14cf96c0e1905b22bbb05e68;hb=b2dab3acfb8cb23bdb54298c88aecfb7042fb8d5;hp=c702be63e8f64e5a39321448aa6294c290878cde;hpb=48bedc24dc34159fdf0ddaa5daaa055596c11d5c;p=perso%2FImmae%2FProjets%2FCryptomonnaies%2FCryptoportfolio%2FTrader.git diff --git a/script.py b/script.py index c702be6..187ff73 100644 --- a/script.py +++ b/script.py @@ -31,13 +31,25 @@ def get_ticker(c1, c2, market): "ask": float(1/ticker["bid"]), "bidA": float(1/ticker["askA"]), "askA": float(1/ticker["bidA"]), + "bidE": float(1/ticker["askE"]), + "askE": float(1/ticker["bidE"]), } def augment_ticker(ticker): + bid_factor = 1.01 + ask_factor = 0.99 + fees = fetch_fees(market) # FIXME: need to do better than just a multiplier ticker.update({ "inverted": False, - "bidA": ticker["bid"] * 0.99, - "askA": ticker["ask"] * 1.01, + # Adjusted + "bidA": ticker["bid"] * bid_factor, + "askA": ticker["ask"] * ask_factor, + # Expected in the end + "bidE": ticker["bid"] * bid_factor * (1 - fees["maker"]), + "askE": ticker["ask"] * ask_factor * (1 - fees["maker"]), + # fees + "bidF": ticker["bid"] * bid_factor * fees["maker"], + "askF": ticker["ask"] * ask_factor * fees["maker"], }) if (c1, c2, market.__class__) in get_ticker.cache: @@ -64,16 +76,26 @@ def fetch_balances(market): balances[key] = int(value * 10**max_digits) return balances +@static_var("cache", {}) +def fetch_fees(market): + if market.__class__ not in fetch_fees.cache: + fetch_fees.cache[market.__class__] = market.fetch_fees() + return fetch_fees.cache[market.__class__] + 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 + repartition_in_base_currency[currency] = [asset_value, 0] 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["bidA"] * asset_value) + repartition_in_base_currency[currency] = [ + int(asset_ticker["bidE"] * asset_value), + int(asset_ticker["bidF"] * asset_value) + ] + return repartition_in_base_currency def dispatch_assets(base_currency_value, repartition_pertenthousand, market, base_currency="BTC"): @@ -83,43 +105,114 @@ def dispatch_assets(base_currency_value, repartition_pertenthousand, market, bas 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"): +def compute_moves(current_assets, repartition_pertenthousand, market, no_fees=True, 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()]) + total_base_value = sum([ v[0] 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) + if no_fees: + for key in set(value_in_base.keys()).union(set(new_repartition.keys())): + mouvements[key] = value_in_base.get(key, [0, 0])[0] - new_repartition.get(key, 0) + else: + for key in set(value_in_base.keys()).union(set(new_repartition.keys())): + value, fee = value_in_base.get(key, [0, 0]) + mouvements[key] = [value - new_repartition.get(key, 0), fee] - 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) + return mouvements + +def compute_order(currency, value, market, base_currency="BTC"): + if currency == base_currency or value == 0: + return [None, 0, False] + + asset_ticker = get_ticker(currency, base_currency, market) + if asset_ticker["inverted"]: + asset_ticker = get_ticker(base_currency, currency, market) if value > 0: - action = "sell" - currency_price = int(value / asset_ticker["bid"]) + rate = asset_ticker["askA"] + return ["buy", rate, True] 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, + rate = asset_ticker["bidA"] + return ["sell", rate, True] + else: + if value > 0: + rate = asset_ticker["bidA"] + return ["sell", rate, False] + else: + rate = asset_ticker["askA"] + return ["buy", rate, False] + +def make_order(currency, value, market, base_currency="BTC"): + action, rate, inverted = compute_order(currency, value, market, base_currency=base_currency) + amount = formatted_price(abs(value)) + if not inverted: + symbol = "{}/{}".format(currency, base_currency) + else: + symbol = "{}/{}".format(base_currency, currency) + return market.create_order(symbol, 'limit', action, amount, price=rate) + +def make_orders(current_assets, repartition_pertenthousand, market, base_currency="BTC"): + mouvements = compute_moves( + current_assets, + repartition_pertenthousand, + market, + base_currency=base_currency) + + results = [] + for currency, value in sorted(mouvements.items(), key=lambda x: x[1]): + # FIXME: wait for sales to finish + results.append(make_order(currency, value, market, base_currency=base_currency)) + return results + +def print_assets(assets, indent="", market=None, base_currency="BTC"): + if market is not None: + format_string = "{}{} {} ({} {})" + else: + format_string = "{}{} {}" + base_currency_price = 0 + + for currency, value in assets.items(): + if market is not None: + asset_ticker = get_ticker(currency, base_currency, market) + base_currency_price = asset_ticker["bidE"] * value + print(format_string.format( + indent, + formatted_price(value), + currency, + formatted_price(base_currency_price), + base_currency)) + +def print_orders(current_assets, repartition_pertenthousand, market, base_currency="BTC"): + mouvements = compute_moves( + current_assets, + repartition_pertenthousand, + market, + no_fees=False, + base_currency=base_currency) + + for currency, [value, fee] in mouvements.items(): + action, rate, inverted = compute_order( 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)) + value, + market, + base_currency=base_currency) + if action is not None: + currency_price = int(value / rate) + + if not inverted: + c1, c2 = [base_currency, currency] + v1, v2 = [value, currency_price] + else: + c1, c2 = [currency, base_currency] + v1, v2 = [currency_price, value] + + print("need to {} {} {}'s worth of {}, i.e. {} {} ( + {} {} fee)".format( + action, + formatted_price(abs(v1)), c1, + c2, + formatted_price(abs(v2)), c2, + formatted_price(fee), c2)) current_assets = fetch_balances(market) -give_orders(current_assets, repartition_pertenthousand, market) +print_orders(current_assets, repartition_pertenthousand, market)