X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=portfolio.py;h=43a39c4506c7caa6ba6fdbea4f48c5c6c10e4397;hb=f86ee14037646bedc3a3dee4a48f085308981757;hp=f9423b91d0736178fb4759016195e3d29ecd2499;hpb=eb9c92e155941b51042ba57e23f651454bd8e55a;p=perso%2FImmae%2FProjets%2FCryptomonnaies%2FCryptoportfolio%2FTrader.git diff --git a/portfolio.py b/portfolio.py index f9423b9..43a39c4 100644 --- a/portfolio.py +++ b/portfolio.py @@ -1,13 +1,10 @@ import time from datetime import datetime, timedelta from decimal import Decimal as D, ROUND_DOWN -# Put your poloniex api key in market.py from json import JSONDecodeError from simplejson.errors import JSONDecodeError as SimpleJSONDecodeError from ccxt import ExchangeError, ExchangeNotAvailable import requests -import helper as h -from store import * # FIXME: correctly handle web call timeouts @@ -18,26 +15,27 @@ class Portfolio: last_date = None @classmethod - def wait_for_recent(cls, delta=4): - cls.repartition(refetch=True) + def wait_for_recent(cls, market, delta=4): + cls.repartition(market, refetch=True) while cls.last_date is None or datetime.now() - cls.last_date > timedelta(delta): time.sleep(30) - cls.repartition(refetch=True) + market.report.print_log("Attempt to fetch up-to-date cryptoportfolio") + cls.repartition(market, refetch=True) @classmethod - def repartition(cls, liquidity="medium", refetch=False): - cls.parse_cryptoportfolio(refetch=refetch) + def repartition(cls, market, liquidity="medium", refetch=False): + cls.parse_cryptoportfolio(market, refetch=refetch) liquidities = cls.liquidities[liquidity] return liquidities[cls.last_date] @classmethod - def get_cryptoportfolio(cls): + def get_cryptoportfolio(cls, market): try: r = requests.get(cls.URL) - ReportStore.log_http_request(r.request.method, + market.report.log_http_request(r.request.method, r.request.url, r.request.body, r.request.headers, r) except Exception as e: - ReportStore.log_error("get_cryptoportfolio", exception=e) + market.report.log_error("get_cryptoportfolio", exception=e) return try: cls.data = r.json(parse_int=D, parse_float=D) @@ -45,9 +43,9 @@ class Portfolio: cls.data = None @classmethod - def parse_cryptoportfolio(cls, refetch=False): + def parse_cryptoportfolio(cls, market, refetch=False): if refetch or cls.data is None: - cls.get_cryptoportfolio() + cls.get_cryptoportfolio(market) def filter_weights(weight_hash): if weight_hash[1][0] == 0: @@ -118,7 +116,7 @@ class Amount: self.value * rate, linked_to=self, rate=rate) - asset_ticker = h.get_ticker(self.currency, other_currency, market) + asset_ticker = market.get_ticker(self.currency, other_currency) if asset_ticker is not None: rate = Computation.compute_value(asset_ticker, action, compute_value=compute_value) return Amount( @@ -283,7 +281,7 @@ class Balance: return "Balance({}".format(self.currency) + "".join([exchange, margin, total]) + ")" class Trade: - def __init__(self, value_from, value_to, currency, market=None): + def __init__(self, value_from, value_to, currency, market): # We have value_from of currency, and want to finish with value_to of # that currency. value_* may not be in currency's terms self.currency = currency @@ -353,18 +351,18 @@ class Trade: if tick == 7: update = "market_fallback" - ReportStore.log_order(order, tick, update=update, + self.market.report.log_order(order, tick, update=update, compute_value=compute_value, new_order=new_order) if new_order is not None: order.cancel() new_order.run() - ReportStore.log_order(order, tick, new_order=new_order) + self.market.report.log_order(order, tick, new_order=new_order) def prepare_order(self, compute_value="default"): if self.action is None: return None - ticker = h.get_ticker(self.currency, self.base_currency, self.market) + ticker = self.market.get_ticker(self.currency, self.base_currency) inverted = ticker["inverted"] if inverted: ticker = ticker["original"] @@ -430,7 +428,7 @@ class Trade: close_if_possible = (self.value_to == 0) if delta <= 0: - ReportStore.log_error("prepare_order", message="Less to do than already filled: {}".format(delta)) + self.market.report.log_error("prepare_order", message="Less to do than already filled: {}".format(delta)) return None order = Order(self.order_action(inverted), @@ -456,11 +454,11 @@ class Trade: self.action) def print_with_order(self, ind=""): - ReportStore.print_log("{}{}".format(ind, self)) + self.market.report.print_log("{}{}".format(ind, self)) for order in self.orders: - ReportStore.print_log("{}\t{}".format(ind, order)) + self.market.report.print_log("{}\t{}".format(ind, order)) for mouvement in order.mouvements: - ReportStore.print_log("{}\t\t{}".format(ind, mouvement)) + self.market.report.print_log("{}\t\t{}".format(ind, mouvement)) class Order: def __init__(self, action, amount, rate, base_currency, trade_type, market, @@ -525,15 +523,15 @@ class Order: def run(self): symbol = "{}/{}".format(self.amount.currency, self.base_currency) - amount = round(self.amount, self.market.order_precision(symbol)).value + amount = round(self.amount, self.market.ccxt.order_precision(symbol)).value - if TradeStore.debug: - ReportStore.log_debug_action("market.create_order('{}', 'limit', '{}', {}, price={}, account={})".format( + if self.market.debug: + self.market.report.log_debug_action("market.ccxt.create_order('{}', 'limit', '{}', {}, price={}, account={})".format( symbol, self.action, amount, self.rate, self.account)) self.results.append({"debug": True, "id": -1}) else: try: - self.results.append(self.market.create_order(symbol, 'limit', self.action, amount, price=self.rate, account=self.account)) + self.results.append(self.market.ccxt.create_order(symbol, 'limit', self.action, amount, price=self.rate, account=self.account)) except ExchangeNotAvailable: # Impossible to honor the order (dust amount) self.status = "closed" @@ -541,15 +539,15 @@ class Order: return except Exception as e: self.status = "error" - action = "market.create_order('{}', 'limit', '{}', {}, price={}, account={})".format(symbol, self.action, amount, self.rate, self.account) - ReportStore.log_error(action, exception=e) + action = "market.ccxt.create_order('{}', 'limit', '{}', {}, price={}, account={})".format(symbol, self.action, amount, self.rate, self.account) + self.market.report.log_error(action, exception=e) return self.id = self.results[0]["id"] self.status = "open" def get_status(self): - if TradeStore.debug: - ReportStore.log_debug_action("Getting {} status".format(self)) + if self.market.debug: + self.market.report.log_debug_action("Getting {} status".format(self)) return self.status # other states are "closed" and "canceled" if not self.finished: @@ -559,23 +557,23 @@ class Order: return self.status def mark_finished_order(self): - if TradeStore.debug: - ReportStore.log_debug_action("Mark {} as finished".format(self)) + if self.market.debug: + self.market.report.log_debug_action("Mark {} as finished".format(self)) return if self.status == "closed": if self.trade_type == "short" and self.action == "buy" and self.close_if_possible: - self.market.close_margin_position(self.amount.currency, self.base_currency) + self.market.ccxt.close_margin_position(self.amount.currency, self.base_currency) def fetch(self, force=False): - if TradeStore.debug: - ReportStore.log_debug_action("Fetching {}".format(self)) + if self.market.debug: + self.market.report.log_debug_action("Fetching {}".format(self)) return if (not force and self.fetch_cache_timestamp is not None and time.time() - self.fetch_cache_timestamp < 10): return self.fetch_cache_timestamp = time.time() - result = self.market.fetch_order(self.id) + result = self.market.ccxt.fetch_order(self.id) self.results.append(result) self.status = result["status"] @@ -606,7 +604,7 @@ class Order: def fetch_mouvements(self): try: - mouvements = self.market.privatePostReturnOrderTrades({"orderNumber": self.id}) + mouvements = self.market.ccxt.privatePostReturnOrderTrades({"orderNumber": self.id}) except ExchangeError: mouvements = [] self.mouvements = [] @@ -616,11 +614,11 @@ class Order: self.base_currency, mouvement_hash)) def cancel(self): - if TradeStore.debug: - ReportStore.log_debug_action("Mark {} as cancelled".format(self)) + if self.market.debug: + self.market.report.log_debug_action("Mark {} as cancelled".format(self)) self.status = "canceled" return - self.market.cancel_order(self.id) + self.market.ccxt.cancel_order(self.id) self.fetch() class Mouvement: @@ -663,6 +661,3 @@ class Mouvement: date, self.action, self.total, self.total_in_base, fee_rate) -if __name__ == '__main__': # pragma: no cover - from market import market - h.print_orders(market)