]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git/blobdiff - store.py
Fix available balance when buying
[perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git] / store.py
index 32c41211050c83d97c554e84ae29d188c457f3e0..1a1ed762ec33245ffa46cb6f3bb4cb7e78a828d1 100644 (file)
--- a/store.py
+++ b/store.py
@@ -325,6 +325,49 @@ class BalanceStore:
         else:
             self.market.report.log_balances(tag=tag, checkpoint=checkpoint)
 
+    def available_balances_for_repartition(self,
+            compute_value="average", base_currency="BTC",
+            liquidity="medium", repartition=None):
+        if repartition is None:
+            repartition = Portfolio.repartition(liquidity=liquidity)
+        base_currency_balance = self.all.get(base_currency)
+
+        if base_currency_balance is None:
+            total_base_value = portfolio.Amount(base_currency, 0)
+        else:
+            total_base_value = base_currency_balance.exchange_free + \
+                    base_currency_balance.margin_available - \
+                    base_currency_balance.margin_in_position
+
+        amount_in_position = {}
+
+        # Compute balances already in the target position
+        for currency, (ptt, trade_type) in repartition.items():
+            amount_in_position[currency] = portfolio.Amount(base_currency, 0)
+            balance = self.all.get(currency)
+            if currency != base_currency and balance is not None:
+                if trade_type == "short":
+                    amount = balance.margin_borrowed
+                else:
+                    amount = balance.exchange_free + balance.exchange_used
+                amount_in_position[currency] = amount.in_currency(base_currency,
+                    self.market, compute_value=compute_value)
+                total_base_value += amount_in_position[currency]
+
+        # recursively delete more-than-filled positions from the wanted
+        # repartition
+        did_delete = True
+        while did_delete:
+            did_delete = False
+            sum_ratio = sum([v[0] for k, v in repartition.items()])
+            current_base_value = total_base_value
+            for currency, (ptt, trade_type) in repartition.copy().items():
+                if amount_in_position[currency] > current_base_value * ptt / sum_ratio:
+                    did_delete = True
+                    del(repartition[currency])
+                    total_base_value -= amount_in_position[currency]
+        return repartition, total_base_value, amount_in_position
+
     def dispatch_assets(self, amount, liquidity="medium", repartition=None):
         if repartition is None:
             repartition = Portfolio.repartition(liquidity=liquidity)
@@ -521,7 +564,7 @@ class Portfolio:
             cls.retrieve_cryptoportfolio()
         cls.get_cryptoportfolio()
         liquidities = cls.liquidities.get(liquidity)
-        return liquidities[cls.last_date.get()]
+        return liquidities[cls.last_date.get()].copy()
 
     @classmethod
     def get_cryptoportfolio(cls, refetch=False):