Could someone please explain how I can get custom stats objects AND create a copy of portfolio equity all in the same formula?

This attempt below did not work.

//
SetCustomBacktestProc(""); 

if( Status("action") == actionPortfolio ) 
{ 
	bo = GetBacktesterObject(); 

    bo.Backtest(); // run default backtest procedure 
    
    st = bo.GetPerformanceStats(0); // get stats for all trades 
    stl = bo.GetPerformanceStats(1); // get stats for long trades
    sts = bo.GetPerformanceStats(2); // get stats for all short trades 
    
    // initialize counter
    stoplossCountLong = stoplossCountShort = 0;

    // iterate through closed trades
    for( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() )
    {
        
      // check for stop-loss exit reason
        if( trade.ExitReason == 2 )
        {
         // increase long or short counter respectively
            if( trade.IsLong() )
                stoplossCountLong++;
            else
                stoplossCountShort++;
        }
    }
    
    //show largest winner
    lwin = st.GetValue("WinnersLargestWin");
    //long trades stats
    lt = stl.GetValue("AllQty");
	lt2 = stl.GetValue("AllAvgProfitLoss");
	lt3 = stl.GetValue("ProfitFactor");
	lt4 = stl.GetValue("CAR/MDD");
	//short trade stats
    sst = sts.GetValue("AllQty");
	sst2 = sts.GetValue("AllAvgProfitLoss");
	sst3 = sts.GetValue("ProfitFactor");
	sst4 = sts.GetValue("CAR/MDD");

    
    // Here we add custom metric to backtest report 
    bo.AddCustomMetric( "# of L", lt);
	bo.AddCustomMetric( "L Avg PL", lt2);
	bo.AddCustomMetric( "L PF", lt3);
	bo.AddCustomMetric( "L CAR/MDD", lt4);
	bo.AddCustomMetric( "# of SS", sst);
	bo.AddCustomMetric( "SS Avg PL", sst2);
	bo.AddCustomMetric( "SS PF", sst3);
	bo.AddCustomMetric( "SS CAR/MDD", sst4);
    bo.AddCustomMetric( "Largest Win", lwin );
    bo.AddCustomMetric( "Stoploss trades", stoplossCountLong + stoplossCountShort, stoplossCountLong, stoplossCountShort, 0 );
}  
//

Buy = Cross( C, MA( C, 20 ) ); // 
Sell = Cross( MA( C, 20 ), C );

//
SetCustomBacktestProc("");
if( Status("action") == actionPortfolio )
{
 bo = GetBacktesterObject();
 bo.Backtest();
 AddToComposite( bo.EquityArray, 
                 "~~~MY_EQUITY_COPY", "X", 
                 atcFlagDeleteValues | atcFlagEnableInPortfolio );
}

Why did you decide to put your AddToComposite( bo.EquityArray... into a separate if() block that runs a second backtest?

bo.Backtest() method obviously can be called only ONCE per one backtest run. So you should not call it twice as you do in your code. To achieve what you want, remove second if() block and move AddToComposite() call inside the first if().

Excellent! Thank you very much for your help.