]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git/commitdiff
Store currency conversion rate and use it in trade computations
authorIsmaël Bouya <ismael.bouya@normalesup.org>
Sun, 21 Jan 2018 14:57:13 +0000 (15:57 +0100)
committerIsmaël Bouya <ismael.bouya@normalesup.org>
Sun, 21 Jan 2018 14:57:36 +0000 (15:57 +0100)
portfolio.py
test.py

index 5211dd80fb1ffe47d82f9254e43afe8d07961001..6d51989e2ae39d55f9f54f86291a6b4820e96782 100644 (file)
@@ -80,25 +80,34 @@ class Portfolio:
 class Amount:
     MAX_DIGITS = 18
 
-    def __init__(self, currency, value, linked_to=None, ticker=None):
+    def __init__(self, currency, value, linked_to=None, ticker=None, rate=None):
         self.currency = currency
         self.value = D(value)
         self.linked_to = linked_to
         self.ticker = ticker
+        self.rate = rate
 
         self.ticker_cache = {}
         self.ticker_cache_timestamp = time.time()
 
-    def in_currency(self, other_currency, market, action=None, compute_value="average"):
+    def in_currency(self, other_currency, market, rate=None, action=None, compute_value="average"):
         if other_currency == self.currency:
             return self
+        if rate is not None:
+            return Amount(
+                    other_currency,
+                    self.value * rate,
+                    linked_to=self,
+                    rate=rate)
         asset_ticker = Trade.get_ticker(self.currency, other_currency, market)
         if asset_ticker is not None:
+            rate = Trade.compute_value(asset_ticker, action, compute_value=compute_value)
             return Amount(
                     other_currency,
-                    self.value * Trade.compute_value(asset_ticker, action, compute_value=compute_value),
+                    self.value * rate,
                     linked_to=self,
-                    ticker=asset_ticker)
+                    ticker=asset_ticker,
+                    rate=rate)
         else:
             raise Exception("This asset is not available in the chosen market")
 
@@ -226,15 +235,8 @@ class Balance:
         return "Balance({} [{}/{}/{}])".format(self.currency, str(self.free), str(self.used), str(self.total))
 
 class Computation:
-    def average_inverse(ticker, action):
-        if ticker["inverted"]:
-            return 1/ticker["original"]["average"]
-        else:
-            return ticker["average"]
-
     computations = {
             "default": lambda x, y: x[y],
-            "average_inverse": average_inverse,
             "average": lambda x, y: x["average"],
             "bid": lambda x, y: x["bid"],
             "ask": lambda x, y: x["ask"],
@@ -341,9 +343,7 @@ class Trade:
 
         if not inverted:
             value_from = self.value_from.linked_to
-            # The ticker will most probably be inverted, but we want the average
-            # of the initial value
-            value_to = self.value_to.in_currency(self.currency, self.market, compute_value="average_inverse")
+            value_to = self.value_to.in_currency(self.currency, self.market, rate=1/self.value_from.rate)
             delta = abs(value_to - value_from)
             currency = self.base_currency
         else:
diff --git a/test.py b/test.py
index a9baadff58ee3dda9cefa9fbd2c2f45bb089ddef..edf6d015b08391c8bb722dd1badd9d0e2ffbe323 100644 (file)
--- a/test.py
+++ b/test.py
@@ -40,6 +40,9 @@ class AmountTest(unittest.TestCase):
             converted_amount = amount.in_currency("ETH", None, compute_value="ask")
             self.assertEqual(D("4"), converted_amount.value)
 
+        converted_amount = amount.in_currency("ETH", None, rate=D("0.02"))
+        self.assertEqual(D("0.2"), converted_amount.value)
+
     def test__abs(self):
         amount = portfolio.Amount("SC", -120)
         self.assertEqual(120, abs(amount).value)