X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=script.py;fp=script.py;h=0000000000000000000000000000000000000000;hb=dd359bc0617a915909efb2ef37048192c0639836;hp=187ff73024de4ecf14cf96c0e1905b22bbb05e68;hpb=b2dab3acfb8cb23bdb54298c88aecfb7042fb8d5;p=perso%2FImmae%2FProjets%2FCryptomonnaies%2FCryptoportfolio%2FTrader.git diff --git a/script.py b/script.py deleted file mode 100644 index 187ff73..0000000 --- a/script.py +++ /dev/null @@ -1,218 +0,0 @@ -import ccxt -# Put your poloniex api key in market.py -from market import market - -def static_var(varname, value): - def decorate(func): - setattr(func, varname, value) - return func - return decorate - -max_digits = 18 - -repartition_pertenthousand = { - "BTC": 2857, - "ZEC": 3701, - "DOGE": 1805, - "DGB": 1015, - "SC": 623, - } - - -def formatted_price(value): - return round(value / 10**max_digits, 8) - -@static_var("cache", {}) -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"]), - "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, - # 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: - 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)) - 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 - -@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, 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["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"): - 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 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[0] for k, v in value_in_base.items()]) - - new_repartition = dispatch_assets(total_base_value, repartition_pertenthousand, market, base_currency=base_currency) - mouvements = {} - - 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] - - 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: - 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, - 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) -print_orders(current_assets, repartition_pertenthousand, market)