Skip to content

Commit

Permalink
Add test for rounding error on fload aggregation
Browse files Browse the repository at this point in the history
  • Loading branch information
xmatthias committed Sep 26, 2019
1 parent 5978b7b commit 49f0a72
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 2 deletions.
1 change: 1 addition & 0 deletions freqtrade/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
ORDERTIF_POSSIBILITIES = ['gtc', 'fok', 'ioc']
AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList']
DRY_RUN_WALLET = 999.9
MATH_CLOSE_PREC = 1e-14 # Precision used for float comparisons

TICKER_INTERVALS = [
'1m', '3m', '5m', '15m', '30m',
Expand Down
55 changes: 53 additions & 2 deletions tests/test_freqtradebot.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import logging
import time
from copy import deepcopy
from math import isclose
from unittest.mock import MagicMock, PropertyMock

import arrow
Expand All @@ -12,6 +13,7 @@

from freqtrade import (DependencyException, InvalidOrderException,
OperationalException, TemporaryError, constants)
from freqtrade.constants import MATH_CLOSE_PREC
from freqtrade.data.dataprovider import DataProvider
from freqtrade.freqtradebot import FreqtradeBot
from freqtrade.persistence import Trade
Expand Down Expand Up @@ -1635,6 +1637,31 @@ def test_update_trade_state_withorderdict(default_conf, trades_for_order, limit_
assert trade.amount == limit_buy_order['amount']


def test_update_trade_state_withorderdict_rounding_fee(default_conf, trades_for_order,
limit_buy_order, mocker, caplog):
trades_for_order[0]['amount'] = limit_buy_order['amount'] + 1e-14
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order)
# get_order should not be called!!
mocker.patch('freqtrade.exchange.Exchange.get_order', MagicMock(side_effect=ValueError))
patch_exchange(mocker)
Trade.session = MagicMock()
amount = sum(x['amount'] for x in trades_for_order)
freqtrade = get_patched_freqtradebot(mocker, default_conf)
trade = Trade(
pair='LTC/ETH',
amount=amount,
exchange='binance',
open_rate=0.245441,
open_order_id="123456",
is_open=True,
open_date=arrow.utcnow().datetime,
)
freqtrade.update_trade_state(trade, limit_buy_order)
assert trade.amount != amount
assert trade.amount == limit_buy_order['amount']
assert log_has_re(r'Applying fee on amount for .*', caplog)


def test_update_trade_state_exception(mocker, default_conf,
limit_buy_order, caplog) -> None:
freqtrade = get_patched_freqtradebot(mocker, default_conf)
Expand Down Expand Up @@ -3207,8 +3234,7 @@ def test_get_real_amount_invalid_order(default_conf, trades_for_order, buy_order

def test_get_real_amount_wrong_amount(default_conf, trades_for_order, buy_order_fee, mocker):
limit_buy_order = deepcopy(buy_order_fee)
limit_buy_order['fee'] = {'cost': 0.004}
limit_buy_order['amount'] = limit_buy_order['amount'] + 0.1
limit_buy_order['amount'] = limit_buy_order['amount'] - 0.001

patch_RPCManager(mocker)
patch_exchange(mocker)
Expand All @@ -3229,6 +3255,31 @@ def test_get_real_amount_wrong_amount(default_conf, trades_for_order, buy_order_
freqtrade.get_real_amount(trade, limit_buy_order)


def test_get_real_amount_wrong_amount_rounding(default_conf, trades_for_order, buy_order_fee,
mocker):
# Floats should not be compared directly.
limit_buy_order = deepcopy(buy_order_fee)
trades_for_order[0]['amount'] = trades_for_order[0]['amount'] + 1e-15

patch_RPCManager(mocker)
patch_exchange(mocker)
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order)
amount = float(sum(x['amount'] for x in trades_for_order))
trade = Trade(
pair='LTC/ETH',
amount=amount,
exchange='binance',
open_rate=0.245441,
open_order_id="123456"
)
freqtrade = FreqtradeBot(default_conf)
patch_get_signal(freqtrade)

# Amount changes by fee amount.
assert isclose(freqtrade.get_real_amount(trade, limit_buy_order), amount - (amount * 0.001),
rel_tol=MATH_CLOSE_PREC,)


def test_get_real_amount_invalid(default_conf, trades_for_order, buy_order_fee, mocker):
# Remove "Currency" from fee dict
trades_for_order[0]['fee'] = {'cost': 0.008}
Expand Down

0 comments on commit 49f0a72

Please sign in to comment.