From 314c017dd358ff7fb9f41f2ab7fdefd643a1914d Mon Sep 17 00:00:00 2001 From: Matthias Date: Sun, 16 Feb 2025 13:27:42 +0100 Subject: [PATCH] feat: enable trade.from_json to import backtested trades --- freqtrade/persistence/trade_model.py | 72 +++++++++++++++------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index c08dcb13b..ad347715c 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -1535,45 +1535,47 @@ class LocalTrade: :param json_str: json string to parse :return: Trade instance """ + from uuid import uuid4 + import rapidjson data = rapidjson.loads(json_str) trade = cls( __FROM_JSON=True, - id=data["trade_id"], + id=data.get("trade_id"), pair=data["pair"], - base_currency=data["base_currency"], - stake_currency=data["quote_currency"], + base_currency=data.get("base_currency"), + stake_currency=data.get("quote_currency"), is_open=data["is_open"], - exchange=data["exchange"], + exchange=data.get("exchange", "import"), amount=data["amount"], - amount_requested=data["amount_requested"], + amount_requested=data.get("amount_requested", data["amount"]), stake_amount=data["stake_amount"], - strategy=data["strategy"], + strategy=data.get("strategy"), enter_tag=data["enter_tag"], - timeframe=data["timeframe"], + timeframe=data.get("timeframe"), fee_open=data["fee_open"], - fee_open_cost=data["fee_open_cost"], - fee_open_currency=data["fee_open_currency"], + fee_open_cost=data.get("fee_open_cost"), + fee_open_currency=data.get("fee_open_currency"), fee_close=data["fee_close"], - fee_close_cost=data["fee_close_cost"], - fee_close_currency=data["fee_close_currency"], + fee_close_cost=data.get("fee_close_cost"), + fee_close_currency=data.get("fee_close_currency"), open_date=datetime.fromtimestamp(data["open_timestamp"] // 1000, tz=timezone.utc), open_rate=data["open_rate"], - open_rate_requested=data["open_rate_requested"], - open_trade_value=data["open_trade_value"], + open_rate_requested=data.get("open_rate_requested", data["open_rate"]), + open_trade_value=data.get("open_trade_value"), close_date=( datetime.fromtimestamp(data["close_timestamp"] // 1000, tz=timezone.utc) if data["close_timestamp"] else None ), - realized_profit=data["realized_profit"], + realized_profit=data.get("realized_profit", 0), close_rate=data["close_rate"], - close_rate_requested=data["close_rate_requested"], - close_profit=data["close_profit"], - close_profit_abs=data["close_profit_abs"], + close_rate_requested=data.get("close_rate_requested", data["close_rate"]), + close_profit=data.get("close_profit", data.get("profit_ratio")), + close_profit_abs=data.get("close_profit_abs", data.get("profit_abs")), exit_reason=data["exit_reason"], - exit_order_status=data["exit_order_status"], + exit_order_status=data.get("exit_order_status"), stop_loss=data["stop_loss_abs"], stop_loss_pct=data["stop_loss_ratio"], initial_stop_loss=data["initial_stop_loss_abs"], @@ -1581,11 +1583,11 @@ class LocalTrade: min_rate=data["min_rate"], max_rate=data["max_rate"], leverage=data["leverage"], - interest_rate=data["interest_rate"], - liquidation_price=data["liquidation_price"], + interest_rate=data.get("interest_rate"), + liquidation_price=data.get("liquidation_price"), is_short=data["is_short"], - trading_mode=data["trading_mode"], - funding_fees=data["funding_fees"], + trading_mode=data.get("trading_mode"), + funding_fees=data.get("funding_fees"), amount_precision=data.get("amount_precision", None), price_precision=data.get("price_precision", None), precision_mode=data.get("precision_mode", None), @@ -1597,23 +1599,25 @@ class LocalTrade: amount=order["amount"], ft_amount=order["amount"], ft_order_side=order["ft_order_side"], - ft_pair=order["pair"], - ft_is_open=order["is_open"], - order_id=order["order_id"], - status=order["status"], - average=order["average"], + ft_pair=order.get("pair", data["pair"]), + ft_is_open=order.get("is_open", False), + order_id=order.get("order_id", uuid4().hex), + status=order.get("status"), + average=order.get("average", order.get("safe_price")), cost=order["cost"], - filled=order["filled"], - order_date=datetime.strptime(order["order_date"], DATETIME_PRINT_FORMAT), + filled=order.get("filled", order["amount"]), + order_date=datetime.strptime(order["order_date"], DATETIME_PRINT_FORMAT) + if order.get("order_date") + else None, order_filled_date=( datetime.fromtimestamp(order["order_filled_timestamp"] // 1000, tz=timezone.utc) if order["order_filled_timestamp"] else None ), - order_type=order["order_type"], - price=order["price"], - ft_price=order["price"], - remaining=order["remaining"], + order_type=order.get("order_type"), + price=order.get("price", order.get("safe_price")), + ft_price=order.get("price", order.get("safe_price")), + remaining=order.get("remaining", 0.0), funding_fee=order.get("funding_fee", None), ft_order_tag=order.get("ft_order_tag", None), ) @@ -1677,7 +1681,7 @@ class Trade(ModelBase, LocalTrade): stake_amount: Mapped[float] = mapped_column(Float(), nullable=False) # type: ignore max_stake_amount: Mapped[float | None] = mapped_column(Float()) # type: ignore amount: Mapped[float] = mapped_column(Float()) # type: ignore - amount_requested: Mapped[float | None] = mapped_column(Float()) # type: ignore + equested: Mapped[float | None] = mapped_column(Float()) # type: ignore open_date: Mapped[datetime] = mapped_column( # type: ignore nullable=False, default=datetime.now )