Why i get error "COM/Object handle is null"?

My Main goal is to add a few columns BUT ONLY IN CASE OF BACKTESTING. By OPTIMIZATION it is no neccessary and the optimization is too slowly.

I have tried it with actionBacktest, but why i get error "COM/Object handle is null" ???
With actionPortfolio it works.

COMObjectHandleIsNull

/*******************
* BACKTEST COLUMNS *
********************/
function backtest()
{
	/* Now custom-backtest procedure follows */ 
	if( Status("action") == actionBacktest ) 
	{ 
		SetCustomBacktestProc(""); 

		bo = GetBacktesterObject(); 
		
		if( NOT IsNull(bo) )
		{
			bo.Backtest(1); // run default backtest procedure 

			for( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() ) 
			{
				SetForeign( trade.Symbol );
				myTradeEntryBar = Lookup(BarIndex(),trade.entrydatetime,0);
				todayOpenAt093000 = ValueWhen( TimeNum() == 093000 AND BarIndex() < myTradeEntryBar , O , 1 );
				yesterdayCloseAt155900 = ValueWhen( TimeNum() == 155900 AND BarIndex() < myTradeEntryBar , C , 1 );
				//trade.AddCustomMetric("myTradeEntryBar", myTradeEntryBar, 0 ); 
				trade.AddCustomMetric("gap", abs( todayOpenAt093000[myTradeEntryBar] / yesterdayCloseAt155900[myTradeEntryBar] - 1 ), 6);
				trade.AddCustomMetric("todayOpenAt093000", todayOpenAt093000[myTradeEntryBar] ); 
				trade.AddCustomMetric("yesterdayCloseAt155900", yesterdayCloseAt155900[myTradeEntryBar] );
				trade.AddCustomMetric("Commission", trade.GetCommission());
				trade.AddCustomMetric("Commission / PositionValue", trade.GetCommission() / trade.GetPositionValue(), 8);
			} 

			bo.ListTrades(); 
		}
	}
}

backtest();

Use this instead:

if( Status("action") == actionPortfolio ) 

Additional info is in Porfolio Backtester Interface Reference Guide

… get access to backtester object by calling GetBacktesterObject() method. Note that GetBacktester method should only be called when Status(“action”) returns actionPortfolio:

I know. I have written.
“With actionPortfolio it works.”

But i mean it is not good. I want to use ONLY for backtesting. For optimizing NO!

"
actionBacktest (NOTE backtest only, no optimization)
actionPortfolio (2nd phase of portfolio backtest (custom backtest)
"
https://www.amibroker.com/guide/afl/status.html

@Zoltan When you click the backtest button, your code is executed multiple times with different actions. First will be one or more phase 1 executions (one for each symbol in your watchlist), followed by a single phase 2 execution. If you want to see this, you can add a _Trace statement to the top of your AFL and examine the logs.

_Trace("Status(actionex)=" + Status("actionex") + " Name="+Name() + " stockNum=" + stockNum);

You can only add custom metrics during phase 2 (actionPortfolio). However, you should be able to detect optimization within actionPortfolio and skip the expensive custom metrics. I haven’t tried this code, but it should at least give you the basic idea:

if (Status("action") == actionPortfolio)
{
    bo = GetBacktesterObject();
    if (Status("actionex") != actionExOptimizePortfolio)
    {
        for(trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade())
            trade.AddCustomMetric(...);
    }
}