aboutsummaryrefslogblamecommitdiff
path: root/store.py
blob: 841a0fc9e4f581ad468a2c3e8664507b003b4232 (plain) (tree)






















































                                                                                                  
 
                                                     





                                                                       
                 











                                                                  






























                                                                        
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, repartition=None):
        if repartition is None:
            repartition = portfolio.Portfolio.repartition()
        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()