2 # Put your poloniex api key in market.py
3 from market
import market
5 def static_var(varname
, value
):
7 setattr(func
, varname
, value
)
13 repartition_pertenthousand
= {
22 def formatted_price(value
):
23 return round(value
/ 10**max_digits
, 8)
25 @static_var("cache", {})
26 def get_ticker(c1
, c2
, market
):
30 "bid": float(1/ticker
["ask"]),
31 "ask": float(1/ticker
["bid"]),
32 "bidA": float(1/ticker
["askA"]),
33 "askA": float(1/ticker
["bidA"]),
35 def augment_ticker(ticker
):
36 # FIXME: need to do better than just a multiplier
39 "bidA": ticker
["bid"] * 0.99,
40 "askA": ticker
["ask"] * 1.01,
43 if (c1
, c2
, market
.__class
__) in get_ticker
.cache
:
44 return get_ticker
.cache
[(c1
, c2
, market
.__class
__)]
45 if (c2
, c1
, market
.__class
__) in get_ticker
.cache
:
46 return invert(get_ticker
.cache
[(c2
, c1
, market
.__class
__)])
49 get_ticker
.cache
[(c1
, c2
, market
.__class
__)] = market
.fetch_ticker("{}/{}".format(c1
, c2
))
50 augment_ticker(get_ticker
.cache
[(c1
, c2
, market
.__class
__)])
51 except ccxt
.ExchangeError
:
53 get_ticker
.cache
[(c2
, c1
, market
.__class
__)] = market
.fetch_ticker("{}/{}".format(c2
, c1
))
54 augment_ticker(get_ticker
.cache
[(c2
, c1
, market
.__class
__)])
55 except ccxt
.ExchangeError
:
56 get_ticker
.cache
[(c1
, c2
, market
.__class
__)] = None
57 return get_ticker(c1
, c2
, market
)
59 def fetch_balances(market
):
61 fetched_balance
= market
.fetch_balance()
62 for key
, value
in fetched_balance
["total"].items():
64 balances
[key
] = int(value
* 10**max_digits
)
67 def assets_value(assets
, market
, base_currency
="BTC"):
68 repartition_in_base_currency
= {}
69 for currency
, asset_value
in assets
.items():
70 if currency
== base_currency
:
71 repartition_in_base_currency
[currency
] = asset_value
73 asset_ticker
= get_ticker(currency
, base_currency
, market
)
74 if asset_ticker
is None:
75 raise Exception("This asset is not available in the chosen market")
76 repartition_in_base_currency
[currency
] = int(asset_ticker
["bidA"] * asset_value
)
77 return repartition_in_base_currency
79 def dispatch_assets(base_currency_value
, repartition_pertenthousand
, market
, base_currency
="BTC"):
80 sum_pertenthousand
= sum([v
for k
, v
in repartition_pertenthousand
.items()])
81 repartition_in_base_currency
= {}
82 for currency
, ptt
in repartition_pertenthousand
.items():
83 repartition_in_base_currency
[currency
] = int(ptt
* base_currency_value
/ sum_pertenthousand
)
84 return repartition_in_base_currency
86 def compute_moves(current_assets
, repartition_pertenthousand
, market
, base_currency
="BTC"):
87 value_in_base
= assets_value(current_assets
, market
, base_currency
=base_currency
)
88 total_base_value
= sum([ v
for k
, v
in value_in_base
.items()])
90 new_repartition
= dispatch_assets(total_base_value
, repartition_pertenthousand
, market
, base_currency
=base_currency
)
93 for key
in set(value_in_base
.keys()).union(set(new_repartition
.keys())):
94 mouvements
[key
] = value_in_base
.get(key
, 0) - new_repartition
.get(key
, 0)
98 def compute_order(currency
, value
, market
, base_currency
="BTC"):
99 if currency
== base_currency
or value
== 0:
100 return [None, 0, False]
102 asset_ticker
= get_ticker(currency
, base_currency
, market
)
103 if asset_ticker
["inverted"]:
104 asset_ticker
= get_ticker(base_currency
, currency
, market
)
106 rate
= asset_ticker
["askA"]
107 return ["buy", rate
, True]
109 rate
= asset_ticker
["bidA"]
110 return ["sell", rate
, True]
113 rate
= asset_ticker
["bidA"]
114 return ["sell", rate
, False]
116 rate
= asset_ticker
["askA"]
117 return ["buy", rate
, False]
119 def make_order(currency
, value
, market
, base_currency
="BTC"):
120 action
, rate
, inverted
= compute_order(currency
, value
, market
, base_currency
=base_currency
)
121 amount
= formatted_price(abs(value
))
123 symbol
= "{}/{}".format(currency
, base_currency
)
125 symbol
= "{}/{}".format(base_currency
, currency
)
126 return market
.create_order(symbol
, 'limit', action
, amount
, price
=rate
)
128 def make_orders(current_assets
, repartition_pertenthousand
, market
, base_currency
="BTC"):
129 mouvements
= compute_moves(
131 repartition_pertenthousand
,
133 base_currency
=base_currency
)
136 for currency
, value
in sorted(mouvements
.items(), key
=lambda x
: x
[1]):
137 # FIXME: wait for sales to finish
138 results
.append(make_order(currency
, value
, market
, base_currency
=base_currency
))
141 def print_assets(assets
, indent
="", market
=None, base_currency
="BTC"):
142 if market
is not None:
143 format_string
= "{}{} {} ({} {})"
145 format_string
= "{}{} {}"
146 base_currency_price
= 0
148 for currency
, value
in assets
.items():
149 if market
is not None:
150 asset_ticker
= get_ticker(currency
, base_currency
, market
)
151 base_currency_price
= asset_ticker
["bidA"] * value
152 print(format_string
.format(
154 formatted_price(value
),
156 formatted_price(base_currency_price
),
159 def print_orders(current_assets
, repartition_pertenthousand
, market
, base_currency
="BTC"):
160 mouvements
= compute_moves(
162 repartition_pertenthousand
,
164 base_currency
=base_currency
)
166 for currency
, value
in mouvements
.items():
167 action
, rate
, inverted
= compute_order(
171 base_currency
=base_currency
)
172 if action
is not None:
173 currency_price
= int(value
/ rate
)
176 c1
, c2
= [base_currency
, currency
]
177 v1
, v2
= [value
, currency_price
]
179 c1
, c2
= [currency
, base_currency
]
180 v1
, v2
= [currency_price
, value
]
182 print("need to {} {} {}'s worth of {}, i.e. {} {}".format(
184 formatted_price(abs(v1
)), c1
,
186 formatted_price(abs(v2
)), c2
))
188 current_assets
= fetch_balances(market
)
189 print_orders(current_assets
, repartition_pertenthousand
, market
)