]> git.immae.eu Git - perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git/blob - store.py
Add Makefile and test coverage
[perso/Immae/Projets/Cryptomonnaies/Cryptoportfolio/Trader.git] / store.py
1 import portfolio
2
3 __all__ = ["BalanceStore", "TradeStore"]
4
5 class BalanceStore:
6 all = {}
7
8 @classmethod
9 def currencies(cls):
10 return cls.all.keys()
11
12 @classmethod
13 def in_currency(cls, other_currency, market, compute_value="average", type="total"):
14 amounts = {}
15 for currency, balance in cls.all.items():
16 other_currency_amount = getattr(balance, type)\
17 .in_currency(other_currency, market, compute_value=compute_value)
18 amounts[currency] = other_currency_amount
19 return amounts
20
21 @classmethod
22 def fetch_balances(cls, market):
23 all_balances = market.fetch_all_balances()
24 for currency, balance in all_balances.items():
25 if balance["exchange_total"] != 0 or balance["margin_total"] != 0 or \
26 currency in cls.all:
27 cls.all[currency] = portfolio.Balance(currency, balance)
28
29 @classmethod
30 def dispatch_assets(cls, amount, repartition=None):
31 if repartition is None:
32 repartition = portfolio.Portfolio.repartition()
33 sum_ratio = sum([v[0] for k, v in repartition.items()])
34 amounts = {}
35 for currency, (ptt, trade_type) in repartition.items():
36 amounts[currency] = ptt * amount / sum_ratio
37 if trade_type == "short":
38 amounts[currency] = - amounts[currency]
39 if currency not in BalanceStore.all:
40 cls.all[currency] = portfolio.Balance(currency, {})
41 return amounts
42
43 class TradeStore:
44 all = []
45 debug = False
46
47 @classmethod
48 def compute_trades(cls, values_in_base, new_repartition, only=None, market=None, debug=False):
49 cls.debug = cls.debug or debug
50 base_currency = sum(values_in_base.values()).currency
51 for currency in BalanceStore.currencies():
52 if currency == base_currency:
53 continue
54 value_from = values_in_base.get(currency, portfolio.Amount(base_currency, 0))
55 value_to = new_repartition.get(currency, portfolio.Amount(base_currency, 0))
56
57 if value_from.value * value_to.value < 0:
58 cls.add_trade_if_matching(
59 value_from, portfolio.Amount(base_currency, 0),
60 currency, only=only, market=market)
61 cls.add_trade_if_matching(
62 portfolio.Amount(base_currency, 0), value_to,
63 currency, only=only, market=market)
64 else:
65 cls.add_trade_if_matching(value_from, value_to,
66 currency, only=only, market=market)
67
68 @classmethod
69 def add_trade_if_matching(cls, value_from, value_to, currency,
70 only=None, market=None):
71 trade = portfolio.Trade(value_from, value_to, currency,
72 market=market)
73 if only is None or trade.action == only:
74 cls.all.append(trade)
75 return True
76 return False
77
78 @classmethod
79 def prepare_orders(cls, only=None, compute_value="default"):
80 for trade in cls.all:
81 if only is None or trade.action == only:
82 trade.prepare_order(compute_value=compute_value)
83
84 @classmethod
85 def print_all_with_order(cls):
86 for trade in cls.all:
87 trade.print_with_order()
88
89 @classmethod
90 def run_orders(cls):
91 for order in cls.all_orders(state="pending"):
92 order.run()
93
94 @classmethod
95 def all_orders(cls, state=None):
96 all_orders = sum(map(lambda v: v.orders, cls.all), [])
97 if state is None:
98 return all_orders
99 else:
100 return list(filter(lambda o: o.status == state, all_orders))
101
102 @classmethod
103 def update_all_orders_status(cls):
104 for order in cls.all_orders(state="open"):
105 order.get_status()
106
107