From 057f852e063382a1eef18e6e45ec65d88fc5f22b Mon Sep 17 00:00:00 2001 From: axel Date: Wed, 14 Jun 2023 11:40:30 -0400 Subject: [PATCH] fix localTrade and trade classe miroring, fix persistence tests --- freqtrade/persistence/trade_model.py | 28 +++++++++++++++++++---- tests/conftest_trades.py | 12 +++++----- tests/persistence/test_persistence.py | 32 +++++++++++++-------------- 3 files changed, 46 insertions(+), 26 deletions(-) diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index ead3f7a5d..2525a33ad 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -495,8 +495,10 @@ class LocalTrade(): ) def to_json(self, minified: bool = False) -> Dict[str, Any]: - filled_orders = self.select_filled_or_open_orders() - orders = [order.to_json(self.entry_side, minified) for order in filled_orders] + filled_or_open_orders = self.select_filled_or_open_orders() + orders_json = [order.to_json(self.entry_side, minified) for order in filled_or_open_orders] + open_orders = self.select_open_orders() + open_orders_json = [order.to_json(self.entry_side, minified) for order in open_orders] return { 'trade_id': self.id, @@ -572,11 +574,11 @@ class LocalTrade(): 'is_short': self.is_short, 'trading_mode': self.trading_mode, 'funding_fees': self.funding_fees, - 'open_order_id': self.open_order_id, 'amount_precision': self.amount_precision, 'price_precision': self.price_precision, 'precision_mode': self.precision_mode, - 'orders': orders, + 'orders': orders_json, + 'open_orders': open_orders_json } @staticmethod @@ -1064,6 +1066,16 @@ class LocalTrade(): or (o.ft_is_open is True and o.status is not None) ] + def select_open_orders(self) -> List['Order']: + """ + Finds open orders + :param order_side: Side of the order (either 'buy', 'sell', or None) + :return: array of Order objects + """ + return [o for o in self.orders if + (o.ft_is_open is True and o.status is not None) + ] + @property def nr_of_successful_entries(self) -> int: """ @@ -1317,6 +1329,14 @@ class Trade(ModelBase, LocalTrade): def open_orders(self): return [order for order in self.orders if order.ft_is_open] + @hybrid_property + def open_orders_count(self) -> int: + return len(self.open_orders) + + @hybrid_property + def open_orders_ids(self) -> list: + return [open_order.order_id for open_order in self.open_orders] + def __init__(self, **kwargs): super().__init__(**kwargs) self.realized_profit = 0 diff --git a/tests/conftest_trades.py b/tests/conftest_trades.py index 9642435e5..7a3e893f7 100644 --- a/tests/conftest_trades.py +++ b/tests/conftest_trades.py @@ -46,7 +46,7 @@ def mock_trade_1(fee, is_short: bool): open_date=datetime.now(tz=timezone.utc) - timedelta(minutes=17), open_rate=0.123, exchange='binance', - open_order_id=f'dry_run_buy_{direc(is_short)}_12345', + # open_order_id=f'dry_run_buy_{direc(is_short)}_12345', strategy='StrategyTestV3', timeframe=5, is_short=is_short @@ -103,7 +103,7 @@ def mock_trade_2(fee, is_short: bool): close_profit_abs=-0.005584127 if is_short else 0.000584127, exchange='binance', is_open=False, - open_order_id=f'dry_run_sell_{direc(is_short)}_12345', + # open_order_id=f'dry_run_sell_{direc(is_short)}_12345', strategy='StrategyTestV3', timeframe=5, enter_tag='TEST1', @@ -211,7 +211,7 @@ def mock_trade_4(fee, is_short: bool): is_open=True, open_rate=0.123, exchange='binance', - open_order_id=f'prod_buy_{direc(is_short)}_12345', + # open_order_id=f'prod_buy_{direc(is_short)}_12345', strategy='StrategyTestV3', timeframe=5, is_short=is_short, @@ -328,7 +328,7 @@ def mock_trade_6(fee, is_short: bool): exchange='binance', strategy='SampleStrategy', enter_tag='TEST2', - open_order_id=f"prod_sell_{direc(is_short)}_6", + # open_order_id=f"prod_sell_{direc(is_short)}_6", timeframe=5, is_short=is_short ) @@ -412,7 +412,7 @@ def short_trade(fee): # close_profit_abs=-0.6925113200000013, exchange='binance', is_open=True, - open_order_id='dry_run_exit_short_12345', + # open_order_id='dry_run_exit_short_12345', strategy='DefaultStrategy', timeframe=5, exit_reason='sell_signal', @@ -503,7 +503,7 @@ def leverage_trade(fee): close_profit_abs=2.5983135000000175, exchange='kraken', is_open=False, - open_order_id='dry_run_leverage_buy_12368', + # open_order_id='dry_run_leverage_buy_12368', strategy='DefaultStrategy', timeframe=5, exit_reason='sell_signal', diff --git a/tests/persistence/test_persistence.py b/tests/persistence/test_persistence.py index fcb8771d0..eabb582d1 100644 --- a/tests/persistence/test_persistence.py +++ b/tests/persistence/test_persistence.py @@ -491,11 +491,10 @@ def test_update_market_order(market_buy_order_usdt, market_sell_order_usdt, fee, leverage=1.0, ) - trade.open_order_id = 'mocked_market_buy' oobj = Order.parse_from_ccxt_object(market_buy_order_usdt, 'ADA/USDT', 'buy') trade.orders.append(oobj) trade.update_trade(oobj) - assert trade.open_order_id is None + assert len(trade.open_orders) == 0 assert trade.open_rate == 2.0 assert trade.close_profit is None assert trade.close_date is None @@ -506,11 +505,10 @@ def test_update_market_order(market_buy_order_usdt, market_sell_order_usdt, fee, caplog.clear() trade.is_open = True - trade.open_order_id = 'mocked_market_sell' oobj = Order.parse_from_ccxt_object(market_sell_order_usdt, 'ADA/USDT', 'sell') trade.orders.append(oobj) trade.update_trade(oobj) - assert trade.open_order_id is None + assert len(trade.open_orders) == 0 assert trade.close_rate == 2.2 assert pytest.approx(trade.close_profit) == 0.094513715710723 assert trade.close_date is not None @@ -560,7 +558,7 @@ def test_calc_open_close_trade_price( ) entry_order = limit_order[trade.entry_side] exit_order = limit_order[trade.exit_side] - trade.open_order_id = f'something-{is_short}-{lev}-{exchange}' + # trade.open_order_id = f'something-{is_short}-{lev}-{exchange}' oobj = Order.parse_from_ccxt_object(entry_order, 'ADA/USDT', trade.entry_side) oobj.trade = trade @@ -658,7 +656,7 @@ def test_calc_close_trade_price_exception(limit_buy_order_usdt, fee): leverage=1.0, ) - trade.open_order_id = 'something' + # trade.open_order_id = 'something' oobj = Order.parse_from_ccxt_object(limit_buy_order_usdt, 'ADA/USDT', 'buy') trade.update_trade(oobj) assert trade.calc_close_trade_value(trade.close_rate) == 0.0 @@ -677,7 +675,7 @@ def test_update_open_order(limit_buy_order_usdt): trading_mode=margin ) - assert trade.open_order_id is None + assert len(trade.open_orders) == 0 assert trade.close_profit is None assert trade.close_date is None @@ -685,7 +683,7 @@ def test_update_open_order(limit_buy_order_usdt): oobj = Order.parse_from_ccxt_object(limit_buy_order_usdt, 'ADA/USDT', 'buy') trade.update_trade(oobj) - assert trade.open_order_id is None + assert len(trade.open_orders) == 0 assert trade.close_profit is None assert trade.close_date is None @@ -758,7 +756,7 @@ def test_calc_open_trade_value( is_short=is_short, trading_mode=trading_mode ) - trade.open_order_id = 'open_trade' + # trade.open_order_id = 'open_trade' oobj = Order.parse_from_ccxt_object( limit_buy_order_usdt, 'ADA/USDT', 'sell' if is_short else 'buy') trade.update_trade(oobj) # Buy @ 2.0 @@ -813,7 +811,7 @@ def test_calc_close_trade_price( trading_mode=trading_mode, funding_fees=funding_fees ) - trade.open_order_id = 'close_trade' + # trade.open_order_id = 'close_trade' assert round(trade.calc_close_trade_value(rate=close_rate), 8) == result @@ -1135,7 +1133,7 @@ def test_calc_profit( trading_mode=trading_mode, funding_fees=funding_fees ) - trade.open_order_id = 'something' + # trade.open_order_id = 'something' assert pytest.approx(trade.calc_profit(rate=close_rate)) == round(profit, 8) assert pytest.approx(trade.calc_profit_ratio(rate=close_rate)) == round(profit_ratio, 8) @@ -1330,7 +1328,7 @@ def test_to_json(fee): open_rate=0.123, exchange='binance', enter_tag=None, - open_order_id='dry_run_buy_12345', + # open_order_id='dry_run_buy_12345', precision_mode=1, amount_precision=8.0, price_precision=7.0, @@ -1346,7 +1344,7 @@ def test_to_json(fee): 'is_open': None, 'open_date': trade.open_date.strftime(DATETIME_PRINT_FORMAT), 'open_timestamp': int(trade.open_date.timestamp() * 1000), - 'open_order_id': 'dry_run_buy_12345', + # 'open_order_id': trade.open_orders_count, 'close_date': None, 'close_timestamp': None, 'open_rate': 0.123, @@ -1401,6 +1399,7 @@ def test_to_json(fee): 'price_precision': 7.0, 'precision_mode': 1, 'orders': [], + 'open_orders': [], } # Simulate dry_run entries @@ -1468,7 +1467,7 @@ def test_to_json(fee): 'is_open': None, 'max_rate': None, 'min_rate': None, - 'open_order_id': None, + # 'open_order_id': None, 'open_rate_requested': None, 'open_trade_value': 12.33075, 'exit_reason': None, @@ -1487,6 +1486,7 @@ def test_to_json(fee): 'price_precision': 8.0, 'precision_mode': 2, 'orders': [], + 'open_orders': [], } @@ -2638,7 +2638,7 @@ def test_recalc_trade_from_orders_dca(data) -> None: assert len(trade.orders) == idx + 1 if idx < len(data) - 1: assert trade.is_open is True - assert trade.open_order_id is None + assert len(trade.open_orders) == 0 assert trade.amount == result[0] assert trade.open_rate == result[1] assert trade.stake_amount == result[2] @@ -2652,4 +2652,4 @@ def test_recalc_trade_from_orders_dca(data) -> None: assert not trade.is_open trade = Trade.session.scalars(select(Trade)).first() assert trade - assert trade.open_order_id is None + assert len(trade.open_orders) == 0