Merge pull request #3112 from freqtrade/trade_state_updates
Trade state updates
This commit is contained in:
@@ -758,6 +758,7 @@ def limit_buy_order():
|
||||
'datetime': arrow.utcnow().isoformat(),
|
||||
'price': 0.00001099,
|
||||
'amount': 90.99181073,
|
||||
'filled': 90.99181073,
|
||||
'remaining': 0.0,
|
||||
'status': 'closed'
|
||||
}
|
||||
@@ -773,6 +774,7 @@ def market_buy_order():
|
||||
'datetime': arrow.utcnow().isoformat(),
|
||||
'price': 0.00004099,
|
||||
'amount': 91.99181073,
|
||||
'filled': 91.99181073,
|
||||
'remaining': 0.0,
|
||||
'status': 'closed'
|
||||
}
|
||||
@@ -788,6 +790,7 @@ def market_sell_order():
|
||||
'datetime': arrow.utcnow().isoformat(),
|
||||
'price': 0.00004173,
|
||||
'amount': 91.99181073,
|
||||
'filled': 91.99181073,
|
||||
'remaining': 0.0,
|
||||
'status': 'closed'
|
||||
}
|
||||
@@ -803,6 +806,7 @@ def limit_buy_order_old():
|
||||
'datetime': str(arrow.utcnow().shift(minutes=-601).datetime),
|
||||
'price': 0.00001099,
|
||||
'amount': 90.99181073,
|
||||
'filled': 0.0,
|
||||
'remaining': 90.99181073,
|
||||
'status': 'open'
|
||||
}
|
||||
@@ -818,6 +822,7 @@ def limit_sell_order_old():
|
||||
'datetime': arrow.utcnow().shift(minutes=-601).isoformat(),
|
||||
'price': 0.00001099,
|
||||
'amount': 90.99181073,
|
||||
'filled': 0.0,
|
||||
'remaining': 90.99181073,
|
||||
'status': 'open'
|
||||
}
|
||||
@@ -833,6 +838,7 @@ def limit_buy_order_old_partial():
|
||||
'datetime': arrow.utcnow().shift(minutes=-601).isoformat(),
|
||||
'price': 0.00001099,
|
||||
'amount': 90.99181073,
|
||||
'filled': 23.0,
|
||||
'remaining': 67.99181073,
|
||||
'status': 'open'
|
||||
}
|
||||
@@ -856,6 +862,7 @@ def limit_sell_order():
|
||||
'datetime': arrow.utcnow().isoformat(),
|
||||
'price': 0.00001173,
|
||||
'amount': 90.99181073,
|
||||
'filled': 90.99181073,
|
||||
'remaining': 0.0,
|
||||
'status': 'closed'
|
||||
}
|
||||
|
@@ -1731,6 +1731,20 @@ def test_cancel_order_dry_run(default_conf, mocker, exchange_name):
|
||||
assert exchange.cancel_order(order_id='123', pair='TKN/BTC') is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
||||
@pytest.mark.parametrize("order,result", [
|
||||
({'status': 'closed', 'filled': 10}, False),
|
||||
({'status': 'closed', 'filled': 0.0}, True),
|
||||
({'status': 'canceled', 'filled': 0.0}, True),
|
||||
({'status': 'canceled', 'filled': 10.0}, False),
|
||||
({'status': 'unknown', 'filled': 10.0}, False),
|
||||
({'result': 'testest123'}, False),
|
||||
])
|
||||
def test_check_order_canceled_empty(mocker, default_conf, exchange_name, order, result):
|
||||
exchange = get_patched_exchange(mocker, default_conf, id=exchange_name)
|
||||
assert exchange.check_order_canceled_empty(order) == result
|
||||
|
||||
|
||||
# Ensure that if not dry_run, we should call API
|
||||
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
||||
def test_cancel_order(default_conf, mocker, exchange_name):
|
||||
|
@@ -1316,18 +1316,20 @@ def test_send_msg_sell_cancel_notification(default_conf, mocker) -> None:
|
||||
'type': RPCMessageType.SELL_CANCEL_NOTIFICATION,
|
||||
'exchange': 'Binance',
|
||||
'pair': 'KEY/ETH',
|
||||
'reason': 'Cancelled on exchange'
|
||||
})
|
||||
assert msg_mock.call_args[0][0] \
|
||||
== ('*Binance:* Cancelling Open Sell Order for KEY/ETH')
|
||||
== ('*Binance:* Cancelling Open Sell Order for KEY/ETH. Reason: Cancelled on exchange')
|
||||
|
||||
msg_mock.reset_mock()
|
||||
telegram.send_msg({
|
||||
'type': RPCMessageType.SELL_CANCEL_NOTIFICATION,
|
||||
'exchange': 'Binance',
|
||||
'pair': 'KEY/ETH',
|
||||
'reason': 'timeout'
|
||||
})
|
||||
assert msg_mock.call_args[0][0] \
|
||||
== ('*Binance:* Cancelling Open Sell Order for KEY/ETH')
|
||||
== ('*Binance:* Cancelling Open Sell Order for KEY/ETH. Reason: timeout')
|
||||
# Reset singleton function to avoid random breaks
|
||||
telegram._fiat_converter.convert_amount = old_convamount
|
||||
|
||||
|
@@ -1592,13 +1592,13 @@ def test_exit_positions_exception(mocker, default_conf, limit_buy_order, caplog)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_order', return_value=limit_buy_order)
|
||||
|
||||
trade = MagicMock()
|
||||
trade.open_order_id = '123'
|
||||
trade.open_order_id = None
|
||||
trade.open_fee = 0.001
|
||||
trades = [trade]
|
||||
|
||||
# Test raise of DependencyException exception
|
||||
mocker.patch(
|
||||
'freqtrade.freqtradebot.FreqtradeBot.update_trade_state',
|
||||
'freqtrade.freqtradebot.FreqtradeBot.handle_trade',
|
||||
side_effect=DependencyException()
|
||||
)
|
||||
n = freqtrade.exit_positions(trades)
|
||||
@@ -1970,7 +1970,7 @@ def test_check_handle_cancelled_buy(default_conf, ticker, limit_buy_order_old, o
|
||||
rpc_mock = patch_RPCManager(mocker)
|
||||
cancel_order_mock = MagicMock()
|
||||
patch_exchange(mocker)
|
||||
limit_buy_order_old.update({"status": "canceled"})
|
||||
limit_buy_order_old.update({"status": "canceled", 'filled': 0.0})
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
fetch_ticker=ticker,
|
||||
@@ -2049,7 +2049,7 @@ def test_check_handle_cancelled_sell(default_conf, ticker, limit_sell_order_old,
|
||||
""" Handle sell order cancelled on exchange"""
|
||||
rpc_mock = patch_RPCManager(mocker)
|
||||
cancel_order_mock = MagicMock()
|
||||
limit_sell_order_old.update({"status": "canceled"})
|
||||
limit_sell_order_old.update({"status": "canceled", 'filled': 0.0})
|
||||
patch_exchange(mocker)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
@@ -2129,7 +2129,7 @@ def test_check_handle_timedout_partial_fee(default_conf, ticker, open_trade, cap
|
||||
assert rpc_mock.call_count == 2
|
||||
trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all()
|
||||
assert len(trades) == 1
|
||||
# Verify that tradehas been updated
|
||||
# Verify that trade has been updated
|
||||
assert trades[0].amount == (limit_buy_order_old_partial['amount'] -
|
||||
limit_buy_order_old_partial['remaining']) - 0.0001
|
||||
assert trades[0].open_order_id is None
|
||||
@@ -2168,7 +2168,7 @@ def test_check_handle_timedout_partial_except(default_conf, ticker, open_trade,
|
||||
assert rpc_mock.call_count == 2
|
||||
trades = Trade.query.filter(Trade.open_order_id.is_(open_trade.open_order_id)).all()
|
||||
assert len(trades) == 1
|
||||
# Verify that tradehas been updated
|
||||
# Verify that trade has been updated
|
||||
|
||||
assert trades[0].amount == (limit_buy_order_old_partial['amount'] -
|
||||
limit_buy_order_old_partial['remaining'])
|
||||
@@ -2276,7 +2276,8 @@ def test_handle_timedout_limit_sell(mocker, default_conf) -> None:
|
||||
assert freqtrade.handle_timedout_limit_sell(trade, order)
|
||||
assert cancel_order_mock.call_count == 1
|
||||
order['amount'] = 2
|
||||
assert not freqtrade.handle_timedout_limit_sell(trade, order)
|
||||
assert (freqtrade.handle_timedout_limit_sell(trade, order)
|
||||
== 'partially filled - keeping order open')
|
||||
# Assert cancel_order was not called (callcount remains unchanged)
|
||||
assert cancel_order_mock.call_count == 1
|
||||
|
||||
@@ -2499,6 +2500,7 @@ def test_execute_sell_with_stoploss_on_exchange(default_conf, ticker, fee, ticke
|
||||
assert trade
|
||||
trades = [trade]
|
||||
|
||||
freqtrade.check_handle_timedout()
|
||||
freqtrade.exit_positions(trades)
|
||||
|
||||
# Increase the price and sell it
|
||||
@@ -2544,8 +2546,11 @@ def test_may_execute_sell_after_stoploss_on_exchange_hit(default_conf, ticker, f
|
||||
|
||||
# Create some test data
|
||||
freqtrade.enter_positions()
|
||||
freqtrade.check_handle_timedout()
|
||||
trade = Trade.query.first()
|
||||
trades = [trade]
|
||||
assert trade.stoploss_order_id is None
|
||||
|
||||
freqtrade.exit_positions(trades)
|
||||
assert trade
|
||||
assert trade.stoploss_order_id == '123'
|
||||
|
Reference in New Issue
Block a user