diff --git a/freqtrade/main.py b/freqtrade/main.py index 8508bb878..4d6891485 100755 --- a/freqtrade/main.py +++ b/freqtrade/main.py @@ -88,7 +88,7 @@ def _process(dynamic_whitelist: Optional[bool] = False) -> bool: logger.info('Got open order for %s', trade) trade.update(exchange.get_order(trade.open_order_id)) - if not close_trade_if_fulfilled(trade): + if trade.is_open and trade.open_order_id is None: # Check if we can sell our current pair state_changed = handle_trade(trade) or state_changed @@ -109,27 +109,6 @@ def _process(dynamic_whitelist: Optional[bool] = False) -> bool: return state_changed -def close_trade_if_fulfilled(trade: Trade) -> bool: - """ - Checks if the trade is closable, and if so it is being closed. - :param trade: Trade - :return: True if trade has been closed else False - """ - # If we don't have an open order and the close rate is already set, - # we can close this trade. - if trade.close_profit is not None \ - and trade.close_date is not None \ - and trade.close_rate is not None \ - and trade.open_order_id is None: - trade.is_open = False - logger.info( - 'Marking %s as closed as the trade is fulfilled and found no open orders for it.', - trade - ) - return True - return False - - def execute_sell(trade: Trade, limit: float) -> None: """ Executes a limit sell for the given trade and limit diff --git a/freqtrade/persistence.py b/freqtrade/persistence.py index e48538754..cbe7c1de4 100644 --- a/freqtrade/persistence.py +++ b/freqtrade/persistence.py @@ -85,20 +85,27 @@ class Trade(_DECL_BASE): if not order['closed']: return - logger.debug('Updating trade (id=%d) ...', self.id) + logger.info('Updating trade (id=%d) ...', self.id) if order['type'] == 'LIMIT_BUY': # Update open rate and actual amount self.open_rate = order['rate'] self.amount = order['amount'] + logger.info('LIMIT_BUY has been fulfilled for %s.', self) elif order['type'] == 'LIMIT_SELL': # Set close rate and set actual profit self.close_rate = order['rate'] self.close_profit = self.calc_profit() self.close_date = datetime.utcnow() + self.is_open = False + logger.info( + 'Marking %s as closed as the trade is fulfilled and found no open orders for it.', + self + ) else: raise ValueError('Unknown order type: {}'.format(order['type'])) self.open_order_id = None + Trade.session.flush() def calc_profit(self, rate: Optional[float] = None) -> float: """ diff --git a/freqtrade/tests/test_main.py b/freqtrade/tests/test_main.py index ae7402945..32a0bfb0a 100644 --- a/freqtrade/tests/test_main.py +++ b/freqtrade/tests/test_main.py @@ -8,7 +8,7 @@ from sqlalchemy import create_engine from freqtrade.exchange import Exchanges from freqtrade.analyze import SignalType -from freqtrade.main import create_trade, handle_trade, close_trade_if_fulfilled, init, \ +from freqtrade.main import create_trade, handle_trade, init, \ get_target_bid, _process from freqtrade.misc import get_state, State, FreqtradeException from freqtrade.persistence import Trade @@ -183,7 +183,6 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order, mocker): handle_trade(trade) assert trade.open_order_id == 'mocked_limit_sell' - assert close_trade_if_fulfilled(trade) is False # Simulate fulfilled LIMIT_SELL order for trade trade.update(limit_sell_order) @@ -205,20 +204,15 @@ def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order, mo # Create trade and sell it init(default_conf, create_engine('sqlite://')) trade = create_trade(15.0) - trade.update(limit_buy_order) - trade.update(limit_sell_order) - Trade.session.add(trade) - Trade.session.flush() + trade.update(limit_buy_order) trade = Trade.query.filter(Trade.is_open.is_(True)).first() assert trade - # Simulate that there is no open order - trade.open_order_id = None + trade.update(limit_sell_order) + trade = Trade.query.filter(Trade.is_open.is_(False)).first() + assert trade - closed = close_trade_if_fulfilled(trade) - assert closed - assert not trade.is_open with pytest.raises(ValueError, match=r'.*closed trade.*'): handle_trade(trade)