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"]),
34 "bidE": float(1/ticker
["askE"]),
35 "askE": float(1/ticker
["bidE"]),
37 def augment_ticker(ticker
):
40 fees
= fetch_fees(market
)
41 # FIXME: need to do better than just a multiplier
45 "bidA": ticker
["bid"] * bid_factor
,
46 "askA": ticker
["ask"] * ask_factor
,
48 "bidE": ticker
["bid"] * bid_factor
* (1 - fees
["maker"]),
49 "askE": ticker
["ask"] * ask_factor
* (1 - fees
["maker"]),
51 "bidF": ticker
["bid"] * bid_factor
* fees
["maker"],
52 "askF": ticker
["ask"] * ask_factor
* fees
["maker"],
55 if (c1
, c2
, market
.__class
__) in get_ticker
.cache
:
56 return get_ticker
.cache
[(c1
, c2
, market
.__class
__)]
57 if (c2
, c1
, market
.__class
__) in get_ticker
.cache
:
58 return invert(get_ticker
.cache
[(c2
, c1
, market
.__class
__)])
61 get_ticker
.cache
[(c1
, c2
, market
.__class
__)] = market
.fetch_ticker("{}/{}".format(c1
, c2
))
62 augment_ticker(get_ticker
.cache
[(c1
, c2
, market
.__class
__)])
63 except ccxt
.ExchangeError
:
65 get_ticker
.cache
[(c2
, c1
, market
.__class
__)] = market
.fetch_ticker("{}/{}".format(c2
, c1
))
66 augment_ticker(get_ticker
.cache
[(c2
, c1
, market
.__class
__)])
67 except ccxt
.ExchangeError
:
68 get_ticker
.cache
[(c1
, c2
, market
.__class
__)] = None
69 return get_ticker(c1
, c2
, market
)
71 def fetch_balances(market
):
73 fetched_balance
= market
.fetch_balance()
74 for key
, value
in fetched_balance
["total"].items():
76 balances
[key
] = int(value
* 10**max_digits
)
79 @static_var("cache", {})
80 def fetch_fees(market
):
81 if market
.__class
__ not in fetch_fees
.cache
:
82 fetch_fees
.cache
[market
.__class
__] = market
.fetch_fees()
83 return fetch_fees
.cache
[market
.__class
__]
85 def assets_value(assets
, market
, base_currency
="BTC"):
86 repartition_in_base_currency
= {}
87 for currency
, asset_value
in assets
.items():
88 if currency
== base_currency
:
89 repartition_in_base_currency
[currency
] = [asset_value
, 0]
91 asset_ticker
= get_ticker(currency
, base_currency
, market
)
92 if asset_ticker
is None:
93 raise Exception("This asset is not available in the chosen market")
94 repartition_in_base_currency
[currency
] = [
95 int(asset_ticker
["bidE"] * asset_value
),
96 int(asset_ticker
["bidF"] * asset_value
)
99 return repartition_in_base_currency
101 def dispatch_assets(base_currency_value
, repartition_pertenthousand
, market
, base_currency
="BTC"):
102 sum_pertenthousand
= sum([v
for k
, v
in repartition_pertenthousand
.items()])
103 repartition_in_base_currency
= {}
104 for currency
, ptt
in repartition_pertenthousand
.items():
105 repartition_in_base_currency
[currency
] = int(ptt
* base_currency_value
/ sum_pertenthousand
)
106 return repartition_in_base_currency
108 def compute_moves(current_assets
, repartition_pertenthousand
, market
, no_fees
=True, base_currency
="BTC"):
109 value_in_base
= assets_value(current_assets
, market
, base_currency
=base_currency
)
110 total_base_value
= sum([ v
[0] for k
, v
in value_in_base
.items()])
112 new_repartition
= dispatch_assets(total_base_value
, repartition_pertenthousand
, market
, base_currency
=base_currency
)
116 for key
in set(value_in_base
.keys()).union(set(new_repartition
.keys())):
117 mouvements
[key
] = value_in_base
.get(key
, [0, 0])[0] - new_repartition
.get(key
, 0)
119 for key
in set(value_in_base
.keys()).union(set(new_repartition
.keys())):
120 value
, fee
= value_in_base
.get(key
, [0, 0])
121 mouvements
[key
] = [value
- new_repartition
.get(key
, 0), fee
]
125 def compute_order(currency
, value
, market
, base_currency
="BTC"):
126 if currency
== base_currency
or value
== 0:
127 return [None, 0, False]
129 asset_ticker
= get_ticker(currency
, base_currency
, market
)
130 if asset_ticker
["inverted"]:
131 asset_ticker
= get_ticker(base_currency
, currency
, market
)
133 rate
= asset_ticker
["askA"]
134 return ["buy", rate
, True]
136 rate
= asset_ticker
["bidA"]
137 return ["sell", rate
, True]
140 rate
= asset_ticker
["bidA"]
141 return ["sell", rate
, False]
143 rate
= asset_ticker
["askA"]
144 return ["buy", rate
, False]
146 def make_order(currency
, value
, market
, base_currency
="BTC"):
147 action
, rate
, inverted
= compute_order(currency
, value
, market
, base_currency
=base_currency
)
148 amount
= formatted_price(abs(value
))
150 symbol
= "{}/{}".format(currency
, base_currency
)
152 symbol
= "{}/{}".format(base_currency
, currency
)
153 return market
.create_order(symbol
, 'limit', action
, amount
, price
=rate
)
155 def make_orders(current_assets
, repartition_pertenthousand
, market
, base_currency
="BTC"):
156 mouvements
= compute_moves(
158 repartition_pertenthousand
,
160 base_currency
=base_currency
)
163 for currency
, value
in sorted(mouvements
.items(), key
=lambda x
: x
[1]):
164 # FIXME: wait for sales to finish
165 results
.append(make_order(currency
, value
, market
, base_currency
=base_currency
))
168 def print_assets(assets
, indent
="", market
=None, base_currency
="BTC"):
169 if market
is not None:
170 format_string
= "{}{} {} ({} {})"
172 format_string
= "{}{} {}"
173 base_currency_price
= 0
175 for currency
, value
in assets
.items():
176 if market
is not None:
177 asset_ticker
= get_ticker(currency
, base_currency
, market
)
178 base_currency_price
= asset_ticker
["bidE"] * value
179 print(format_string
.format(
181 formatted_price(value
),
183 formatted_price(base_currency_price
),
186 def print_orders(current_assets
, repartition_pertenthousand
, market
, base_currency
="BTC"):
187 mouvements
= compute_moves(
189 repartition_pertenthousand
,
192 base_currency
=base_currency
)
194 for currency
, [value
, fee
] in mouvements
.items():
195 action
, rate
, inverted
= compute_order(
199 base_currency
=base_currency
)
200 if action
is not None:
201 currency_price
= int(value
/ rate
)
204 c1
, c2
= [base_currency
, currency
]
205 v1
, v2
= [value
, currency_price
]
207 c1
, c2
= [currency
, base_currency
]
208 v1
, v2
= [currency_price
, value
]
210 print("need to {} {} {}'s worth of {}, i.e. {} {} ( + {} {} fee)".format(
212 formatted_price(abs(v1
)), c1
,
214 formatted_price(abs(v2
)), c2
,
215 formatted_price(fee
), c2
))
217 current_assets
= fetch_balances(market
)
218 print_orders(current_assets
, repartition_pertenthousand
, market
)