]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git/blobdiff - portfolio.py
Add missing tests
[perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git] / portfolio.py
index b629966b3e057cd53e50220be244e686d5418ad9..e98689ee4c2599fc63f77b6236057e9df0b2519e 100644 (file)
@@ -1,4 +1,5 @@
 import time
+from datetime import datetime
 from decimal import Decimal as D, ROUND_DOWN
 # Put your poloniex api key in market.py
 from json import JSONDecodeError
@@ -272,7 +273,7 @@ class Trade:
         if self.base_currency == self.currency:
             return None
 
-        if self.value_from < self.value_to:
+        if abs(self.value_from) < abs(self.value_to):
             return "acquire"
         else:
             return "dispose"
@@ -301,19 +302,16 @@ class Trade:
         if tick in [0, 1, 3, 4, 6]:
             print("{}, tick {}, waiting".format(order, tick))
         elif tick == 2:
-            self.prepare_order(compute_value=lambda x, y: (x[y] + x["average"]) / 2)
-            new_order = self.orders[-1]
+            new_order = self.prepare_order(compute_value=lambda x, y: (x[y] + x["average"]) / 2)
             print("{}, tick {}, cancelling and adjusting to {}".format(order, tick, new_order))
         elif tick ==5:
-            self.prepare_order(compute_value=lambda x, y: (x[y]*2 + x["average"]) / 3)
-            new_order = self.orders[-1]
+            new_order = self.prepare_order(compute_value=lambda x, y: (x[y]*2 + x["average"]) / 3)
             print("{}, tick {}, cancelling and adjusting to {}".format(order, tick, new_order))
         elif tick >= 7:
             if tick == 7:
                 print("{}, tick {}, fallbacking to market value".format(order, tick))
             if (tick - 7) % 3 == 0:
-                self.prepare_order(compute_value="default")
-                new_order = self.orders[-1]
+                new_order = self.prepare_order(compute_value="default")
                 print("{}, tick {}, market value, cancelling and adjusting to {}".format(order, tick, new_order))
 
         if new_order is not None:
@@ -322,7 +320,7 @@ class Trade:
 
     def prepare_order(self, compute_value="default"):
         if self.action is None:
-            return
+            return None
         ticker = h.get_ticker(self.currency, self.base_currency, self.market)
         inverted = ticker["inverted"]
         if inverted:
@@ -387,11 +385,13 @@ class Trade:
 
         if delta <= 0:
             print("Less to do than already filled: {}".format(delta))
-            return
+            return None
 
-        self.orders.append(Order(self.order_action(inverted),
+        order = Order(self.order_action(inverted),
             delta, rate, base_currency, self.trade_type,
-            self.market, self, close_if_possible=close_if_possible))
+            self.market, self, close_if_possible=close_if_possible)
+        self.orders.append(order)
+        return order
 
     def __repr__(self):
         return "Trade({} -> {} in {}, {})".format(
@@ -419,6 +419,8 @@ class Order:
         self.status = "pending"
         self.trade = trade
         self.close_if_possible = close_if_possible
+        self.id = None
+        self.fetch_cache_timestamp = None
 
     def __repr__(self):
         return "Order({} {} {} at {} {} [{}]{})".format(
@@ -438,6 +440,10 @@ class Order:
         else:
             return "margin"
 
+    @property
+    def open(self):
+        return self.status == "open"
+
     @property
     def pending(self):
         return self.status == "pending"
@@ -446,10 +452,6 @@ class Order:
     def finished(self):
         return self.status == "closed" or self.status == "canceled" or self.status == "error"
 
-    @property
-    def id(self):
-        return self.results[0]["id"]
-
     def run(self):
         symbol = "{}/{}".format(self.amount.currency, self.base_currency)
         amount = round(self.amount, self.market.order_precision(symbol)).value
@@ -457,26 +459,27 @@ class Order:
         if TradeStore.debug:
             print("market.create_order('{}', 'limit', '{}', {}, price={}, account={})".format(
                 symbol, self.action, amount, self.rate, self.account))
-            self.status = "open"
             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.status = "open"
             except Exception as e:
                 self.status = "error"
                 print("error when running market.create_order('{}', 'limit', '{}', {}, price={}, account={})".format(
                     symbol, self.action, amount, self.rate, self.account))
                 self.error_message = str("{}: {}".format(e.__class__.__name__, e))
                 print(self.error_message)
+                return
+        self.id = self.results[0]["id"]
+        self.status = "open"
 
     def get_status(self):
         if TradeStore.debug:
             return self.status
         # other states are "closed" and "canceled"
-        if self.status == "open":
+        if not self.finished:
             self.fetch()
-            if self.status != "open":
+            if self.finished:
                 self.mark_finished_order()
         return self.status
 
@@ -487,15 +490,15 @@ class Order:
             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)
 
-    fetch_cache_timestamp = None
     def fetch(self, force=False):
         if TradeStore.debug or (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()
 
-        self.results.append(self.market.fetch_order(self.id))
-        result = self.results[-1]
+        result = self.market.fetch_order(self.id)
+        self.results.append(result)
+
         self.status = result["status"]
         # Time at which the order started
         self.timestamp = result["datetime"]
@@ -503,11 +506,9 @@ class Order:
 
         # FIXME: consider open order with dust remaining as closed
 
-    @property
     def dust_amount_remaining(self):
-        return self.remaining_amount < 0.001
+        return self.remaining_amount() < Amount(self.amount.currency, D("0.001"))
 
-    @property
     def remaining_amount(self):
         if self.status == "open":
             self.fetch()
@@ -536,7 +537,7 @@ class Order:
         if TradeStore.debug:
             self.status = "canceled"
             return
-        self.market.cancel_order(self.result['id'])
+        self.market.cancel_order(self.id)
         self.fetch()
 
 class Mouvement:
@@ -552,6 +553,6 @@ class Mouvement:
         # rate * total = total_in_base
         self.total_in_base = Amount(base_currency, hash_["total"])
 
-if __name__ == '__main__':
+if __name__ == '__main__': # pragma: no cover
     from market import market
     h.print_orders(market)