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
|
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 process_sell_needed__1_sell(market, base_currency="BTC", debug=False):
prepare_trades(market, base_currency=base_currency, debug=debug)
TradeStore.prepare_orders(compute_value="average", only="dispose")
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_needed__2_sell(market, base_currency="BTC", debug=False):
update_trades(market, base_currency=base_currency, debug=debug, only="acquire")
TradeStore.prepare_orders(compute_value="average", only="acquire")
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()
def process_sell_all__1_all_sell(market, base_currency="BTC", debug=False):
prepare_trades_to_sell_all(market, base_currency=base_currency, 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__2_all_buy(market, base_currency="BTC", debug=False):
prepare_trades(market, base_currency=base_currency, 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()
|