aboutsummaryrefslogtreecommitdiff
path: root/helper.py
blob: d9c69cc45ee80e2a658db164cf03ea95c762189a (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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import time
from ccxt import ExchangeError
from store import *

def move_balances(market, debug=False):
    needed_in_margin = {} 
    moving_to_margin = {}

    for currency in BalanceStore.all:
        if BalanceStore.all[currency].margin_free != 0:
            needed_in_margin[currency] = 0
    for trade in TradeStore.all:
        if trade.value_to.currency not in needed_in_margin:
            needed_in_margin[trade.value_to.currency] = 0
        if trade.trade_type == "short":
            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
        moving_to_margin[currency] = (needed - current_balance)
        delta = moving_to_margin[currency].value
        if debug:
            ReportStore.log_debug_action("Moving {} from exchange to margin".format(moving_to_margin[currency]))
            continue
        if delta > 0:
            market.transfer_balance(currency, delta, "exchange", "margin")
        elif delta < 0:
            market.transfer_balance(currency, -delta, "margin", "exchange")
    ReportStore.log_move_balances(needed_in_margin, moving_to_margin, debug)

    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", liquidity="medium", compute_value="average", debug=False):
    ReportStore.log_stage("prepare_trades")
    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, liquidity=liquidity)
    # 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", liquidity="medium", compute_value="average", only=None, debug=False):
    ReportStore.log_stage("update_trades")
    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, liquidity=liquidity)
    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):
    ReportStore.log_stage("prepare_trades_to_sell_all")
    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(sleep=None):
    if sleep is None:
        sleep = 7 if TradeStore.debug else 30
        if TradeStore.debug:
            ReportStore.log_debug_action("Set follow_orders tick to {}s".format(sleep))
    tick = 0
    ReportStore.log_stage("follow_orders_begin")
    while len(TradeStore.all_orders(state="open")) > 0:
        time.sleep(sleep)
        tick += 1
        open_orders = TradeStore.all_orders(state="open")
        ReportStore.log_stage("follow_orders_tick_{}".format(tick))
        ReportStore.log_orders(open_orders, tick=tick)
        for order in open_orders:
            if order.get_status() != "open":
                ReportStore.log_order(order, tick, finished=True)
            else:
                order.trade.update_order(order, tick)
    ReportStore.log_stage("follow_orders_end")

def print_orders(market, base_currency="BTC"):
    ReportStore.log_stage("print_orders")
    BalanceStore.fetch_balances(market, tag="print_orders")
    prepare_trades(market, base_currency=base_currency, compute_value="average", debug=True)
    TradeStore.prepare_orders(compute_value="average")

def print_balances(market, base_currency="BTC"):
    BalanceStore.fetch_balances(market)
    if base_currency is not None:
        ReportStore.print_log("total:")
        ReportStore.print_log(sum(BalanceStore.in_currency(base_currency, market).values()))

def process_sell_needed__1_sell(market, liquidity="medium", base_currency="BTC", debug=False):
    ReportStore.log_stage("process_sell_needed__1_sell_begin")
    BalanceStore.fetch_balances(market, tag="process_sell_needed__1_sell_begin")
    prepare_trades(market, liquidity=liquidity, base_currency=base_currency, debug=debug)
    TradeStore.prepare_orders(compute_value="average", only="dispose")
    TradeStore.run_orders()
    follow_orders()
    BalanceStore.fetch_balances(market, tag="process_sell_needed__1_sell_end")
    ReportStore.log_stage("process_sell_needed__1_sell_end")

def process_sell_needed__2_buy(market, liquidity="medium", base_currency="BTC", debug=False):
    ReportStore.log_stage("process_sell_needed__2_buy_begin")
    BalanceStore.fetch_balances(market, tag="process_sell_needed__2_buy_begin")
    update_trades(market, base_currency=base_currency, liquidity=liquidity, debug=debug, only="acquire")
    TradeStore.prepare_orders(compute_value="average", only="acquire")
    move_balances(market, debug=debug)
    TradeStore.run_orders()
    follow_orders()
    BalanceStore.fetch_balances(market, tag="process_sell_needed__2_buy_end")
    ReportStore.log_stage("process_sell_needed__2_buy_end")

def process_sell_all__1_all_sell(market, base_currency="BTC", debug=False, liquidity="medium"):
    ReportStore.log_stage("process_sell_all__1_all_sell_begin")
    BalanceStore.fetch_balances(market, tag="process_sell_all__1_all_sell_begin")
    prepare_trades_to_sell_all(market, base_currency=base_currency, debug=debug)
    TradeStore.prepare_orders(compute_value="average")
    TradeStore.run_orders()
    follow_orders()
    BalanceStore.fetch_balances(market, tag="process_sell_all__1_all_sell_end")
    ReportStore.log_stage("process_sell_all__1_all_sell_end")

def process_sell_all__2_all_buy(market, base_currency="BTC", debug=False, liquidity="medium"):
    ReportStore.log_stage("process_sell_all__2_all_buy_begin")
    BalanceStore.fetch_balances(market, tag="process_sell_all__2_all_buy_begin")
    prepare_trades(market, liquidity=liquidity, base_currency=base_currency, debug=debug)
    TradeStore.prepare_orders(compute_value="average")
    move_balances(market, debug=debug)
    TradeStore.run_orders()
    follow_orders()
    BalanceStore.fetch_balances(market, tag="process_sell_all__2_all_buy_end")
    ReportStore.log_stage("process_sell_all__2_all_buy_end")