Handle order returns that contain trades directly
binance market orders - and potentially other exchanges
This commit is contained in:
parent
f7b2c0c5d7
commit
f8d30abd79
@ -1381,14 +1381,17 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
return self.apply_fee_conditional(trade, trade_base_currency,
|
return self.apply_fee_conditional(trade, trade_base_currency,
|
||||||
amount=order_amount, fee_abs=fee_cost)
|
amount=order_amount, fee_abs=fee_cost)
|
||||||
return order_amount
|
return order_amount
|
||||||
return self.fee_detection_from_trades(trade, order, order_amount)
|
return self.fee_detection_from_trades(trade, order, order_amount, order.get('trades', []))
|
||||||
|
|
||||||
def fee_detection_from_trades(self, trade: Trade, order: Dict, order_amount: float) -> float:
|
def fee_detection_from_trades(self, trade: Trade, order: Dict, order_amount: float,
|
||||||
|
trades: List) -> float:
|
||||||
"""
|
"""
|
||||||
fee-detection fallback to Trades. Parses result of fetch_my_trades to get correct fee.
|
fee-detection fallback to Trades.
|
||||||
|
Either uses provided trades list or the result of fetch_my_trades to get correct fee.
|
||||||
"""
|
"""
|
||||||
trades = self.exchange.get_trades_for_order(self.exchange.get_order_id_conditional(order),
|
if not trades:
|
||||||
trade.pair, trade.open_date)
|
trades = self.exchange.get_trades_for_order(
|
||||||
|
self.exchange.get_order_id_conditional(order), trade.pair, trade.open_date)
|
||||||
|
|
||||||
if len(trades) == 0:
|
if len(trades) == 0:
|
||||||
logger.info("Applying fee on amount for %s failed: myTrade-Dict empty found", trade)
|
logger.info("Applying fee on amount for %s failed: myTrade-Dict empty found", trade)
|
||||||
|
@ -2221,6 +2221,46 @@ def market_buy_order_usdt():
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def market_buy_order_usdt_doublefee(market_buy_order_usdt):
|
||||||
|
order = deepcopy(market_buy_order_usdt)
|
||||||
|
order['fee'] = None
|
||||||
|
# Market orders filled with 2 trades can have fees in different currencies
|
||||||
|
# assuming the account runs out of BNB.
|
||||||
|
order['fees'] = [
|
||||||
|
{'cost': 0.00025125, 'currency': 'BNB'},
|
||||||
|
{'cost': 0.05030681, 'currency': 'USDT'},
|
||||||
|
]
|
||||||
|
order['trades'] = [{
|
||||||
|
'timestamp': None,
|
||||||
|
'datetime': None,
|
||||||
|
'symbol': 'ETH/USDT',
|
||||||
|
'id': None,
|
||||||
|
'order': '123',
|
||||||
|
'type': 'market',
|
||||||
|
'side': 'sell',
|
||||||
|
'takerOrMaker': None,
|
||||||
|
'price': 2.01,
|
||||||
|
'amount': 25.0,
|
||||||
|
'cost': 50.25,
|
||||||
|
'fee': {'cost': 0.00025125, 'currency': 'BNB'}
|
||||||
|
}, {
|
||||||
|
'timestamp': None,
|
||||||
|
'datetime': None,
|
||||||
|
'symbol': 'ETH/USDT',
|
||||||
|
'id': None,
|
||||||
|
'order': '123',
|
||||||
|
'type': 'market',
|
||||||
|
'side': 'sell',
|
||||||
|
'takerOrMaker': None,
|
||||||
|
'price': 2.0,
|
||||||
|
'amount': 5,
|
||||||
|
'cost': 10,
|
||||||
|
'fee': {'cost': 0.0100306, 'currency': 'USDT'}
|
||||||
|
}]
|
||||||
|
return order
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def market_sell_order_usdt():
|
def market_sell_order_usdt():
|
||||||
return {
|
return {
|
||||||
|
@ -3634,6 +3634,31 @@ def test_get_real_amount_invalid_order(default_conf_usdt, trades_for_order, buy_
|
|||||||
assert freqtrade.get_real_amount(trade, limit_buy_order_usdt) == amount
|
assert freqtrade.get_real_amount(trade, limit_buy_order_usdt) == amount
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_real_amount_fees_order(default_conf_usdt, market_buy_order_usdt_doublefee,
|
||||||
|
fee, mocker):
|
||||||
|
|
||||||
|
tfo_mock = mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[])
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.get_valid_pair_combination', return_value='BNB/USDT')
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', return_value={'last': 200})
|
||||||
|
trade = Trade(
|
||||||
|
pair='LTC/USDT',
|
||||||
|
amount=30.0,
|
||||||
|
exchange='binance',
|
||||||
|
fee_open=fee.return_value,
|
||||||
|
fee_close=fee.return_value,
|
||||||
|
open_rate=0.245441,
|
||||||
|
open_order_id="123456"
|
||||||
|
)
|
||||||
|
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
||||||
|
|
||||||
|
# Amount does not change
|
||||||
|
assert trade.fee_open == 0.0025
|
||||||
|
assert freqtrade.get_real_amount(trade, market_buy_order_usdt_doublefee) == 30.0
|
||||||
|
assert tfo_mock.call_count == 0
|
||||||
|
# Fetch fees from trades dict if available to get "proper" values
|
||||||
|
assert round(trade.fee_open, 4) == 0.001
|
||||||
|
|
||||||
|
|
||||||
def test_get_real_amount_wrong_amount(default_conf_usdt, trades_for_order, buy_order_fee, fee,
|
def test_get_real_amount_wrong_amount(default_conf_usdt, trades_for_order, buy_order_fee, fee,
|
||||||
mocker):
|
mocker):
|
||||||
limit_buy_order_usdt = deepcopy(buy_order_fee)
|
limit_buy_order_usdt = deepcopy(buy_order_fee)
|
||||||
|
Loading…
Reference in New Issue
Block a user