Add a Column of Equity at Entry Date on Backtest report

Hi guys,

So I have been trying to add a Column that shows Equity value at the Entry Date for every trade in Backtest Report including closed and open trades, but I have been unable to do so.

Can someone please help? I don't think it should be this hard, but I have been looking around and while I can use StaticVarSet for symbols on metrics that use properties such as C, H, L, O, and V, I cannot use StaticVarSet to generate equity line.

Thank you all for your help!

Here is my current CBT code. What should I add to my current CBT code to see such result?

return1 = (C*0.5+O*0.1+H*0.2+L*0.2);
thanhkhoan = return1*Volume;
thanhkhoan1=Ref(thanhkhoan ,-1);
thanhkhoanbq10=MA(thanhkhoan1 ,10);
thanhkhoanbq20=MA(thanhkhoan1 ,20); //Gia tri giao dich TB 20 phien
Max_buy = thanhkhoanbq20 / 10; //10% of GTGD 20 phien
precision = 0;

tkbq20 = Prec(thanhkhoanbq20, precision );
mb20 = Prec(Max_buy, precision );
volprec = Prec(V, precision );
 
StaticVarSet( "mkt_vol" + Name(), tkbq20 );
StaticVarSet( "max_buy" + Name(), mb20 );
StaticVarSet( "Van_Tharp" + Name(), PctSize);
StaticVarSet( Name() + "liquidity", tkbq20 ); //Display
StaticVarSet( Name() + "max_entry", mb20 ); //Display
StaticVarSet( Name() + "10% Volume", volprec/10); //Display

limit_daily_entries = 1;

SetCustomBacktestProc( "" );
if ( Status( "action" ) == actionPortfolio )
{
    // retrieving portfolio backtester interface
    bo = GetBacktesterObject();  
    bo.PreProcess();
	
    for ( i = 0; i < BarCount; i++ )        
    {   // iterating through all trade signals and adjust pos size
        count = 0;
        eq[i] = bo.Equity;
        
        for ( sig = bo.GetFirstSignal( i ); sig; sig = bo.GetNextSignal( i ) ) 
		{	
			if( sig.IsEntry() && sig.IsLong() ) 
            {	
				if ( count < limit_daily_entries ) //limit = 1
				{	
					count ++;  
					Max_buy1 = StaticVarGet( "max_buy" + sig.Symbol );
					Van_Tharp = StaticVarGet( "Van_Tharp" + sig.Symbol );
					Max_buy_portion[i] = Max_buy1[i]/eq[i]*100;    
					sig.PosSize = -Min(Van_Tharp[i],Max_buy_portion[i]); 
				}
				else
					sig.Price = -1; //ignore entry signal
			} 	//Close the if Entry loop		
        } 	//Close the sig loop
		bo.ProcessTradeSignals( i );    
	}	//  End of for loop over bars i
	
	for(trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade())
	{
		// read Vol values and display as custom metric
        symbol_liquidity = StaticVarGet( trade.Symbol + "liquidity" );
        symbol_maxentry = StaticVarGet( trade.Symbol + "max_entry" );
        symbol_vol = StaticVarGet( trade.Symbol + "10% Volume" );
        symbol_VanTharp = StaticVarGet( "Van_Tharp" + trade.Symbol );
        //symbol_7 = StaticVarGet( trade.Symbol + "7% Trailing" ); 
        trade.AddCustomMetric( "PosSize", Lookup( symbol_VanTharp, trade.EntryDateTime ) );
        trade.AddCustomMetric( "GTGD (trieu)", Lookup( symbol_liquidity, trade.EntryDateTime ) );
        trade.AddCustomMetric( "Max Buy (trieu)", Lookup( symbol_maxentry, trade.EntryDateTime) );
        trade.AddCustomMetric( "Max Buy (shares)", Lookup( symbol_vol, trade.EntryDateTime) );
        //trade.AddCustomMetric( "7% Trailing", Lookup( symbol_7, trade.EntryDateTime) );
	}	//Close loop for closed trades
	
	for ( trade = bo.GetFirstOpenPos( ); trade; trade = bo.GetNextOpenPos( ) )
    {
        // read ATR values and display as custom metric
        symbol_liquidity = StaticVarGet( trade.Symbol + "liquidity" );
        symbol_maxentry = StaticVarGet( trade.Symbol + "max_entry" );
        symbol_vol = StaticVarGet( trade.Symbol + "10% Volume" );
        symbol_VanTharp = StaticVarGet( "Van_Tharp" + trade.Symbol );
        //symbol_7 = StaticVarGet( trade.Symbol + "7% Trailing" );
        trade.AddCustomMetric( "PosSize", Lookup( symbol_VanTharp, trade.EntryDateTime ) );
        trade.AddCustomMetric( "GTGD (trieu)", Lookup( symbol_liquidity, trade.EntryDateTime ) );
        trade.AddCustomMetric( "Max Buy (trieu)", Lookup( symbol_maxentry, trade.EntryDateTime) );
        trade.AddCustomMetric( "Max Buy (shares)", Lookup( symbol_vol, trade.EntryDateTime) ); 
        //trade.AddCustomMetric( "7% Trailing", Lookup( symbol_7, trade.EntryDateTime) );
    }	//Close loop for open trades
    	
    bo.PostProcess();
} 

Hi,

you can use this template as a guide but it's simpler because equity is already available directly from the backtester (no need for static variables) : https://www.amibroker.com/kb/2014/11/20/how-to-show-indicator-values-in-backtest-trade-list/

Example:

SetCustomBacktestProc( "" );

if ( Status( "action" ) == actionPortfolio )
{
    bo = GetBacktesterObject();
    // run default backtest procedure without generating the trade list
    bo.Backtest( True );

    // iterate through closed trades
    for ( trade = bo.GetFirstTrade( ); trade; trade = bo.GetNextTrade( ) )
    {
       
      equityvalue = Lookup( bo.EquityArray, trade.EntryDateTime );
	  trade.AddCustomMetric( "Equity", equityvalue );
          
    }

    // iterate through open positions
    for ( trade = bo.GetFirstOpenPos( ); trade; trade = bo.GetNextOpenPos( ) )
    {
       
      equityvalue = Lookup( bo.EquityArray, trade.EntryDateTime );
	  trade.AddCustomMetric( "Equity", equityvalue );
    }

    // generate trade list
    bo.ListTrades( );
}

// your trading system here
Buy = Cross( MACD(), Signal() );
Sell = Cross( Signal(), MACD() );


1 Like

Done! I nailed it. Thank you so much @pmxgs. Here is the solution for everyone:

SetCustomBacktestProc( "" );
if ( Status( "action" ) == actionPortfolio )
{
    // retrieving portfolio backtester interface
    bo = GetBacktesterObject();
    bo.PreProcess();
    
	for(trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade())
	{
        equityvalue = Lookup( bo.EquityArray, trade.EntryDateTime );
	    trade.AddCustomMetric( "Equity", equityvalue );
       
	}	//Close loop for closed trades
	
	for (trade = bo.GetFirstOpenPos( ); trade; trade = bo.GetNextOpenPos( ))
    {
        equityvalue = Lookup( bo.EquityArray, trade.EntryDateTime );
		trade.AddCustomMetric( "Equity", equityvalue );
    }	//Close loop for open trades
    
    bo.PostProcess();
} 

It works fine on Mid level CBT too!

1 Like

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.