From ce74a5b97e9011358854a8474d97fc5fadee1e84 Mon Sep 17 00:00:00 2001 From: creslin <34645187+creslinux@users.noreply.github.com> Date: Sun, 29 Jul 2018 13:34:57 +0000 Subject: [PATCH 1/3] Update __init__.py Also setting price "rate" to a precision CCXT informs us the exchange/pair accepts Moved from round() to math floor and ceil to explicitly round_down on amount and up on price. --- freqtrade/exchange/__init__.py | 45 ++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index 41fe3e832..99eb303bf 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -4,6 +4,7 @@ import logging from random import randint from typing import List, Dict, Any, Optional from datetime import datetime +from math import floor, ceil import ccxt import arrow @@ -95,10 +96,6 @@ class Exchange(object): except (KeyError, AttributeError): raise OperationalException(f'Exchange {name} is not supported') - # check if config has sandbox = True, if so use ['test'] sandbox API from CCXT - if (exchange_config.get('sandbox')): - api.urls['api'] = api.urls['test'] - return api @property @@ -154,18 +151,38 @@ class Exchange(object): """ return endpoint in self._api.has and self._api.has[endpoint] - def symbol_prec(self, pair, amount: float): + def symbol_amount_prec(self, pair, amount: float): ''' - Returns the amount to buy or sell to the precision the Exchange accepts + Returns the amount to buy or sell to a precision the Exchange accepts + Rounded down + :param pair: the symbol :param amount: amount :return: amount ''' - if self._api.markets[pair]['precision']['amount']: + if self._api.markets[pair]['precision']['amount'] > 0: symbol_prec = self._api.markets[pair]['precision']['amount'] - amount = round(amount, symbol_prec) - + multiplier = int('1' + ('0' * symbol_prec)) + big_amount = amount * multiplier + round_down = floor(big_amount) + amount = round_down / multiplier return amount + def symbol_price_prec(self, pair, price: float): + ''' + Returns the price buying or selling with to the precision the Exchange accepts + Rounds up + :param pair: the symbol + :param price: amount + :return: price + ''' + if self._api.markets[pair]['precision']['price'] > 0: + symbol_prec = self._api.markets[pair]['precision']['price'] + multiplier = int('1' + ('0' * symbol_prec)) + big_price = price * multiplier + round_up = ceil(big_price) + price = round_up / multiplier + return price + def buy(self, pair: str, rate: float, amount: float) -> Dict: if self._conf['dry_run']: order_id = f'dry_run_buy_{randint(0, 10**6)}' @@ -183,8 +200,9 @@ class Exchange(object): return {'id': order_id} try: - # Set the precision accepted by the exchange - amount = self.symbol_prec(pair, amount) + # Set the precision for amount and price(rate) as accepted by the exchange + amount = self.symbol_amount_prec(pair, amount) + rate = self.symbol_price_prec(pair, rate) return self._api.create_limit_buy_order(pair, amount, rate) except ccxt.InsufficientFunds as e: @@ -219,8 +237,9 @@ class Exchange(object): return {'id': order_id} try: - # Set the precision accepted by the exchange - amount = self.symbol_prec(pair, amount) + # Set the precision for amount and price(rate) as accepted by the exchange + amount = self.symbol_amount_prec(pair, amount) + rate = self.symbol_price_prec(pair, rate) return self._api.create_limit_sell_order(pair, amount, rate) except ccxt.InsufficientFunds as e: From 05463e3d913561365193f885c69c4c3135588bec Mon Sep 17 00:00:00 2001 From: creslin <34645187+creslinux@users.noreply.github.com> Date: Sun, 29 Jul 2018 13:58:16 +0000 Subject: [PATCH 2/3] Update __init__.py --- freqtrade/exchange/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index 99eb303bf..4792a0a21 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -159,7 +159,7 @@ class Exchange(object): :param amount: amount :return: amount ''' - if self._api.markets[pair]['precision']['amount'] > 0: + if self._api.markets[pair]['precision']['amount']: symbol_prec = self._api.markets[pair]['precision']['amount'] multiplier = int('1' + ('0' * symbol_prec)) big_amount = amount * multiplier @@ -175,7 +175,7 @@ class Exchange(object): :param price: amount :return: price ''' - if self._api.markets[pair]['precision']['price'] > 0: + if self._api.markets[pair]['precision']['price']: symbol_prec = self._api.markets[pair]['precision']['price'] multiplier = int('1' + ('0' * symbol_prec)) big_price = price * multiplier From 0682f142d27ae97f8591b8d53cbef516e5359efe Mon Sep 17 00:00:00 2001 From: creslin <34645187+creslinux@users.noreply.github.com> Date: Mon, 30 Jul 2018 10:27:19 +0000 Subject: [PATCH 3/3] Update __init__.py Moved to pow(10, on recommendation from core team Removed excessive boiler plating for simple function Tested on sandbox with print output and in scratch conn is HTTPSConnectionPool(host='api-public.sandbox.gdax.com', port=443) conn is HTTPSConnectionPool(host='api-public.sandbox.gdax.com', port=443) be_amount 0.00610615427076642 sym prec is 8 af_amount 0.00610615 b4_price 8188.46 sym prec is 2 af_price 8188.46 --- freqtrade/exchange/__init__.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index 4792a0a21..0f89eb660 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -155,32 +155,22 @@ class Exchange(object): ''' Returns the amount to buy or sell to a precision the Exchange accepts Rounded down - :param pair: the symbol - :param amount: amount - :return: amount ''' if self._api.markets[pair]['precision']['amount']: symbol_prec = self._api.markets[pair]['precision']['amount'] - multiplier = int('1' + ('0' * symbol_prec)) - big_amount = amount * multiplier - round_down = floor(big_amount) - amount = round_down / multiplier + big_amount = amount * pow(10, symbol_prec) + amount = floor(big_amount) / pow(10, symbol_prec) return amount def symbol_price_prec(self, pair, price: float): ''' Returns the price buying or selling with to the precision the Exchange accepts Rounds up - :param pair: the symbol - :param price: amount - :return: price ''' if self._api.markets[pair]['precision']['price']: symbol_prec = self._api.markets[pair]['precision']['price'] - multiplier = int('1' + ('0' * symbol_prec)) - big_price = price * multiplier - round_up = ceil(big_price) - price = round_up / multiplier + big_price = price * pow(10, symbol_prec) + price = ceil(big_price) / pow(10, symbol_prec) return price def buy(self, pair: str, rate: float, amount: float) -> Dict: