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
|
import ccxt
# Put your poloniex api key in market.py
from market import market
def static_var(varname, value):
def decorate(func):
setattr(func, varname, value)
return func
return decorate
max_digits = 18
repartition_pertenthousand = {
"BTC": 2857,
"ZEC": 3701,
"DOGE": 1805,
"DGB": 1015,
"SC": 623,
}
def formatted_price(value):
return round(value / 10**max_digits, 8)
@static_var("cache", {})
def get_ticker(c1, c2, market):
def invert(ticker):
return {
"inverted": True,
"bid": float(1/ticker["ask"]),
"ask": float(1/ticker["bid"]),
"bidA": float(1/ticker["askA"]),
"askA": float(1/ticker["bidA"]),
}
def augment_ticker(ticker):
# FIXME: need to do better than just a multiplier
ticker.update({
"inverted": False,
"bidA": ticker["bid"] * 0.99,
"askA": ticker["ask"] * 1.01,
})
if (c1, c2, market.__class__) in get_ticker.cache:
return get_ticker.cache[(c1, c2, market.__class__)]
if (c2, c1, market.__class__) in get_ticker.cache:
return invert(get_ticker.cache[(c2, c1, market.__class__)])
try:
get_ticker.cache[(c1, c2, market.__class__)] = market.fetch_ticker("{}/{}".format(c1, c2))
augment_ticker(get_ticker.cache[(c1, c2, market.__class__)])
except ccxt.ExchangeError:
try:
get_ticker.cache[(c2, c1, market.__class__)] = market.fetch_ticker("{}/{}".format(c2, c1))
augment_ticker(get_ticker.cache[(c2, c1, market.__class__)])
except ccxt.ExchangeError:
get_ticker.cache[(c1, c2, market.__class__)] = None
return get_ticker(c1, c2, market)
def fetch_balances(market):
balances = {}
fetched_balance = market.fetch_balance()
for key, value in fetched_balance["total"].items():
if value > 0:
balances[key] = int(value * 10**max_digits)
return balances
def assets_value(assets, market, base_currency="BTC"):
repartition_in_base_currency = {}
for currency, asset_value in assets.items():
if currency == base_currency:
repartition_in_base_currency[currency] = asset_value
else:
asset_ticker = get_ticker(currency, base_currency, market)
if asset_ticker is None:
raise Exception("This asset is not available in the chosen market")
repartition_in_base_currency[currency] = int(asset_ticker["bidA"] * asset_value)
return repartition_in_base_currency
def dispatch_assets(base_currency_value, repartition_pertenthousand, market, base_currency="BTC"):
sum_pertenthousand = sum([v for k, v in repartition_pertenthousand.items()])
repartition_in_base_currency = {}
for currency, ptt in repartition_pertenthousand.items():
repartition_in_base_currency[currency] = int(ptt * base_currency_value / sum_pertenthousand)
return repartition_in_base_currency
def give_orders(current_assets, repartition_pertenthousand, market, base_currency="BTC"):
value_in_base = assets_value(current_assets, market, base_currency=base_currency)
total_base_value = sum([ v for k, v in value_in_base.items()])
new_repartition = dispatch_assets(total_base_value, repartition_pertenthousand, market, base_currency=base_currency)
mouvements = {}
for key in set(value_in_base.keys()).union(set(new_repartition.keys())):
mouvements[key] = value_in_base.get(key, 0) - new_repartition.get(key, 0)
print("assets before repartition:")
for currency, value in current_assets.items():
print("holding {} {}".format(
formatted_price(value),
currency))
print("------------")
for currency, value in mouvements.items():
if currency == base_currency:
continue
asset_ticker = get_ticker(currency, base_currency, market)
if value > 0:
action = "sell"
currency_price = int(value / asset_ticker["bid"])
else:
action = "buy"
currency_price = int(value / asset_ticker["ask"])
if value != 0:
print("need to {} {} {}'s worth of {}, i.e. {} {}".format(
action,
formatted_price(abs(value)),
base_currency,
currency,
formatted_price(abs(currency_price)),
currency))
print("------------\nassets after repartition:")
for currency, value in new_repartition.items():
print("holding {} {}".format(formatted_price(value), currency))
current_assets = fetch_balances(market)
give_orders(current_assets, repartition_pertenthousand, market)
|