Backtest from file and synthetic tickers

Hello, I am importing discretionary option trades from a CSV file into AmiBroker. Each trade contains:

  • Entry date
  • Exit date
  • Final PnL (in $)

To backtest this, I simulate trades on a synthetic symbol with constant price = 100. For each trade:

  • Buy at 100 on entry
  • Sell at a price adjusted so that the final PnL matches the known result., I.e for a $500 profit: sellprice = 105, 1 contract, pointvalue = 100
    Trade statistics are correct. However, the portfolio equity curve is step-shaped because the synthetic price remains flat during the trade and changes only on exit, so the entire PnL is booked at the exit bar.

What I want instead is linear mark-to-market allocation of the known final PnL across the trade duration. Example:

  • Profit = +500
  • Duration = 5 bars
  • Desired behavior: +100 per bar increase in equity until exit.

What I tried:

  1. Modifying synthetic prices (creating a ramp)
    → Affects chart but does NOT affect portfolio equity in the HTML report.
  2. Custom Backtest Procedure:
  • Running standard portfolio processing
  • Iterating open positions
  • Distributing profit per bar
  • Modifying bo.Cash during the trade
  • Reversing the accumulated adjustment at exit

This partially works but:

  • Modifying bo.Cash gives inconsistencies in the equity (the way I tried)
  • The HTML report seems to use internal engine equity arrays that may not be writable.

Questions:

  1. Is portfolio equity (used in the standard HTML report) writable or overridable from CBT? I mean directly, not via positionsize
  2. Is there a way to alter mark-to-market behavior of open positions?
  3. Is there a way to distribute final trade profit across its lifetime instead of booking it fully at exit?

I do NOT want to change final trade results — only the intra-trade equity path.

Thank you.

Thanks Tomasz, I’m already using that file-based backtest code. My question is different: can portfolio equity (MTM path) be modified during an open trade without affecting the trades themselves?

Create synthetic price for every day and you will be fine without doing anything special.

1 Like

I tried that approach. It changed prices (see pic) but it did not change the equity. It seems that the backtester is using the database prices instead of synthetic prices. Should I force those prices with addtocomposite or something similar? Thanks

// ====== Linear synthetic price within the trade (for linear equity) ======
inTrade = Flip( Buy, Sell );

// "Anchor" prices of the trade
EntryP = ValueWhen( Buy,  BuyPrice );
ExitP  = ValueWhen( Sell, SellPrice );   // Note: this is the exit price of the trade

// Total bars in the trade (measured at the exit bar)
TotalBars = ValueWhen( Sell, BarsSince( Buy ) );

// Progress in bars since entry (0..TotalBars)
k = BarsSince( Buy );

// Avoid division by zero and NULLs
TotalBars = IIf( TotalBars > 0, TotalBars, 1 );

// Linear interpolation
lin = EntryP + (ExitP - EntryP) * ( k / TotalBars );

// Final price to use
synthetic = Nz( IIf( inTrade, lin, 100 ), 100 );

// Coherent OHLC
O = H = L = C = synthetic;

This is NOT how do you change prices.

The OHLC arrays that you see in the formula are COPIES of actual data, you are NOT modifying actual prices in the database. You are operating on COPIES.

You can create synthetic tickers using AddToComposite. This way you will create ACTUAL DATA in the database.
So you should FIRST create synthetic tickers using AddToComposite AND THEN backtest on synthetic tickers.

1 Like