From 2618f3371c9f484b398c6573d65f16dc50fe9fa4 Mon Sep 17 00:00:00 2001 From: Sam Germain Date: Mon, 21 Mar 2022 01:28:36 -0600 Subject: [PATCH] taker or maker passed correctly for buy and sell orders --- freqtrade/freqtradebot.py | 35 +++++++++++++++++++++++++++++++---- tests/test_freqtradebot.py | 20 +++++++++++++++++--- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 7c20a7f60..a8e51057a 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -570,6 +570,35 @@ class FreqtradeBot(LoggingMixin): logger.info(f"Bids to asks delta for {pair} does not satisfy condition.") return False + def get_fee( + self, + pair: str, + side: str, + is_short: bool = False, + ): + ''' + :param pair: Unified CCXT symbol + :param side: One of entry, exit or stoploss + :param is_short: True for short trades + ''' + order_type = self.config['order_types'][side] + if order_type == 'limit': + enter_side = 'ask' if is_short else 'bid' + exit_side = 'bid' if is_short else 'ask' + if ( + side == 'entry' and self.config['bid_strategy']['price_side'] == enter_side or + side == 'exit' and self.config['ask_strategy']['price_side'] == exit_side + ): + taker_or_maker = 'maker' + else: + taker_or_maker = 'taker' + else: + taker_or_maker = 'taker' + return self.exchange.get_fee( + symbol=pair, + taker_or_maker=taker_or_maker + ) + def execute_entry( self, pair: str, @@ -664,12 +693,10 @@ class FreqtradeBot(LoggingMixin): enter_limit_filled_price = safe_value_fallback(order, 'average', 'price') # Fee is applied twice because we make a LIMIT_BUY and LIMIT_SELL - fee = self.exchange.get_fee(symbol=pair, taker_or_maker='maker') base_currency = self.exchange.get_pair_base_currency(pair) open_date = datetime.now(timezone.utc) funding_fees = self.exchange.get_funding_fees( pair=pair, amount=amount, is_short=is_short, open_date=open_date) - # This is a new trade if trade is None: trade = Trade( pair=pair, @@ -679,8 +706,8 @@ class FreqtradeBot(LoggingMixin): amount=amount, is_open=True, amount_requested=amount_requested, - fee_open=fee, - fee_close=fee, + fee_open=self.get_fee(pair, 'entry'), + fee_close=self.get_fee(pair, 'exit'), open_rate=enter_limit_filled_price, open_rate_requested=enter_limit_requested, open_date=open_date, diff --git a/tests/test_freqtradebot.py b/tests/test_freqtradebot.py index 89fe88a2c..b36ddee6e 100644 --- a/tests/test_freqtradebot.py +++ b/tests/test_freqtradebot.py @@ -769,6 +769,11 @@ def test_execute_entry(mocker, default_conf_usdt, fee, limit_order, bid = 0.11 enter_rate_mock = MagicMock(return_value=bid) enter_mm = MagicMock(return_value=open_order) + default_conf_usdt['order_types'] = { + 'entry': 'limit', + 'exit': 'market', + 'stoploss': 'market', + } mocker.patch.multiple( 'freqtrade.exchange.Exchange', get_rate=enter_rate_mock, @@ -780,15 +785,15 @@ def test_execute_entry(mocker, default_conf_usdt, fee, limit_order, create_order=enter_mm, get_min_pair_stake_amount=MagicMock(return_value=1), get_max_pair_stake_amount=MagicMock(return_value=500000), - get_fee=fee, + get_fee=MagicMock(side_effect=( + lambda symbol, taker_or_maker: fee if taker_or_maker == 'maker' else fee*2 + )), get_funding_fees=MagicMock(return_value=0), name=exchange_name, get_maintenance_ratio_and_amt=MagicMock(return_value=(0.01, 0.01)), get_max_leverage=MagicMock(return_value=10), ) mocker.patch.multiple( - 'freqtrade.exchange.Okx', - get_max_pair_stake_amount=MagicMock(return_value=500000), ) pair = 'ETH/USDT' @@ -816,6 +821,8 @@ def test_execute_entry(mocker, default_conf_usdt, fee, limit_order, assert trade assert trade.is_open is True assert trade.open_order_id == '22' + assert trade.open_fee == fee + assert trade.close_fee == fee*2 # Test calling with price open_order['id'] = '33' @@ -836,6 +843,11 @@ def test_execute_entry(mocker, default_conf_usdt, fee, limit_order, order['cost'] = 100 order['id'] = '444' + default_conf_usdt['order_types'] = { + 'entry': 'market', + 'exit': 'limit', + 'stoploss': 'market', + } mocker.patch('freqtrade.exchange.Exchange.create_order', MagicMock(return_value=order)) assert freqtrade.execute_entry(pair, stake_amount, is_short=is_short) @@ -846,6 +858,8 @@ def test_execute_entry(mocker, default_conf_usdt, fee, limit_order, assert trade.open_rate == 10 assert trade.stake_amount == round(order['price'] * order['filled'] / leverage, 8) assert pytest.approx(trade.liquidation_price) == liq_price + assert trade.open_fee == fee*2 + assert trade.close_fee == fee # In case of rejected or expired order and partially filled order['status'] = 'expired'