Historical Backtest - change in capital after initial equity

I have used http://www.amibroker.com/kb/2014/09/30/gen-backtest-from-a-file/ to backtest my historical trades. This works well.

I am however looking to see how I can introduce new capital. For instance if my initial equity is $100,000 can I nominate a date to introduce $75,000 equity. This is important for me because if I increase the initial equity to cover all of my trades my stats are misstated - all being judged against that initial equity.

To be clear I give this example:

Initial historical trade date: January 1 2015
Initial equity: $100,000
Date of new equity: September 1, 2015
Additional equity $75,000 [so equity is now at $175,000]

The code I am using is:

// signal-based backtest, redundant (raw) signals are NOT removed,
// MULTIPLE positions per symbol will be open if BUY/SHORT signal is 'true' for more than one bar and there are free funds
// Sell/Cover exit all open positions on given symbol, Scale-In/Out work on all open positions of given symbol at once.
SetBacktestMode( backtestRegularRawMulti ); 


file = "C:\\TEMP\\trades.csv"; // change this to real location of your data 
dt = DateTime();
//
// Initialize variables
SetOption("InitialEquity",175000);
SetOption("MaxOpenPositions",20);

SetTradeDelays (0,0,0,0);
Buy = Sell = possize = 0; 
//
fh = fopen( file, "r" );
//
if( fh )
 {
     while( ! feof( fh ) )
     {
         line = fgets( fh );
         // get the ticker symbol from the file
         sym = StrExtract( line, 0 );
         // if ticker matches current symbol
         if ( Name() == sym )
         {
             // extract data from line of text
             trade = StrExtract( line, 1 );
             trade_datetime = StrToDateTime( StrExtract( line, 2 ) );
             price = StrToNum( StrExtract( line, 3 ) );
             shares = StrToNum( StrExtract( line, 4 ) );
             //
             if ( trade == "Buy" )
             {
                 newbuy = dt == trade_datetime;
                 Buy = Buy OR newbuy; // combine previous buy signals with new
                 BuyPrice = IIf( newbuy, price, BuyPrice );
                 possize = IIf( newbuy, shares, possize );
             }
             //
             if ( trade == "Sell" )
             {
                 newsell = dt == trade_datetime;
                 Sell = Sell OR newsell; // combine previous sell signals with new
                 SellPrice = IIf( newsell, price, SellPrice );
             }
         }
     }
     //
     fclose( fh );
 }
 else
 {
     Error( "ERROR: file can not be open" );
 }
//
SetPositionSize( possize, spsShares ); 

I have looked at this post. Dionysos has provided some code - however as per the final post it goes to profit rather than to equity.

So not what I need.

Buy = Sell = Short = Cover = 0; 

SetCustomBacktestProc("");

if (Status("action") == actionPortfolio) 
{
    bo = GetBacktesterObject();	//  Get backtester object
   
    bo.PreProcess();	//  Do pre-processing (always required)
	
    for (i = 0; i < BarCount; i++)	//  Loop through all bars
    {
        bo.ProcessTradeSignals( i );	//  Process trades at bar (always required)
        addfunds= DateNum()==1000301;//
        if(addfunds[i])
			{
				bo.Cash = bo.Cash + 15000; 
			}
 
        
    }	  
      
    bo.PostProcess();	//  Do post-processing (always required)
}

Equity = Cash + Market Value of Open Positions

bo.cash += 10000; 

$10,000 goes to Cash.
which can be used to open a new position or scale-in an existing one :

bo.cash += 10000; 
bo.EnterTrade(...);
bo.ScaleTrade(...);

@CNHTractor is correct that the value you add to cash will be counted as “profit” at the end of the back test, because total profit is simply Final Equity - Initial Equity. Therefore, it will affect CAR and other metrics. The only way to get around that is to recalculate metrics of interest on your own, removing the effect of the cash additions.

it affects the metrics, certainly: CAR/MDD, CAR, etc.

The process still works though, adding and taking out cash, then rebalancing. I’m just wondering if in a low level CBT you could calc the stats first, then add cash.

BTW it was aron that helped with the code.

I need to work on other things, so just some food for thought.

Dio

Buy = Sell = Short = Cover = 0;

SetCustomBacktestProc( "" );

if( Status( "action" ) == actionPortfolio )
{
    bo = GetBacktesterObject();	
    bo.PreProcess();	
    Total = 0;     // track total of cash additions
    myequity = GetOption( "initialequity" );  // equity I want to track 
    addcash = mtRandomA() < 0.3;

    for( i = 0; i < BarCount; i++ )	//  Loop through all bars
    {
      
        if( addcash [i] )
        {
            bo.Cash += 10000;
            total += 10000;
        }

           _TRACEf( "%.f\t%.f" , bo.Equity, myequity );


        bo.ProcessTradeSignals( i );  // updates equity

        myequity = bo.Equity - total ;  // update myequity

       
    }

    bo.PostProcess();	
}

2 Likes

You probably should use AccountMargin option.
Instead of adding $75,000 cash increase the positon sizes by $75,000

so this one tracks "myequity" in the sense that it would show the "true" money made regardless of the additions:

nice one! Thanks for pointing out that solution aron. Much appreciated.

image

If you want to be able to calculate things like Drawdown, Sharpe Ratio, etc. then you would need to keep track of myEquity as an array rather than as a single value. Even then, many of your metrics will be skewed by the fact that your position sizes are larger due to the increased working capital. It all boils down to determining which metrics are of use to you, and then how to make them as accurate as possible.