tradingstrategy-ai / trade-executor

A Python framework for managing positions and trades in DeFi
https://tradingstrategy.ai
Other
91 stars 25 forks source link

`calculate_compounding_realised_trading_profitability` doesn't work with concurrent open positions #795

Open AlexTheLion123 opened 4 months ago

AlexTheLion123 commented 4 months ago

Steps to reproduce

  1. Add the following code cell to this notebook after the backtest is run:
from tradeexecutor.visual.benchmark import visualise_long_short_benchmark
from tradeexecutor.visual.equity_curve import calculate_long_compounding_realised_trading_profitability, calculate_compounding_realised_trading_profitability
from plotly import graph_objects as go
import pandas as pd

compounding = calculate_compounding_realised_trading_profitability(state)

initial_cash = 10_000
series2 = []
for p in state.stats.portfolio:
    pnl = (p.total_equity-initial_cash)/initial_cash
    series2.append((p.calculated_at, pnl))
times, values = zip(*series2)
equity = pd.Series(values, index=times)

trace1 = go.Scatter(
    x=compounding.index,
    y=compounding.values,
    mode='lines'
)

trace2 = go.Scatter(
    x=equity.index,
    y=equity.values,
    mode='lines'
)

fig = go.Figure()
fig.add_trace(trace1)
fig.add_trace(trace2)
fig.show()
  1. Run the notebook and notice how the two curves don't match as they should

Image

  1. Now go to the strategy and make sure it can only have 1 open position at a time. By changing to these lines:
signal_locked = False
has_been_opened = False

def decide_trades:
   ...

      global signal_locked
      global has_been_opened

      if signal_locked == True and position_manager.is_any_open():
          has_been_opened = True

      if has_been_opened == True and not position_manager.is_any_open():
          signal_locked = False
          has_been_opened = False

      if signal_locked == False:
          if momentum >= positive_mometum_threshold:
              signal_locked = True
              alpha_model.set_signal(
                  pair,
                  momentum,
                  stop_loss=stop_loss,
                  take_profit=take_profit,
              )
          elif momentum <= negative_mometum_threshold:
              if strategy_universe.can_open_short(timestamp, pair):
                  # Only open a short if we have lending markets available at this point
                  signal_locked = True
                  alpha_model.set_signal(
                      pair,
                      momentum,
                      stop_loss=stop_loss,
                      take_profit=take_profit,
                      leverage=1.0,
                  )
          else:
              # Momentum is ~0,
              # not worth of a signal
              pass
  1. Also change the trading cycle and time bucket to 1 hour for more trades

  2. Run the original notebook and notice how the two curves line up much closer.

Screenshot from 2024-02-16 11-20-41

AlexTheLion123 commented 4 months ago

Changing to P1 since this is the only way to calculate profit for live strategies

AlexTheLion123 commented 1 month ago

Concurrent open positions no longer allowed