From e06ad1af5c87e37988cc07a276d17d55ad49ce4e Mon Sep 17 00:00:00 2001 From: Marko Paasila Date: Sat, 16 Mar 2019 18:07:52 +0200 Subject: [PATCH 1/2] Added a method to correct prices and amounts or an order so that they match what is actually possible. --- dexbot/strategies/base.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/dexbot/strategies/base.py b/dexbot/strategies/base.py index f8951d029..f29714008 100644 --- a/dexbot/strategies/base.py +++ b/dexbot/strategies/base.py @@ -958,6 +958,37 @@ def get_own_spread(self): actual_spread = lowest_own_sell_price / highest_own_buy_price - 1 return actual_spread + def fix_order_price(self, price=0, quote_amount=0): + """ + Returns a price and amounts that will match what will actually happen on-chain, and + let you contunue using float values in the logic. + In case the amounts get really small, some returned value might be zero. If so, + it is an indication that the funds available aren't sufficient, or they are spread into too many orders. + Amounts are rounded to closest possible decimal. Thus the final price might be lower or higher than intended. + + :param float | price: the naively calculated price that is to be corrected + :param float | quote_amount: the naively calculated amount + :return dict: values that will result in correctly calculated orders + """ + quote_amount_float = quote_amount + base_amount_float = quote * price + quote_precision = (10 ** market['quote']['precision']) + base_precision = (10 ** market['base']['precision']) + quote_amount_internal = round(quote_amount_float * (quote_precision)) + base_amount_internal = round(base_amount_float * (base_precision)) + target_price_internal = price * (base_precision / quote_precision) + if base_amount_internal < quote_amount_internal: + quote_amount_internal = round(base_amount_internal / target_price_internal) + else: + base_amount_internal = round(quote_amount_internal * target_price_internal) + quote_amount_float = quote_amount_internal / quote_precision + base_amount_float = base_amount_internal / base_precision + final_price = float(base_amount_float / quote_amount_float) + + return {'price': final_price, + 'quote_amount': quote_amount_float, + 'base_amount': base_amount_float} + def get_updated_order(self, order_id): """ Tries to get the updated order from the API. Returns None if the order doesn't exist From ab4f762c9a40c6d290e65b1a41eea7df5a820774 Mon Sep 17 00:00:00 2001 From: Marko Paasila Date: Sat, 16 Mar 2019 18:34:24 +0200 Subject: [PATCH 2/2] Fixes --- dexbot/strategies/base.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dexbot/strategies/base.py b/dexbot/strategies/base.py index f29714008..a7a2d3a9f 100644 --- a/dexbot/strategies/base.py +++ b/dexbot/strategies/base.py @@ -958,23 +958,23 @@ def get_own_spread(self): actual_spread = lowest_own_sell_price / highest_own_buy_price - 1 return actual_spread - def fix_order_price(self, price=0, quote_amount=0): + def fix_order_price(price=0, quote_amount=0): """ Returns a price and amounts that will match what will actually happen on-chain, and - let you contunue using float values in the logic. + let you continue using float values in the logic. In case the amounts get really small, some returned value might be zero. If so, it is an indication that the funds available aren't sufficient, or they are spread into too many orders. Amounts are rounded to closest possible decimal. Thus the final price might be lower or higher than intended. - + :param float | price: the naively calculated price that is to be corrected :param float | quote_amount: the naively calculated amount :return dict: values that will result in correctly calculated orders """ quote_amount_float = quote_amount - base_amount_float = quote * price - quote_precision = (10 ** market['quote']['precision']) - base_precision = (10 ** market['base']['precision']) - quote_amount_internal = round(quote_amount_float * (quote_precision)) + base_amount_float = quote_amount * price + quote_precision = (10 ** self.market['quote']['precision']) + base_precision = (10 ** self.market['base']['precision']) + quote_amount_internal = round(quote_amount_float * quote_precision) base_amount_internal = round(base_amount_float * (base_precision)) target_price_internal = price * (base_precision / quote_precision) if base_amount_internal < quote_amount_internal: