fix: Improved migration for short trades

This commit is contained in:
Matthias
2026-02-03 20:33:16 +01:00
parent a9bbc45ba5
commit 35806c26bf
2 changed files with 32 additions and 2 deletions
+20 -1
View File
@@ -119,21 +119,40 @@ def balance_distribution_over_time(
df.loc[trade.open_date : end_date, f"{pair}_leverage"] = trade.leverage df.loc[trade.open_date : end_date, f"{pair}_leverage"] = trade.leverage
df.loc[trade.open_date : end_date, f"{pair}_is_short"] = 1 if trade.is_short else 0 df.loc[trade.open_date : end_date, f"{pair}_is_short"] = 1 if trade.is_short else 0
orders = [o for o in trade.orders if o["order_filled_timestamp"]] orders = [o for o in trade.orders if o["order_filled_timestamp"]]
current_position = 0
current_collateral = 0
for order in sorted(orders, key=lambda x: x["order_filled_timestamp"]): for order in sorted(orders, key=lambda x: x["order_filled_timestamp"]):
filled_at = pd.Timestamp(dt_from_ts(order["order_filled_timestamp"])) filled_at = pd.Timestamp(dt_from_ts(order["order_filled_timestamp"]))
real_amount = order.get("filled", order["amount"]) real_amount = order.get("filled", order["amount"])
stake = order["safe_price"] * real_amount stake = order["safe_price"] * real_amount
stake_no_lev = stake / trade.leverage stake_no_lev = stake / trade.leverage
if order["ft_is_entry"]: if order["ft_is_entry"]:
# Entry order: lock collateral and pay fee
# For both long and short: balance decreases by collateral + fee
fee = stake * trade.fee_open fee = stake * trade.fee_open
current_position += real_amount
current_collateral += stake_no_lev
df.loc[filled_at:end_date, pair] += real_amount df.loc[filled_at:end_date, pair] += real_amount
df.loc[filled_at:end_date, f"{pair}_collateral"] += stake_no_lev df.loc[filled_at:end_date, f"{pair}_collateral"] += stake_no_lev
df.loc[filled_at:, stake_currency] -= stake_no_lev + fee df.loc[filled_at:, stake_currency] -= stake_no_lev + fee
else: else:
# Exit order: release collateral and realize profit/loss
fee = stake * trade.fee_close fee = stake * trade.fee_close
if trade.is_short:
# For SHORT
df.loc[filled_at:, stake_currency] += (
current_collateral * (1 + trade.leverage) - stake
)
current_collateral * (1 + trade.leverage) - stake
else:
# For LONG
df.loc[filled_at:, stake_currency] += stake - current_collateral * (
trade.leverage - 1
)
df.loc[filled_at:end_date, pair] -= real_amount df.loc[filled_at:end_date, pair] -= real_amount
df.loc[filled_at:end_date, f"{pair}_collateral"] -= stake_no_lev df.loc[filled_at:end_date, f"{pair}_collateral"] -= stake_no_lev
df.loc[filled_at:, stake_currency] += stake_no_lev - fee current_position -= real_amount
current_collateral -= stake_no_lev
# Round to avoid floating point issues # Round to avoid floating point issues
df = df.round(14) df = df.round(14)
@@ -1,5 +1,6 @@
import logging import logging
import numpy as np
import pandas as pd import pandas as pd
from freqtrade.constants import Config from freqtrade.constants import Config
@@ -90,7 +91,17 @@ def _prepare_balance_distribution(
index=balance_dist.index, columns=[f"{p}_value" for p in pairlist_valid], dtype=float index=balance_dist.index, columns=[f"{p}_value" for p in pairlist_valid], dtype=float
) )
for p in pairlist_valid: for p in pairlist_valid:
df_value[f"{p}_value"] = balance_dist[f"{p}_open"] * balance_dist[p] # df_value[f"{p}_value"] = balance_dist[f"{p}_open"] * balance_dist[p]
# Identical calculation to rpc and wallets.py
df_value[f"{p}_value"] = np.where(
balance_dist[f"{p}_is_short"] == 0,
(balance_dist[f"{p}_open"] * balance_dist[p])
- balance_dist[f"{p}_collateral"] * (balance_dist[f"{p}_leverage"] - 1),
(
balance_dist[f"{p}_collateral"] * (1 + balance_dist[f"{p}_leverage"])
- balance_dist[f"{p}_open"] * balance_dist[p]
),
)
balance_dist = pd.concat([balance_dist, df_value], axis=1) balance_dist = pd.concat([balance_dist, df_value], axis=1)
# Aggregate total value at each point in time # Aggregate total value at each point in time