aboutsummaryrefslogtreecommitdiff
path: root/helper.py
blob: 8a29f40419473ab0fc61cc0ff5c130781bf1a648 (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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import time
from ccxt import ExchangeError
from store import *

def move_balances(market, debug=False):
    needed_in_margin = {} 
    for trade in TradeStore.all:
        if trade.trade_type == "short":
            if trade.value_to.currency not in needed_in_margin:
                needed_in_margin[trade.value_to.currency] = 0
            needed_in_margin[trade.value_to.currency] += abs(trade.value_to)
    for currency, needed in needed_in_margin.items():
        current_balance = BalanceStore.all[currency].margin_free
        delta = (needed - current_balance).value
        # FIXME: don't remove too much if there are open margin position
        if delta > 0:
            if debug:
                print("market.transfer_balance({}, {}, 'exchange', 'margin')".format(currency, delta))
            else:
                market.transfer_balance(currency, delta, "exchange", "margin")
        elif delta < 0:
            if debug:
                print("market.transfer_balance({}, {}, 'margin', 'exchange')".format(currency, -delta))
            else:
                market.transfer_balance(currency, -delta, "margin", "exchange")

    BalanceStore.fetch_balances(market)

ticker_cache = {}
ticker_cache_timestamp = time.time()
def get_ticker(c1, c2, market, refresh=False):
    global ticker_cache, ticker_cache_timestamp
    def invert(ticker):
        return {
                "inverted": True,
                "average": (1/ticker["bid"] + 1/ticker["ask"]) / 2,
                "original": ticker,
                }
    def augment_ticker(ticker):
        ticker.update({
            "inverted": False,
            "average": (ticker["bid"] + ticker["ask"] ) / 2,
            })

    if time.time() - ticker_cache_timestamp > 5:
        ticker_cache = {}
        ticker_cache_timestamp = time.time()
    elif not refresh:
        if (c1, c2, market.__class__) in ticker_cache:
            return ticker_cache[(c1, c2, market.__class__)]
        if (c2, c1, market.__class__) in ticker_cache:
            return invert(ticker_cache[(c2, c1, market.__class__)])

    try:
        ticker_cache[(c1, c2, market.__class__)] = market.fetch_ticker("{}/{}".format(c1, c2))
        augment_ticker(ticker_cache[(c1, c2, market.__class__)])
    except ExchangeError:
        try:
            ticker_cache[(c2, c1, market.__class__)] = market.fetch_ticker("{}/{}".format(c2, c1))
            augment_ticker(ticker_cache[(c2, c1, market.__class__)])
        except ExchangeError:
            ticker_cache[(c1, c2, market.__class__)] = None
    return get_ticker(c1, c2, market)

fees_cache = {}
def fetch_fees(market):
    global fees_cache
    if market.__class__ not in fees_cache:
        fees_cache[market.__class__] = market.fetch_fees()
    return fees_cache[market.__class__]

def prepare_trades(market, base_currency="BTC", compute_value="average", debug=False):
    BalanceStore.fetch_balances(market)
    values_in_base = BalanceStore.in_currency(base_currency, market, compute_value=compute_value)
    total_base_value = sum(values_in_base.values())
    new_repartition = BalanceStore.dispatch_assets(total_base_value)
    # Recompute it in case we have new currencies
    values_in_base = BalanceStore.in_currency(base_currency, market, compute_value=compute_value)
    TradeStore.compute_trades(values_in_base, new_repartition, market=market, debug=debug)

def update_trades(market, base_currency="BTC", compute_value="average", only=None, debug=False):
    BalanceStore.fetch_balances(market)
    values_in_base = BalanceStore.in_currency(base_currency, market, compute_value=compute_value)
    total_base_value = sum(values_in_base.values())
    new_repartition = BalanceStore.dispatch_assets(total_base_value)
    TradeStore.compute_trades(values_in_base, new_repartition, only=only, market=market, debug=debug)

def prepare_trades_to_sell_all(market, base_currency="BTC", compute_value="average", debug=False):
    BalanceStore.fetch_balances(market)
    values_in_base = BalanceStore.in_currency(base_currency, market, compute_value=compute_value)
    total_base_value = sum(values_in_base.values())
    new_repartition = BalanceStore.dispatch_assets(total_base_value, repartition={ base_currency: (1, "long") })
    TradeStore.compute_trades(values_in_base, new_repartition, market=market, debug=debug)

def follow_orders(verbose=True, sleep=None):
    if sleep is None:
        sleep = 7 if TradeStore.debug else 30
    tick = 0
    while len(TradeStore.all_orders(state="open")) > 0:
        time.sleep(sleep)
        tick += 1
        for order in TradeStore.all_orders(state="open"):
            if order.get_status() != "open":
                if verbose:
                    print("finished {}".format(order))
            else:
                order.trade.update_order(order, tick)
    if verbose:
        print("All orders finished")

def print_orders(market, base_currency="BTC"):
    prepare_trades(market, base_currency=base_currency, compute_value="average")
    TradeStore.prepare_orders(compute_value="average")
    for currency, balance in BalanceStore.all.items():
        print(balance)
    TradeStore.print_all_with_order()

def make_orders(market, base_currency="BTC"):
    prepare_trades(market, base_currency=base_currency)
    for trade in TradeStore.all:
        print(trade)
        for order in trade.orders:
            print("\t", order, sep="")
            order.run()

def process_sell_all_sell(market, base_currency="BTC", debug=False):
    prepare_trades_to_sell_all(market, debug=debug)
    TradeStore.prepare_orders(compute_value="average")
    print("------------------")
    for currency, balance in BalanceStore.all.items():
        print(balance)
    print("------------------")
    TradeStore.print_all_with_order()
    print("------------------")
    TradeStore.run_orders()
    follow_orders()

def process_sell_all_buy(market, base_currency="BTC", debug=False):
    prepare_trades(market, debug=debug)
    TradeStore.prepare_orders()
    print("------------------")
    for currency, balance in BalanceStore.all.items():
        print(balance)
    print("------------------")
    TradeStore.print_all_with_order()
    print("------------------")
    move_balances(market, debug=debug)
    TradeStore.run_orders()
    follow_orders()