How To - Use Optimize Value In Custom Metrics

Continuing the discussion from Optimization Using Multiple Indicators:

How can we retrieve the Optimize value from the Optimize Result Report?
Basically:

myVar = Optimize("MA_Short",5,5,10,1);

The Optimize report will now have a column heading named "MA_Short"
I want to use the value in this column to add another custom metric.
Using the Backtest Object (or something elsel) how can the value for each optimization run be grammatically retrieved?

As Nike would say: “Just Do It!”. The value you’re looking for is already assigned to myVar. You can use myVar throughout both the Phase 1 AFL and the CBT.

1 Like

@mradtke From what I can test, your suggestion does not work for me.
Basically, during the Status(“action”) == actionPortfolio phase, we need to retrieve a dynamic variable that was initially set in the back test / optimize section of code. I’ll post the sandbox here in case anyone can devise a way to get this to work!

/// @link http://forum.amibroker.com/t/optimization-using-multiple-indicators/3690/10
/// code response suggestion by fxshrat
condnum = 3;// number of conditions to be combined.

comb = Optimize("CombinationNum", 1, 1, 2^condnum, 1); //Optimize(Descr, Default, Min, Max, Step) 

Buy1 = Cross( C, MA( C, 50 ) );
Buy2 = Cross( 30, RSI() );
Buy3 = Cross( MACD(), Signal() );


SetCustomBacktestProc("");

/* Now custom-backtest procedure follows */

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

    bo.Backtest(); // run default backtest procedure
    
    //stats = bo.GetPerformanceStats(0); // get stats for all trades 
    //Comb = stats.GetValue("CombinationNum"); // This line does not work
    
    // Here we add custom metric to backtest report
    bo.AddCustomMetric( "Signals In Use", VarGetText("Signal_"+Comb));
    _TRACE("AFL Valued for COMB at custom metric is "+comb);
}

BuySum = 0;
_TRACE("AFL Execution Combination = " + comb);

for (n = 0; n < condnum; n++)
	{
	BuySum += IIf((comb & 2^n), VarGet("Buy" + (n+1)), 1); 
	
    //Proof that the combination is being used
    if (IIf((comb & 2^n), true, false))
       {_TRACE("AFL using " +  "Buy_"+ (n+1));
         VarSetText("Signal_"+comb, VarGetText("Signal_"+comb)+ " Buy_"+ (n+1));
       }
    }
    
    
Buy = BuySum == condnum;

Sell = 0; 
Short = Cover = 0;

As mradtke said, you can use optimized parameter values in your phase 2 code without doing anything special. The reason your code is not working is because dynamic variables cannot be shared between phase 1 between phase 2. One possible solution is to use static variables.

@steve Thank you! I modified the code to use Static Variables and I am now able to add the custom metrics for each Optimize Scenario. In this case, I am optimizing for every possible combination of indicators (or Buy Signals). The custom metric is the “Signals In Use” column. This column shows exactly which buy signals (or technical indicators) are in use for Optimize each scenario. Thank you to everyone that assisted, including @mradtke, @fxshrat, @beppe and @bursaware.

Here is the latest edition of sandbox code, initially posted by @fxshrat here I am using to insert my custom metric values into the Optimization Result Report:

/// @link http://forum.amibroker.com/t/optimization-using-multiple-indicators/3690/10
/// code response suggestion by fxshrat
/// code modify by SwingTrader
condnum = 3;// number of conditions to be combined.

comb = Optimize("CombinationNum", 1, 1, 2^condnum, 1); //Optimize(Descr, Default, Min, Max, Step) 

Buy1 = Cross( C, MA( C, 50 ) );
Buy2 = Cross( 30, RSI() );
Buy3 = Cross( MACD(), Signal() );



SetCustomBacktestProc("");

/* Now custom-backtest procedure follows */

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

    bo.Backtest(); // run default backtest procedure
    
    //stats = bo.GetPerformanceStats(0); // get stats for all trades 
    //Comb = stats.GetValue("CombinationNum"); // This line does not work
    
    // Here we add custom metric to backtest report
    bo.AddCustomMetric( "Signals In Use", staticVarGetText("Signal_"+Comb));
    _TRACE("AFL Valued for COMB at custom metric is "+comb);
   
}


StaticVarRemove("Signal_*");
BuySum = 0;
_TRACE("AFL Execution Combination = " + comb);

for (n = 0; n < condnum; n++)
	{
	BuySum += IIf((comb & 2^n), VarGet("Buy" + (n+1)), 1); 
	
    //Proof that the combination is being used
    if (IIf((comb & 2^n), true, false))
       {_TRACE("AFL using " +  "Buy_"+ (n+1));
        StaticVarSetText("Signal_"+comb, StaticVarGetText("Signal_"+comb)+ " Buy_"+ (n+1));
       }
    }   
    
    
Buy = BuySum == condnum;

Sell = 0; 
Short = Cover = 0;

You’ve mixed up a couple of things. @mradtke was correct in first place and his reply is actual solution. Simply put comb variable assigned via Optimize is available in both first and second phase without doing anything and without need to use static variables. Static variables are only needed to transfer (other) values from first phase to second phase, but not the optimization parameter itself which is readily available without doing anything. Optimize function always returns current optimization parameter value.

@Tomas, I understand. I am actually using static variables to transfer other information (the Buy indicator combination in use) from the first phase to the second phase. It is during the second phase that I publish the custom metric that contains the indicators that were in use for a particular optimization run.