Unable to add this custom metric to backtest report

I would like to add an extra column to indicate volatility in the backtest report.

Here is my code. The extra column volatility_recent appears but no value appears in the column. However, if I were to use the commented line trade.AddCustomMetric( "proceeds", trade.Shares*trade.ExitPrice );, some numerical value appears in the column.

What is wrong with the code?

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

	volatility_recent = ATR(30);

    // iterate through closed trades
    for ( trade = bo.GetFirstTrade( ); trade; trade = bo.GetNextTrade( ) )
    {
        trade.AddCustomMetric( "volatility_recent", volatility_recent );
		//trade.AddCustomMetric( "proceeds", trade.Shares*trade.ExitPrice );
    }

    // iterate through open positions
    for ( trade = bo.GetFirstOpenPos( ); trade; trade = bo.GetNextOpenPos( ) )
    {       

        trade.AddCustomMetric( "volatility_recent", volatility_recent );
        //trade.AddCustomMetric( "proceeds", trade.Shares*trade.ExitPrice );
    }

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

Custom metric needs to be scalar (number), not array. ATR(30) is an array. So you would need to use LastValue to get last value of array or Lookup to get the value at specified bar.

2 Likes

As T.J. wrote you need to pass ATR array of symbol from 1st phase to 2nd phase of backtest via static variables. Then in custom metric line use lookup to extract array element at certain date time (trade.EntryDateTime or trade.ExitDateTime).

StaticVarSet( "CBT_ATR_" + Name(), ATR(30) );

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( ) )
    {
        trade.AddCustomMetric( "volatility_recent", Lookup( StaticVarGet( "CBT_ATR_" + trade.Symbol ), trade.ExitDateTime ) );
		//trade.AddCustomMetric( "proceeds", trade.Shares*trade.ExitPrice );
    }

    // iterate through open positions
    for ( trade = bo.GetFirstOpenPos( ); trade; trade = bo.GetNextOpenPos( ) )
    {       

        trade.AddCustomMetric( "volatility_recent", Lookup( StaticVarGet( "CBT_ATR_" + trade.Symbol ), Trade.ExitDateTime ) );
        //trade.AddCustomMetric( "proceeds", trade.Shares*trade.ExitPrice );
    }

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