From 0a95ef6ab2e0cf369143f7af6be6ee0d2c3d15a5 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 19 May 2022 06:42:38 +0200 Subject: [PATCH] Don't reset open orders in dry-run on restart --- freqtrade/exchange/exchange.py | 6 ++++ freqtrade/persistence/models.py | 15 --------- freqtrade/persistence/trade_model.py | 27 +++++++++++++++ tests/test_persistence.py | 50 ---------------------------- 4 files changed, 33 insertions(+), 65 deletions(-) diff --git a/freqtrade/exchange/exchange.py b/freqtrade/exchange/exchange.py index d2766cd6d..4ee9d3f63 100644 --- a/freqtrade/exchange/exchange.py +++ b/freqtrade/exchange/exchange.py @@ -953,6 +953,12 @@ class Exchange: order = self.check_dry_limit_order_filled(order) return order except KeyError as e: + from freqtrade.persistence import Order + order = Order.order_by_id(order_id) + if order: + x = order.to_ccxt_object() + self._dry_run_open_orders[order_id] = x + return x # Gracefully handle errors with dry-run orders. raise InvalidOrderException( f'Tried to get an invalid dry-run-order (id: {order_id}). Message: {e}') from e diff --git a/freqtrade/persistence/models.py b/freqtrade/persistence/models.py index c31e50892..1e0a70784 100644 --- a/freqtrade/persistence/models.py +++ b/freqtrade/persistence/models.py @@ -64,10 +64,6 @@ def init_db(db_url: str, clean_open_orders: bool = False) -> None: _DECL_BASE.metadata.create_all(engine) check_migrate(engine, decl_base=_DECL_BASE, previous_tables=previous_tables) - # Clean dry_run DB if the db is not in-memory - if clean_open_orders and db_url != 'sqlite://': - clean_dry_run_db() - def cleanup_db() -> None: """ @@ -76,14 +72,3 @@ def cleanup_db() -> None: """ Trade.commit() - -def clean_dry_run_db() -> None: - """ - Remove open_order_id from a Dry_run DB - :return: None - """ - for trade in Trade.query.filter(Trade.open_order_id.isnot(None)).all(): - # Check we are updating only a dry_run order not a prod one - if 'dry_run' in trade.open_order_id: - trade.open_order_id = None - Trade.commit() diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index 358e776e3..57aeda76c 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -118,6 +118,25 @@ class Order(_DECL_BASE): self.order_filled_date = datetime.now(timezone.utc) self.order_update_date = datetime.now(timezone.utc) + def to_ccxt_object(self) -> Dict[str, Any]: + return { + 'id': self.order_id, + 'symbol': self.ft_pair, + 'price': self.price, + 'average': self.average, + 'amount': self.amount, + 'cost': self.cost, + 'type': self.order_type, + 'side': self.ft_order_side, + 'filled': self.filled, + 'remaining': self.remaining, + 'datetime': self.order_date_utc.strftime('%Y-%m-%dT%H:%M:%S.%3f'), + 'timestamp': int(self.order_date_utc.timestamp() * 1000), + 'status': self.status, + 'fee': None, + 'info': {}, + } + def to_json(self, entry_side: str) -> Dict[str, Any]: return { 'pair': self.ft_pair, @@ -190,6 +209,14 @@ class Order(_DECL_BASE): """ return Order.query.filter(Order.ft_is_open.is_(True)).all() + @staticmethod + def order_by_id(order_id: str) -> Optional['Order']: + """ + Retrieve order based on order_id + :return: Order or None + """ + return Order.query.filter(Order.order_id == order_id).first() + class LocalTrade(): """ diff --git a/tests/test_persistence.py b/tests/test_persistence.py index d84415938..8d033663e 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -1129,56 +1129,6 @@ def test_calc_profit( assert pytest.approx(trade.calc_profit_ratio(rate=close_rate)) == round(profit_ratio, 8) -@pytest.mark.usefixtures("init_persistence") -def test_clean_dry_run_db(default_conf, fee): - - # Simulate dry_run entries - trade = Trade( - pair='ADA/USDT', - stake_amount=0.001, - amount=123.0, - fee_open=fee.return_value, - fee_close=fee.return_value, - open_rate=0.123, - exchange='binance', - open_order_id='dry_run_buy_12345' - ) - Trade.query.session.add(trade) - - trade = Trade( - pair='ETC/BTC', - stake_amount=0.001, - amount=123.0, - fee_open=fee.return_value, - fee_close=fee.return_value, - open_rate=0.123, - exchange='binance', - open_order_id='dry_run_sell_12345' - ) - Trade.query.session.add(trade) - - # Simulate prod entry - trade = Trade( - pair='ETC/BTC', - stake_amount=0.001, - amount=123.0, - fee_open=fee.return_value, - fee_close=fee.return_value, - open_rate=0.123, - exchange='binance', - open_order_id='prod_buy_12345' - ) - Trade.query.session.add(trade) - - # We have 3 entries: 2 dry_run, 1 prod - assert len(Trade.query.filter(Trade.open_order_id.isnot(None)).all()) == 3 - - clean_dry_run_db() - - # We have now only the prod - assert len(Trade.query.filter(Trade.open_order_id.isnot(None)).all()) == 1 - - def test_migrate_new(mocker, default_conf, fee, caplog): """ Test Database migration (starting with new pairformat)