X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=script.py;h=c5ac4aa9ba42630ebe1cfeeaaad1e8210d239443;hb=89b80539deeca58cf8d063a8c75706050be485ab;hp=9bc2fe64ac695f7833ec7a9ecd3d0c7e538c506f;hpb=4c51aa716c2940b006430cad70739ddb965f5068;p=perso%2FImmae%2FProjets%2FCryptomonnaies%2FCryptoportfolio%2FTrader.git diff --git a/script.py b/script.py index 9bc2fe6..c5ac4aa 100644 --- a/script.py +++ b/script.py @@ -9,12 +9,6 @@ def static_var(varname, value): 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, @@ -32,9 +26,19 @@ def formatted_price(value): def get_ticker(c1, c2, market): def invert(ticker): return { + "inverted": True, "bid": float(1/ticker["ask"]), "ask": float(1/ticker["bid"]), + "bidA": float(1/ticker["askA"]), + "askA": float(1/ticker["bidA"]), } + def augment_ticker(ticker): + # FIXME: need to do better than just a multiplier + ticker.update({ + "inverted": False, + "bidA": ticker["bid"] * 0.99, + "askA": ticker["ask"] * 1.01, + }) if (c1, c2, market.__class__) in get_ticker.cache: return get_ticker.cache[(c1, c2, market.__class__)] @@ -43,13 +47,23 @@ def get_ticker(c1, c2, market): try: get_ticker.cache[(c1, c2, market.__class__)] = market.fetch_ticker("{}/{}".format(c1, c2)) + augment_ticker(get_ticker.cache[(c1, c2, market.__class__)]) except ccxt.ExchangeError: try: get_ticker.cache[(c2, c1, market.__class__)] = market.fetch_ticker("{}/{}".format(c2, c1)) + augment_ticker(get_ticker.cache[(c2, c1, market.__class__)]) except ccxt.ExchangeError: get_ticker.cache[(c1, c2, market.__class__)] = None return get_ticker(c1, c2, market) +def fetch_balances(market): + balances = {} + fetched_balance = market.fetch_balance() + for key, value in fetched_balance["total"].items(): + if value > 0: + balances[key] = int(value * 10**max_digits) + return balances + def assets_value(assets, market, base_currency="BTC"): repartition_in_base_currency = {} for currency, asset_value in assets.items(): @@ -59,7 +73,7 @@ def assets_value(assets, market, base_currency="BTC"): 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) + repartition_in_base_currency[currency] = int(asset_ticker["bidA"] * asset_value) return repartition_in_base_currency def dispatch_assets(base_currency_value, repartition_pertenthousand, market, base_currency="BTC"): @@ -69,7 +83,7 @@ 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, 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()]) @@ -79,32 +93,97 @@ def give_orders(current_assets, repartition_pertenthousand, market, base_currenc 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) + 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: + rate = asset_ticker["askA"] + return ["buy", rate, True] + else: + rate = asset_ticker["bidA"] + return ["sell", rate, True] + else: if value > 0: - action = "sell" - currency_price = int(value / asset_ticker["bid"]) + rate = asset_ticker["bidA"] + return ["sell", rate, False] else: - action = "buy" - currency_price = int(value / asset_ticker["ask"]) - if value != 0: + 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["bidA"] * 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, + base_currency=base_currency) + + for currency, value in mouvements.items(): + action, rate, inverted = compute_order( + 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. {} {}".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)) + formatted_price(abs(v1)), c1, + c2, + formatted_price(abs(v2)), c2)) -give_orders(current_assets, repartition_pertenthousand, market) +current_assets = fetch_balances(market) +print_orders(current_assets, repartition_pertenthousand, market)