Use ccxt.decimal_to_precision instead of our own calculation

This commit is contained in:
Matthias 2020-01-12 14:40:58 +01:00
parent fa1f9bcdbd
commit b60d7ad42f
2 changed files with 33 additions and 10 deletions

View File

@ -7,14 +7,15 @@ import inspect
import logging import logging
from copy import deepcopy from copy import deepcopy
from datetime import datetime, timezone from datetime import datetime, timezone
from math import ceil, floor from math import ceil
from random import randint from random import randint
from typing import Any, Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional, Tuple
import arrow import arrow
import ccxt import ccxt
import ccxt.async_support as ccxt_async import ccxt.async_support as ccxt_async
from ccxt.base.decimal_to_precision import ROUND_DOWN, ROUND_UP from ccxt.base.decimal_to_precision import (ROUND, ROUND_DOWN, ROUND_UP,
TRUNCATE, decimal_to_precision)
from pandas import DataFrame from pandas import DataFrame
from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.data.converter import parse_ticker_dataframe
@ -367,26 +368,29 @@ class Exchange:
""" """
return endpoint in self._api.has and self._api.has[endpoint] return endpoint in self._api.has and self._api.has[endpoint]
def symbol_amount_prec(self, pair, amount: float): def symbol_amount_prec(self, pair, amount: float) -> float:
''' '''
Returns the amount to buy or sell to a precision the Exchange accepts Returns the amount to buy or sell to a precision the Exchange accepts
Rounded down Rounded down
''' '''
if self.markets[pair]['precision']['amount']: if self.markets[pair]['precision']['amount']:
symbol_prec = self.markets[pair]['precision']['amount'] amount = float(decimal_to_precision(amount, rounding_mode=TRUNCATE,
big_amount = amount * pow(10, symbol_prec) precision=self.markets[pair]['precision']['amount'],
amount = floor(big_amount) / pow(10, symbol_prec) counting_mode=self.precisionMode,
))
return amount return amount
def symbol_price_prec(self, pair, price: float): def symbol_price_prec(self, pair, price: float) -> float:
''' '''
Returns the price buying or selling with to the precision the Exchange accepts Returns the price buying or selling with to the precision the Exchange accepts
Rounds up Rounds up
''' '''
if self.markets[pair]['precision']['price']: if self.markets[pair]['precision']['price']:
symbol_prec = self.markets[pair]['precision']['price'] price = float(decimal_to_precision(price, rounding_mode=ROUND,
big_price = price * pow(10, symbol_prec) precision=self.markets[pair]['precision']['price'],
price = ceil(big_price) / pow(10, symbol_prec) counting_mode=self.precisionMode,
))
return price return price
def dry_run_order(self, pair: str, ordertype: str, side: str, amount: float, def dry_run_order(self, pair: str, ordertype: str, side: str, amount: float,

View File

@ -181,6 +181,11 @@ def test_symbol_amount_prec(default_conf, mocker):
markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'amount': 4}}}) markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'amount': 4}}})
exchange = get_patched_exchange(mocker, default_conf, id="binance") exchange = get_patched_exchange(mocker, default_conf, id="binance")
# digits counting mode
# DECIMAL_PLACES = 2
# SIGNIFICANT_DIGITS = 3
# TICK_SIZE = 4
mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=2))
mocker.patch('freqtrade.exchange.Exchange.markets', markets) mocker.patch('freqtrade.exchange.Exchange.markets', markets)
amount = 2.34559 amount = 2.34559
@ -188,6 +193,12 @@ def test_symbol_amount_prec(default_conf, mocker):
amount = exchange.symbol_amount_prec(pair, amount) amount = exchange.symbol_amount_prec(pair, amount)
assert amount == 2.3455 assert amount == 2.3455
markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'amount': 0.0001}}})
mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=4))
mocker.patch('freqtrade.exchange.Exchange.markets', markets)
amount = exchange.symbol_amount_prec(pair, amount)
assert amount == 2.3455
def test_symbol_price_prec(default_conf, mocker): def test_symbol_price_prec(default_conf, mocker):
''' '''
@ -197,12 +208,20 @@ def test_symbol_price_prec(default_conf, mocker):
exchange = get_patched_exchange(mocker, default_conf, id="binance") exchange = get_patched_exchange(mocker, default_conf, id="binance")
mocker.patch('freqtrade.exchange.Exchange.markets', markets) mocker.patch('freqtrade.exchange.Exchange.markets', markets)
mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=2))
price = 2.34559 price = 2.34559
pair = 'ETH/BTC' pair = 'ETH/BTC'
price = exchange.symbol_price_prec(pair, price) price = exchange.symbol_price_prec(pair, price)
assert price == 2.3456 assert price == 2.3456
markets = PropertyMock(return_value={'ETH/BTC': {'precision': {'price': 0.0001}}})
mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=4))
mocker.patch('freqtrade.exchange.Exchange.markets', markets)
price = exchange.symbol_price_prec(pair, price)
assert price == 2.3456
def test_set_sandbox(default_conf, mocker): def test_set_sandbox(default_conf, mocker):
""" """