1

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( );
}
guagay_wk
  • 26,337
  • 54
  • 186
  • 295

2 Answers2

1

Custom metric needs to be scalar (number), not array. ATR(30) is an array. So, use LastValue to get last value of array or Lookup to get the value at specified bar. 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.EntryPrice );
    }

    // 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.EntryPrice );
    }

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

EDIT: The credit goes to fxshrat who posted the answer at https://forum.amibroker.com/t/unable-to-add-this-custom-metric-to-backtest-report/7153/2 His answer was posted here and it was rude to post without references. Apologies to fxshrat and Tomasz.

guagay_wk
  • 26,337
  • 54
  • 186
  • 295
1

I'm finding it really interesting that you copy text and code solution by others line by line without giving reference.

Your second post here at stackoverflow is line by line copy of responses by Tomasz and me to you at forum.amibroker.com

https://forum.amibroker.com/t/unable-to-add-this-custom-metric-to-backtest-report/7153

fxshrat
  • 89
  • 5
  • Hi fxshrat, it was rude not to leave references. I have edited the original answer to indicate that the credit was yours. I have also upvoted and marked your answer as the answer. The original answer was posted here to leave as reference to others. No intention to take the credit from you. Sorry about it. You can take it as laziness and bad manners to have left out references. I have corrected the bad manners. – guagay_wk Oct 28 '18 at 11:29