Is it possible to save equity curves during Optimization?

I can save equity curve during after backtesting, but I'd like to save many of them for different parameter values. Is it possible?

You can use SetOption( "GenerateReport", 1 ) to turn on report generation for every step in optimization. Reports include equity charts. But be warned that report generation in every optimization step takes lots of time and would slow down things very very significantly

2 Likes

Thanks. By saving equity curve I meant saving ~~~EQUITY ticker after each step. And looks like it works, but in kind of mysterious way: when I do optimization, the ticker is not saved (I'm using code similar to http://www.amibroker.com/kb/2006/03/11/how-to-create-copy-of-portfolio-equity/, giving different name to each ticker: "~~~MY_EQUITY_COPY" + parameter ), but then, when I do backetest, all tickers appear at once.

How are you verifying whether the tickers are "saved"? My guess is that the new tickers are being written to the database correctly, but you're not seeing the updates in the Symbols window in real time.

@reuptake Try adding this line to your code

SetOption( "RefreshWhenCompleted", True );
3 Likes

Regardin with the doubt of @reuptake, being similar to an issue I asked for a long time before (I am working with it again, because I didn't solve it yet).

Using the code to get the equity from the KB like @reuptake I get ~~~MY_EQUITY_COPY without problem.

But I can't get ~~~MY_OSEQUITY_COPY. Logically, after doing a walk forward test.

As I told you in that post, I did different tests trying different choices of flags setting in the next instruction:

AddToComposite( Foreign( "~~~OSEQUITY", "C" ), "~~~OSEQUITY ", "X", atcFlagDeleteValues | atcFlagEnableInPortfolio );

but I didn't get the right one OSEQUITY ticker.

Replicating step by step, with the next symple code, what I am getting in case someone could help me.

// SANTIAGO VAZQUEZ 2019
_SECTION_BEGIN("INITIAL VARIABLES");  
SetChartOptions(0, chartShowDates|chartWrapTitle);  
SetOption("EveryBarNullCheck", True);


//INITIAL EQUITY AND COMISSIONS//
SetOption( "initialequity", 100000 ); // starting capital   
SetOption("PriceBoundChecking",1);

OptimizerSetEngine("spso"); 
_SECTION_END();

_SECTION_BEGIN("TRADING SYSTEM");
{
MarginDeposit = 1;
PointValue=50; // SP500 FUTURE (esignal symbol ES #F)
PositionSize = 1;

fast = /*Param*/Optimize("fast", 12, 5, 20, 1 );
slow = /*Param*/Optimize("slow", 26, 10, 25, 1 );

Buy=Cross(MACD(fast,slow),Signal(fast,slow));
Sell=Cross(Signal(fast,slow),MACD(fast,slow)); 

Short= 0;
Cover= 0;

// DELETING EXTRASIGNAL
Buy = ExRem(Buy, Sell OR Short);
Short = ExRem(Short, Cover OR Buy);
Sell = ExRem(Sell, Buy);
Cover = ExRem(Cover, Short);

Plot(C, "Price", colorBlack, styleThick | styleNoTitle | styleBar);
Plot(MACD(fast,slow), "MACD", colorBlue, styleLine+styleLeftAxisScale);
Plot(Signal(fast,slow), "Signal", colorRed, styleLine+styleLeftAxisScale);
}
_SECTION_END();

_SECTION_BEGIN("PLOTTING SIGNALS");
// PLOTTING ACTIVATION SIGNALS
distancia = 3*ATR(14);
for(i=0; i<BarCount; i++)
{
if(Buy[i]) PlotText("buy\n" + BuyPrice[i], i, H[i]-distancia[i], colorGreen );
if(Sell[i] AND !Short[i]) PlotText("sell\n" + SellPrice[i], i, L[i]+distancia[i], colorRed);
if(Short[i]) PlotText("short\n" + ShortPrice[i], i,  L[i]+distancia[i], colorRed);
if(Cover[i] AND !Buy[i]) PlotText("cover\n" + CoverPrice[i], i, H[i]-distancia[i], colorGreen );
}

//PLOTTIN SHAPES//   
PlotShapes(IIf(Buy,shapeUpArrow,shapeNone),colorGreen,0,L,-15);   
PlotShapes(IIf(Buy,shapeHollowCircle,shapeNone),colorGreen,0,BuyPrice,0);   
PlotShapes(IIf(Sell AND !Short,shapeDownArrow,shapeNone),colorRed,0,H,-15);   
PlotShapes(IIf(Sell AND !Short ,shapeHollowCircle,shapeNone),colorRed,0,SellPrice,0);   
PlotShapes(IIf(Short,shapeDownArrow,shapeNone),colorRed,0,H,-15);   
PlotShapes(IIf(Short,shapeHollowCircle,shapeNone),colorRed,0,ShortPrice,0);   
PlotShapes(IIf(Cover AND !Buy,shapeUpArrow,shapeNone),colorGreen,0,L,-15);   
PlotShapes(IIf(Cover AND !Buy,shapeHollowCircle,shapeNone),colorGreen,0,CoverPrice,0);  
_SECTION_END();

// The code for AmiBroker 5.50 and above

SetCustomBacktestProc( "" );

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

_SECTION_END();

I have got the right solution after doing the test twice. In this case, the optimization is fast, but in a normal optimization you would spend more time to do it.
is it possible to add a command to get in the first optimization?
Thank you very much!!

The code you posted is wrong.

You replaced correct line from original article from Knowledge Base (http://www.amibroker.com/kb/2006/03/11/how-to-create-copy-of-portfolio-equity/)

AddToComposite( bo.EquityArray, "~~~MY_EQUITY_COPY", "X", atcFlagDeleteValues | atcFlagEnableInPortfolio );

with INCORRECT line of yours:

AddToComposite( Foreign( "~~~OSEQUITY", "C" ), "~~~OSEQUITY ", "X", atcFlagDeleteValues | atcFlagEnableInPortfolio );

The code is wrong because ~~~OSEQUITY symbol is NOT available when custom backtester is running. It is only available AFTER everything is completed.

2 Likes

First of all, thank you very much for responding...
Yes @Tomasz, I understood. But I would be intersted in getting the OSEQUITY ticker after doing an optimization, because I export this array to use in other application.
Any suggestion?
And thank you very much again.... (I feel a deep admiration for the ability you have with AB...:kissing_closed_eyes::kissing_closed_eyes::kissing_closed_eyes:)

Use Batch processor. It is designed to do such things:
http://www.amibroker.com/guide/h_batch.html

2 Likes