aboutsummaryrefslogtreecommitdiff
path: root/store.py
blob: abbe5eef556eb88455aec50f12d07b041c0f5c67 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import portfolio

__all__ = ["BalanceStore", "TradeStore"]

class BalanceStore:
    all = {}

    @classmethod
    def currencies(cls):
        return cls.all.keys()

    @classmethod
    def in_currency(cls, other_currency, market, compute_value="average", type="total"):
        amounts = {}
        for currency, balance in cls.all.items():
            other_currency_amount = getattr(balance, type)\
                    .in_currency(other_currency, market, compute_value=compute_value)
            amounts[currency] = other_currency_amount
        return amounts

    @classmethod
    def fetch_balances(cls, market):
        all_balances = market.fetch_all_balances()
        for currency, balance in all_balances.items():
            if balance["exchange_total"] != 0 or balance["margin_total"] != 0 or \
                    currency in cls.all:
                cls.all[currency] = portfolio.Balance(currency, balance)

    @classmethod
    def dispatch_assets(cls, amount, liquidity="medium", repartition=None):
        if repartition is None:
            repartition = portfolio.Portfolio.repartition(liquidity=liquidity)
        sum_ratio = sum([v[0] for k, v in repartition.items()])
        amounts = {}
        for currency, (ptt, trade_type) in repartition.items():
            amounts[currency] = ptt * amount / sum_ratio
            if trade_type == "short":
                amounts[currency] = - amounts[currency]
            if currency not in BalanceStore.all:
                cls.all[currency] = portfolio.Balance(currency, {})
        return amounts

class TradeStore:
    all = []
    debug = False

    @classmethod
    def compute_trades(cls, values_in_base, new_repartition, only=None, market=None, debug=False):
        cls.debug = cls.debug or debug
        base_currency = sum(values_in_base.values()).currency
        for currency in BalanceStore.currencies():
            if currency == base_currency:
                continue
            value_from = values_in_base.get(currency, portfolio.Amount(base_currency, 0))
            value_to = new_repartition.get(currency, portfolio.Amount(base_currency, 0))

            if value_from.value * value_to.value < 0:
                cls.add_trade_if_matching(
                        value_from, portfolio.Amount(base_currency, 0),
                        currency, only=only, market=market)
                cls.add_trade_if_matching(
                        portfolio.Amount(base_currency, 0), value_to,
                        currency, only=only, market=market)
            else:
                cls.add_trade_if_matching(value_from, value_to,
                        currency, only=only, market=market)

    @classmethod
    def add_trade_if_matching(cls, value_from, value_to, currency,
            only=None, market=None):
        trade = portfolio.Trade(value_from, value_to, currency,
                market=market)
        if only is None or trade.action == only:
            cls.all.append(trade)
            return True
        return False

    @classmethod
    def prepare_orders(cls, only=None, compute_value="default"):
        for trade in cls.all:
            if only is None or trade.action == only:
                trade.prepare_order(compute_value=compute_value)

    @classmethod
    def print_all_with_order(cls):
        for trade in cls.all:
            trade.print_with_order()

    @classmethod
    def run_orders(cls):
        for order in cls.all_orders(state="pending"):
            order.run()

    @classmethod
    def all_orders(cls, state=None):
        all_orders = sum(map(lambda v: v.orders, cls.all), [])
        if state is None:
            return all_orders
        else:
            return list(filter(lambda o: o.status == state, all_orders))

    @classmethod
    def update_all_orders_status(cls):
        for order in cls.all_orders(state="open"):
            order.get_status()