diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2018-01-14 03:34:42 +0100 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2018-01-14 03:38:05 +0100 |
commit | b2dab3acfb8cb23bdb54298c88aecfb7042fb8d5 (patch) | |
tree | ccb2f9aae20ac0b15eeccb59ec538ae0e090ff71 | |
parent | 89b80539deeca58cf8d063a8c75706050be485ab (diff) | |
download | Trader-b2dab3acfb8cb23bdb54298c88aecfb7042fb8d5.tar.gz Trader-b2dab3acfb8cb23bdb54298c88aecfb7042fb8d5.tar.zst Trader-b2dab3acfb8cb23bdb54298c88aecfb7042fb8d5.zip |
Include fees in computation
-rw-r--r-- | script.py | 53 |
1 files changed, 41 insertions, 12 deletions
@@ -31,13 +31,25 @@ def get_ticker(c1, c2, market): | |||
31 | "ask": float(1/ticker["bid"]), | 31 | "ask": float(1/ticker["bid"]), |
32 | "bidA": float(1/ticker["askA"]), | 32 | "bidA": float(1/ticker["askA"]), |
33 | "askA": float(1/ticker["bidA"]), | 33 | "askA": float(1/ticker["bidA"]), |
34 | "bidE": float(1/ticker["askE"]), | ||
35 | "askE": float(1/ticker["bidE"]), | ||
34 | } | 36 | } |
35 | def augment_ticker(ticker): | 37 | def augment_ticker(ticker): |
38 | bid_factor = 1.01 | ||
39 | ask_factor = 0.99 | ||
40 | fees = fetch_fees(market) | ||
36 | # FIXME: need to do better than just a multiplier | 41 | # FIXME: need to do better than just a multiplier |
37 | ticker.update({ | 42 | ticker.update({ |
38 | "inverted": False, | 43 | "inverted": False, |
39 | "bidA": ticker["bid"] * 0.99, | 44 | # Adjusted |
40 | "askA": ticker["ask"] * 1.01, | 45 | "bidA": ticker["bid"] * bid_factor, |
46 | "askA": ticker["ask"] * ask_factor, | ||
47 | # Expected in the end | ||
48 | "bidE": ticker["bid"] * bid_factor * (1 - fees["maker"]), | ||
49 | "askE": ticker["ask"] * ask_factor * (1 - fees["maker"]), | ||
50 | # fees | ||
51 | "bidF": ticker["bid"] * bid_factor * fees["maker"], | ||
52 | "askF": ticker["ask"] * ask_factor * fees["maker"], | ||
41 | }) | 53 | }) |
42 | 54 | ||
43 | if (c1, c2, market.__class__) in get_ticker.cache: | 55 | if (c1, c2, market.__class__) in get_ticker.cache: |
@@ -64,16 +76,26 @@ def fetch_balances(market): | |||
64 | balances[key] = int(value * 10**max_digits) | 76 | balances[key] = int(value * 10**max_digits) |
65 | return balances | 77 | return balances |
66 | 78 | ||
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__] | ||
84 | |||
67 | def assets_value(assets, market, base_currency="BTC"): | 85 | def assets_value(assets, market, base_currency="BTC"): |
68 | repartition_in_base_currency = {} | 86 | repartition_in_base_currency = {} |
69 | for currency, asset_value in assets.items(): | 87 | for currency, asset_value in assets.items(): |
70 | if currency == base_currency: | 88 | if currency == base_currency: |
71 | repartition_in_base_currency[currency] = asset_value | 89 | repartition_in_base_currency[currency] = [asset_value, 0] |
72 | else: | 90 | else: |
73 | asset_ticker = get_ticker(currency, base_currency, market) | 91 | asset_ticker = get_ticker(currency, base_currency, market) |
74 | if asset_ticker is None: | 92 | if asset_ticker is None: |
75 | raise Exception("This asset is not available in the chosen market") | 93 | raise Exception("This asset is not available in the chosen market") |
76 | repartition_in_base_currency[currency] = int(asset_ticker["bidA"] * asset_value) | 94 | repartition_in_base_currency[currency] = [ |
95 | int(asset_ticker["bidE"] * asset_value), | ||
96 | int(asset_ticker["bidF"] * asset_value) | ||
97 | ] | ||
98 | |||
77 | return repartition_in_base_currency | 99 | return repartition_in_base_currency |
78 | 100 | ||
79 | def dispatch_assets(base_currency_value, repartition_pertenthousand, market, base_currency="BTC"): | 101 | def dispatch_assets(base_currency_value, repartition_pertenthousand, market, base_currency="BTC"): |
@@ -83,15 +105,20 @@ def dispatch_assets(base_currency_value, repartition_pertenthousand, market, bas | |||
83 | repartition_in_base_currency[currency] = int(ptt * base_currency_value / sum_pertenthousand) | 105 | repartition_in_base_currency[currency] = int(ptt * base_currency_value / sum_pertenthousand) |
84 | return repartition_in_base_currency | 106 | return repartition_in_base_currency |
85 | 107 | ||
86 | def compute_moves(current_assets, repartition_pertenthousand, market, base_currency="BTC"): | 108 | def compute_moves(current_assets, repartition_pertenthousand, market, no_fees=True, base_currency="BTC"): |
87 | value_in_base = assets_value(current_assets, market, base_currency=base_currency) | 109 | 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()]) | 110 | total_base_value = sum([ v[0] for k, v in value_in_base.items()]) |
89 | 111 | ||
90 | new_repartition = dispatch_assets(total_base_value, repartition_pertenthousand, market, base_currency=base_currency) | 112 | new_repartition = dispatch_assets(total_base_value, repartition_pertenthousand, market, base_currency=base_currency) |
91 | mouvements = {} | 113 | mouvements = {} |
92 | 114 | ||
93 | for key in set(value_in_base.keys()).union(set(new_repartition.keys())): | 115 | if no_fees: |
94 | mouvements[key] = value_in_base.get(key, 0) - new_repartition.get(key, 0) | 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) | ||
118 | else: | ||
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] | ||
95 | 122 | ||
96 | return mouvements | 123 | return mouvements |
97 | 124 | ||
@@ -148,7 +175,7 @@ def print_assets(assets, indent="", market=None, base_currency="BTC"): | |||
148 | for currency, value in assets.items(): | 175 | for currency, value in assets.items(): |
149 | if market is not None: | 176 | if market is not None: |
150 | asset_ticker = get_ticker(currency, base_currency, market) | 177 | asset_ticker = get_ticker(currency, base_currency, market) |
151 | base_currency_price = asset_ticker["bidA"] * value | 178 | base_currency_price = asset_ticker["bidE"] * value |
152 | print(format_string.format( | 179 | print(format_string.format( |
153 | indent, | 180 | indent, |
154 | formatted_price(value), | 181 | formatted_price(value), |
@@ -161,9 +188,10 @@ def print_orders(current_assets, repartition_pertenthousand, market, base_curren | |||
161 | current_assets, | 188 | current_assets, |
162 | repartition_pertenthousand, | 189 | repartition_pertenthousand, |
163 | market, | 190 | market, |
191 | no_fees=False, | ||
164 | base_currency=base_currency) | 192 | base_currency=base_currency) |
165 | 193 | ||
166 | for currency, value in mouvements.items(): | 194 | for currency, [value, fee] in mouvements.items(): |
167 | action, rate, inverted = compute_order( | 195 | action, rate, inverted = compute_order( |
168 | currency, | 196 | currency, |
169 | value, | 197 | value, |
@@ -179,11 +207,12 @@ def print_orders(current_assets, repartition_pertenthousand, market, base_curren | |||
179 | c1, c2 = [currency, base_currency] | 207 | c1, c2 = [currency, base_currency] |
180 | v1, v2 = [currency_price, value] | 208 | v1, v2 = [currency_price, value] |
181 | 209 | ||
182 | print("need to {} {} {}'s worth of {}, i.e. {} {}".format( | 210 | print("need to {} {} {}'s worth of {}, i.e. {} {} ( + {} {} fee)".format( |
183 | action, | 211 | action, |
184 | formatted_price(abs(v1)), c1, | 212 | formatted_price(abs(v1)), c1, |
185 | c2, | 213 | c2, |
186 | formatted_price(abs(v2)), c2)) | 214 | formatted_price(abs(v2)), c2, |
215 | formatted_price(fee), c2)) | ||
187 | 216 | ||
188 | current_assets = fetch_balances(market) | 217 | current_assets = fetch_balances(market) |
189 | print_orders(current_assets, repartition_pertenthousand, market) | 218 | print_orders(current_assets, repartition_pertenthousand, market) |