Help with StaticVarGet()

Hi to everyone,
i have a problem with StaticVarSet and GET.

pctPosSize = ABC/PosQty;
pctPosSizeLast = LastValue(pctPosSize);

StaticVarSet("ABpctPosSizeLast", pctPosSizeLast);

Filter = 1;
AddColumn(StaticVarGet("ABpctPosSizeLast"),"pctPosSizeLast",1.3);

"ABpctPosSizeLast" is correctly set and when i try to get it in exploration, it works.

Then i go in custom backtester to write my equity curve in a csv.

fh = fopen("C:\\Temp\\ABEquity" +  ".csv", "w");
	hdr = "Date,Equity\n";
	fputs(hdr,fh);
	
    // Create a modified equity curve that uses the daily gains
    modEq[0] = initEq;
    dt = DateTime();
    for (i=1; i<BarCount; ++i)
    {
		modEq[i] = modEq[i-1] * dailyGain[i];
		
		line =  NumToStr(dt[i], formatDateTime)+",";
		line += NumToStr(eq[i], 1.2, false);  //+",";
		line += "\n";
		fputs(line,fh);
    }
	  
    line = "\npctPosSize: " + StaticVarGet("ABpctPosSizeLast") +"\n";
    fputs(line,fh);
    fclose(fh);

Everything works ok, but when in the last line i try to get the same StaticVar "ABpctPosSizeLast" , i always get zero.

The CBT runs in the Second phase of BT on the Symbol ~~~Equity.

In the 1st phase, the Formula is run on each symbol.
You will have to store the variable as variable+Name() (which is the symbol) and access it in the same way in the CBT block if you want unique variable per symbol else the variable will just get overwritten by the last symbol that accessed it.

In your case it is unclear as to what exact analysis settings you are using but i'm sure about the last symbol part that accesses it last.

Also i'm not sure whether you intend to maintain unique per symbol values or like a StaticVarAdd() which can add(subtract or update) the same variable in a multi-thread run.

In multithread mode, how can we guarantee without some kind of extra locking code which is the symbol that will set the variable last.

Thanks nsm51.
I apply backtest to a single symbol ("current").
I guess that your intuition (the variable got overwritten) could be true but for now haven't found a solution.

There are two types of backtest, individual and portfolio. Which one are you using?

actionPortfolio this code block is specific i think to Portfolio BT but it doesn't make sense to run portfolio BT on a single symbol ?
so you need to sort that out and in Porfolio BT, the symbol being run on is ~~~Equity in 2nd phase from where you are accessing.

@Heisenberg,

Your code is incomplete. Please create fully re-producible examples without guessing work that are actually usable by users, but not code that creates (lots of) syntax errors because of missing code/variables. It is you looking for help. Help is supposed to be efficient and being finished after short number of posts without much back and forth (-> optimal help).

In case pctPosSize is type number then you do not need LastValue at all.


You do not need CBT to calculate daily gains of equity (no matter if single symbol or portfolio). Also you do not need loop to create cum product / relative performance.

You're right, here is fully re-producible example.

Portfolio = 1;  				// 1 = Portfolio, 0 = All Trades 
SameBarExit = 0;				// 1 = allow same bar exit, 0 = disallow
EntryTiming = 0; 				//  0 = Same Bar on Close, 1 = Next Bar at Open
ExitTiming = 0; 				//  0 = Same Bar on Close, 1 = Next Bar at Open
PosQty = 1; 
Margin = 100;


target = 20;
vola = 100 * ((StDev(log(C/Ref(C,-1)) * sqrt(252) , 15)));
lev = IIf(target/vola>1,1,target/vola) * 100;
pctPosSize = lev/PosQty * 100/Margin;
pctPosSizeLast = LastValue(pctPosSize);

StaticVarSet("ABpctPosSizeLast", pctPosSizeLast);

Filter = 1;
AddColumn(pctPosSize,"ABpctPosSizeLast",1.3);
AddColumn(StaticVarGet("ABpctPosSizeLast"),"pctPosSizeLast",1.3);



SetOption("InitialEquity",IIf(Portfolio,10*1000,100*1000));                   
SetOption("CommissionMode",1);              
SetOption("CommissionAmount",IIf(Portfolio, 0.01, 0)); 
SetOption("AllowSameBarExit", SameBarExit);
SetOption("MaxOpenPositions",IIf(Portfolio,PosQty,2500));                
SetOption("AccountMargin",IIf(Portfolio,Margin,100));                   
SetOption("UsePrevBarEquityForPosSizing",IIf(EntryTiming==0,False,True)); 
SetOption("AllowPositionShrinking", True);   
SetTradeDelays(EntryTiming,ExitTiming,EntryTiming,ExitTiming);                             
SetOption("ActivateStopsImmediately", IIf(ExitTiming==0,False,True)); 
SetPositionSize(IIf(Portfolio,pctPosSize,1),IIf(Portfolio,spsPercentOfEquity,spsShares)); 
RoundLotSize = IIf(Portfolio,1,1); 

Buy = Sell = Short = Cover = 0;
AvgPrice = (H+L)/2;
BuyPrice = ShortPrice = IIf(EntryTiming==0,C,AvgPrice);
SellPrice = CoverPrice = IIf(ExitTiming==0,C,AvgPrice);

BUY = C>MA(C,200) ;
SELL = C<MA(C,200) ;



SetOption("UseCustomBacktestProc", True ); 
if( Status("action") == actionPortfolio ) 
{ 
	
    bo = GetBacktesterObject(); 
    bo.PreProcess(); 
    for( bar = 0; bar < BarCount; bar++ ) 
    { 
         Cnt = 0; 
        
         for( sig = bo.GetFirstSignal( bar ); sig; sig = bo.GetNextSignal( bar ) ) 
         { 
         } 
 
         bo.ProcessTradeSignals( bar ); 
      
         
     } 
    bo.PostProcess(); 
    
    eq = bo.EquityArray();
    initEq = GetOption("InitialEquity");
    prevEq = Ref(eq,-1);
    prevEq[0] = initEq;
    dailyGain = eq /prevEq;	// NOTE: a 4% profit would make dailyGain = 1.04
    
	fh = fopen("C:\\Temp\\ABEquity" + ".csv", "w");
	hdr = "Date,Equity\n";
	fputs(hdr,fh);
	
    // Create equity curve that uses the daily gains
    modEq[0] = initEq;
    dt = DateTime();
    for (i=1; i<BarCount; ++i)
    {
		modEq[i] = modEq[i-1] * dailyGain[i];
		
		line =  NumToStr(dt[i], formatDateTime)+",";
		line += NumToStr(eq[i], 1.2, false);  //+",";
		line += "\n";
		fputs(line,fh);
    }
    
	poslast = StaticVarGet("ABpctPosSizeLast");  
	//_TRACE("poslast: = "+poslast);
    line = "\npctPosSize: " + poslast  +"\n";
    fputs(line,fh);
    fclose(fh);
    
    
} 













As you see position size varies proportionally with the volatility of the instrument.

What i want is "simply" to write in a CSV file the equity curve (day by day) and, in the last row (of the CSV file) i want write the last value of the position size. For last value i mean the one that i should use for tomorrow trading.

As I said you do not need CBT for that and no looping.
You can just use Explorer after backtest (See batch to do all at once).
Also AmiBroker batch has option to export result list to file.

In example I used percentage gain as output but you can also use just Equity.
(As aside... why do you calculate daily gain and then multiply it to equity again if you already have equity (array)?)

Portfolio = 1;  				// 1 = Portfolio, 0 = All Trades 
SameBarExit = 0;				// 1 = allow same bar exit, 0 = disallow
EntryTiming = 0; 				//  0 = Same Bar on Close, 1 = Next Bar at Open
ExitTiming = 0; 				//  0 = Same Bar on Close, 1 = Next Bar at Open
PosQty = 1; 
Margin = 100;

target = 20;
vola = 100 * ((StDev(log(C/Ref(C,-1)) * sqrt(252), 15)));
ratio = target/(vola+1e-9);
lev = IIf(ratio>1,1,ratio) * 100;
pctPosSize = lev/PosQty * 100/Margin;
pctPosSizeLast = LastValue(pctPosSize);

//StaticVarSet("ABpctPosSizeLast", pctPosSizeLast);

explore = Status( "action" ) == actionExplore;
indicator = Status( "action" ) == actionIndicator;
if ( explore OR indicator ) {
	eq = Foreign( "~~~Equity", "C", 1 );
	first = NullCount(eq);
	modEq = 100 * (eq - eq[ first ]) / eq[ first ];
	// OR use
	//modEq = eq;		
	
	//SetOption("NoDefaultColumns", 1);
	SetSortColumns(1, 2);

	Filter = NOT IsNull(eq);
	//AddColumn(DateTime(), "Date", formatDateTime);
	AddColumn(modEq,"modEq (%)",1.3);
	//AddColumn(pctPosSize,"ABpctPosSizeLast",1.3);
	//AddColumn(StaticVarGet("ABpctPosSizeLast"),"pctPosSizeLast",1.3);
	AddRow(StrFormat("%s_pctPosSize: %g", Name(), floor(LastValue(pctPosSize))));
	
	Plot( eq, "Equity", colorRed );
	Plot( modEq, "Rel. Performance of Equity", colorGold, styleOwnScale );
}

SetOption("InitialEquity",IIf(Portfolio,10*1000,100*1000));                   
SetOption("CommissionMode",1);              
SetOption("CommissionAmount",IIf(Portfolio, 0.01, 0)); 
SetOption("AllowSameBarExit", SameBarExit);
SetOption("MaxOpenPositions",IIf(Portfolio,PosQty,2500));                
SetOption("AccountMargin",IIf(Portfolio,Margin,100));                   
SetOption("UsePrevBarEquityForPosSizing",IIf(EntryTiming==0,False,True)); 
SetOption("AllowPositionShrinking", True);   
SetTradeDelays(EntryTiming,ExitTiming,EntryTiming,ExitTiming);                             
SetOption("ActivateStopsImmediately", IIf(ExitTiming==0,False,True)); 
SetPositionSize(IIf(Portfolio,pctPosSize,1),IIf(Portfolio,spsPercentOfEquity,spsShares)); 
RoundLotSize = IIf(Portfolio,1,1); 

Buy = Sell = Short = Cover = 0;
AvgPrice = (H+L)/2;
BuyPrice = ShortPrice = IIf(EntryTiming==0,C,AvgPrice);
SellPrice = CoverPrice = IIf(ExitTiming==0,C,AvgPrice);

BUY = C>MA(C,200) ;
SELL = C<MA(C,200) ;

13

2 Likes

Thank you fxshrat, your solution (Explorer + Batch) is simple and effective.
Let me explain why i I had decided to use CBT.

My ultimate goal is to export multiple equity curve (CSV files) each containing the equity curves corresponding to different parameters.
Now a reproducible example:

Portfolio = 1;  				// 1 = Portfolio, 0 = All Trades 
SameBarExit = 0;				// 1 = allow same bar exit, 0 = disallow
EntryTiming = 0; 				//  0 = Same Bar on Close, 1 = Next Bar at Open
ExitTiming = 0; 				//  0 = Same Bar on Close, 1 = Next Bar at Open
PosQty = 1; 
Margin = 100;


target = Optimize("Target",20,5,40,1);
vola = 100 * ((StDev(log(C/Ref(C,-1)) * sqrt(252) , 15)));
lev = IIf(target/vola>1,1,target/vola) * 100;
pctPosSize = lev/PosQty * 100/Margin;
pctPosSizeLast = LastValue(pctPosSize);

StaticVarSet("ABpctPosSizeLast", pctPosSizeLast);
StaticVarSet("Target", target);

Filter = 1;
AddColumn(pctPosSize,"ABpctPosSize",1.3);
AddColumn(StaticVarGet("ABpctPosSizeLast"),"pctPosSizeLast",1.3);
AddColumn(StaticVarGet("Target"),"target",1.3);




SetOption("InitialEquity",IIf(Portfolio,100*1000,100*1000));                   
SetOption("CommissionMode",1);              
SetOption("CommissionAmount",IIf(Portfolio, 0.01, 0)); 
SetOption("AllowSameBarExit", SameBarExit);
SetOption("MaxOpenPositions",IIf(Portfolio,PosQty,2500));                
SetOption("AccountMargin",IIf(Portfolio,Margin,100));                   
SetOption("UsePrevBarEquityForPosSizing",IIf(EntryTiming==0,False,True)); 
SetOption("AllowPositionShrinking", True);   
SetTradeDelays(EntryTiming,ExitTiming,EntryTiming,ExitTiming);                             
SetOption("ActivateStopsImmediately", IIf(ExitTiming==0,False,True)); 
SetPositionSize(IIf(Portfolio,pctPosSize,1),IIf(Portfolio,spsPercentOfEquity,spsShares)); 
RoundLotSize = IIf(Portfolio,1,1); 

Buy = Sell = Short = Cover = 0;
AvgPrice = (H+L)/2;
BuyPrice = ShortPrice = IIf(EntryTiming==0,C,AvgPrice);
SellPrice = CoverPrice = IIf(ExitTiming==0,C,AvgPrice);

BUY = C>MA(C,200) ;
SELL = C<MA(C,200) ;



SetOption("UseCustomBacktestProc", True ); 
if( Status("action") == actionPortfolio ) 
{ 
	
    bo = GetBacktesterObject(); 
    bo.PreProcess(); 
    for( bar = 0; bar < BarCount; bar++ ) 
    { 
         Cnt = 0; 
        
         for( sig = bo.GetFirstSignal( bar ); sig; sig = bo.GetNextSignal( bar ) ) 
         { 
         } 
 
         bo.ProcessTradeSignals( bar ); 
      
         
     } 
    bo.PostProcess(); 
    
    eq = bo.EquityArray();
    initEq = GetOption("InitialEquity");
    prevEq = Ref(eq,-1);
    prevEq[0] = initEq;
    dailyGain = eq /prevEq;	
    
	fh = fopen("C:\\Temp\\ABEquity" + StaticVarGet("Target") + ".csv", "w");
	hdr = "Date,Equity\n";
	fputs(hdr,fh);
	
    // Create equity curve that uses the daily gains
    modEq[0] = initEq;
    dt = DateTime();
    for (i=1; i<BarCount; ++i)
    {
		modEq[i] = modEq[i-1] * dailyGain[i];
		
		line =  NumToStr(dt[i], formatDateTime)+",";
		line += NumToStr(eq[i], 1.2, false);  //+",";
		line += "\n";
		fputs(line,fh);
    }
    
	poslast = StaticVarGet("ABpctPosSizeLast");  
	//_TRACE("poslast: = "+poslast);
    line = "\npctPosSize: " + poslast  +"\n";
    fputs(line,fh);
    fclose(fh);
    
    
}

As you can see in the TEMP folder there are different CSVs.
The ultimate goal is to integrate all those equity curves (37 CSV files) into just one. With all equity curves allined in just one sheet.

To do this I thought of using r, in particular this example:
https://medium.com/@niharika.goel/merge-multiple-csv-excel-files-in-a-folder-using-r-e385d962a90a

But I also wanted to explore the possibility of exporting all the equity curves aligned in a single CSV directly with amibroker.
To do this, if there is a possibility, I assumed that CBT was the only possibility.
Step by step i was studying how to do that.

So you did not provide all information. Now it turns out it is optimization and you do not want to export single equity per symbol but multiple ones.

Why do you guys not provide everything at start? Almost 10 posts with back and forth. That's what I meant how it should not be.

Please read here first.

Anyway... also there you do not need barcount loop.
To export multiple equities of optimization side by side you just need same procedure as I have described before but with some code change (which would not have been necessary if full info would have been there in the beginning).

/// @link https://forum.amibroker.com/t/help-with-staticvarget/19723/8
Portfolio = 1;  				// 1 = Portfolio, 0 = All Trades 
SameBarExit = 0;				// 1 = allow same bar exit, 0 = disallow
EntryTiming = 0; 				//  0 = Same Bar on Close, 1 = Next Bar at Open
ExitTiming = 0; 				//  0 = Same Bar on Close, 1 = Next Bar at Open
PosQty = 1; 
Margin = 100;

target = Optimize("Target",20,5,40,1);
vola = 100 * ((StDev(log(C/Ref(C,-1)) * sqrt(252), 15)));
ratio = target/(vola+1e-9);
lev = IIf(ratio>1,1,ratio) * 100;
pctPosSize = lev/PosQty * 100/Margin;
pctPosSizeLast = LastValue(pctPosSize);

SetOption("InitialEquity",IIf(Portfolio,10*1000,100*1000));                   
SetOption("CommissionMode",1);              
SetOption("CommissionAmount",IIf(Portfolio, 0.01, 0)); 
SetOption("AllowSameBarExit", SameBarExit);
SetOption("MaxOpenPositions",IIf(Portfolio,PosQty,2500));                
SetOption("AccountMargin",IIf(Portfolio,Margin,100));                   
SetOption("UsePrevBarEquityForPosSizing",IIf(EntryTiming==0,False,True)); 
SetOption("AllowPositionShrinking", True);   
SetTradeDelays(EntryTiming,ExitTiming,EntryTiming,ExitTiming);                             
SetOption("ActivateStopsImmediately", IIf(ExitTiming==0,False,True)); 
SetPositionSize(IIf(Portfolio,pctPosSize,1),IIf(Portfolio,spsPercentOfEquity,spsShares)); 
RoundLotSize = IIf(Portfolio,1,1); 

Buy = Sell = Short = Cover = 0;
AvgPrice = (H+L)/2;
BuyPrice = ShortPrice = IIf(EntryTiming==0,C,AvgPrice);
SellPrice = CoverPrice = IIf(ExitTiming==0,C,AvgPrice);

BUY = C>MA(C,200) ;
SELL = C<MA(C,200) ;

/// first run optimization
/// then run explore
/// (export result list to file)
/// @link https://forum.amibroker.com/t/help-with-staticvarget/19723/9
/// added by fxshrat
explore = Status( "action" ) == actionExplore;
indicator = Status( "action" ) == actionIndicator;
if ( explore OR indicator ) {
	eq = Foreign( "~~~Equity", "C", 1 );
	
	SetSortColumns(1);	
	SetOption("NoDefaultColumns", 1);

	Filter = NOT IsNull(eq);
	
	AddColumn(DateTime(), "Date", formatDateTime);
	str = "";
	// iterating optimization min/max 
	for ( i = 5; i <= 40; i++) {
		modEq = StaticVarGet("Equity_"+i);
		AddColumn(modEq,"modEq_"+i,1.3);
		psz = StaticVarGet("ABpctPosSizeLast"+i);
		str += StrFormat("%g\t", psz);
		//Plot( modEq, "modEq_"+i, colorRed );
	}
	AddRow(StrFormat("%s_pctPosSize:\t%s", Name(), str));	
}
if ( Status("actionex") == actionExOptimizeBacktest )
	StaticVarSet("ABpctPosSizeLast"+target, pctPosSizeLast);
//
SetCustomBacktestProc( "", True );
if ( Status( "action" ) == actionPortfolio ) {
    bo = GetBacktesterObject();
    bo.Backtest();    
    StaticVarSet( "Equity_"+target, bo.EquityArray() );
}

As you can see below multiple equities aligned side by side ready for export (either via File - Export... or via batch).

No R and no other non sense required.

14

1 Like

I have received your instructions, next time I will directly expose the final objective.
The intentions were good because through the resolution of an intermediate problem I was confident of being able to generalize and arrive at the definitive solution on my own. But I realize that the forum is not a school. As said next time I will go directly to the final goal.

My final objective was create a table like yours, but with multiple optimizations variables.
I tryied to generalize with 3 optimization variables and this is the results:

/// @link https://forum.amibroker.com/t/help-with-staticvarget/19723/8
Portfolio = 1;  				// 1 = Portfolio, 0 = All Trades 
SameBarExit = 0;				// 1 = allow same bar exit, 0 = disallow
EntryTiming = 0; 				//  0 = Same Bar on Close, 1 = Next Bar at Open
ExitTiming = 0; 				//  0 = Same Bar on Close, 1 = Next Bar at Open
PosQty = 1; 
Margin = 100;

target = Optimize("Target",20,5,40,1);
irsi = Optimize("RSI",20,5,30,1);
ima = Optimize("Mavg",200,10,300,20);

vola = 100 * ((StDev(log(C/Ref(C,-1)) * sqrt(252), 15)));
ratio = target/(vola+1e-9);
lev = IIf(ratio>1,1,ratio) * 100;
pctPosSize = lev/PosQty * 100/Margin;
pctPosSizeLast = LastValue(pctPosSize);

SetOption("InitialEquity",IIf(Portfolio,1000*1000,100*1000));                   
SetOption("CommissionMode",1);              
SetOption("CommissionAmount",IIf(Portfolio, 0.00, 0)); 
SetOption("AllowSameBarExit", SameBarExit);
SetOption("MaxOpenPositions",IIf(Portfolio,PosQty,2500));                
SetOption("AccountMargin",IIf(Portfolio,Margin,100));                   
SetOption("UsePrevBarEquityForPosSizing",IIf(EntryTiming==0,False,True)); 
SetOption("AllowPositionShrinking", True);   
SetTradeDelays(EntryTiming,ExitTiming,EntryTiming,ExitTiming);                             
SetOption("ActivateStopsImmediately", IIf(ExitTiming==0,False,True)); 
SetPositionSize(IIf(Portfolio,pctPosSize,1),IIf(Portfolio,spsPercentOfEquity,spsShares)); 
RoundLotSize = IIf(Portfolio,1,1); 

Buy = Sell = Short = Cover = 0;
AvgPrice = (H+L)/2;
BuyPrice = ShortPrice = IIf(EntryTiming==0,C,AvgPrice);
SellPrice = CoverPrice = IIf(ExitTiming==0,C,AvgPrice);

BUY = C>MA(C,ima) OR RSI(14) < irsi ;
SELL = C<MA(C,ima) ;

/// first run optimization
/// then run explore
/// (export result list to file)
/// @link https://forum.amibroker.com/t/help-with-staticvarget/19723/9
/// added by fxshrat
explore = Status( "action" ) == actionExplore;
indicator = Status( "action" ) == actionIndicator;
if ( explore OR indicator ) {
	eq = Foreign( "~~~Equity", "C", 1 );
	
	SetSortColumns(1);	
	SetOption("NoDefaultColumns", 1);

	Filter = NOT IsNull(eq);
	
	AddColumn(DateTime(), "Date", formatDateTime);
	str = "";
	// iterating optimization min/max 

for( y = 10; y <= 300; y = y + 20 )
{
    for( z = 5; z <= 30; z++ )
    {
        for( i = 5; i <= 40; i++ )
        {
            modEq = StaticVarGet( "Equity_" + i );
            AddColumn( modEq, "modEq_" + i +"_" + z +"_" + y, 1.3 );
            psz = StaticVarGet( "ABpctPosSizeLast" +i +z +y);
            str += StrFormat( "%g\t", psz );
            //Plot( modEq, "modEq_"+i, colorRed );
        }
    }
}
	AddRow(StrFormat("%s_pctPosSize:\t%s", Name(), str));	
}
if ( Status("actionex") == actionExOptimizeBacktest )
	StaticVarSet("ABpctPosSizeLast" +target +irsi +ima, pctPosSizeLast);
//
SetCustomBacktestProc( "", True );
if ( Status( "action" ) == actionPortfolio ) {
    bo = GetBacktesterObject();
    bo.Backtest();    
    StaticVarSet( "Equity_"+target+irsi+ima, bo.EquityArray() );
}

I think that everithing is ok but the static var set "ABpctPosSizeLast".
Something wrong goes there.

Dear @Heisenberg,

Every new post of yours with new information.
Now it's three optimzation variables and triple loop to call 3 optimization variables' parameters.
You really know how to keep people busy.

There are a few mistakes:
You forgot to add full variable name to StaticVarGet("Equity_....
Then you should rather add underscore to all variable names.

As for

It's because StrFormat function has string length limit (it seems to be 1,000 characters).
You did not say (sounds familiar, doesn't it :wink: ) that you intend to output more than 14,000(!!!) equity curves side by side. So if one value has 7 characters then you end up with string length of around 100k characters + 14,000 column separators. So the length of the second string being inserted to AddRow's StrFormat function is simply getting cut by StrFormat early on.

As you can see here if opening the exported CSV file in Excel
15

If putting the final string variable outside of StrFormat then it is not cut.
As you can see here.
16

BTW, I changed Exploration Filter to lastbarinrange .... imagine if your symbol would have Barcount of 10,000 and code having 14,000 optimization steps... so you would end up with 10k * 14k = 140 million cells if outputting everything.

In addition I have reduced start and end of optimization in below update. Increase at your own risk.

/// @link https://forum.amibroker.com/t/help-with-staticvarget/19723/8
Portfolio = 1;  				// 1 = Portfolio, 0 = All Trades 
SameBarExit = 0;				// 1 = allow same bar exit, 0 = disallow
EntryTiming = 0; 				//  0 = Same Bar on Close, 1 = Next Bar at Open
ExitTiming = 0; 				//  0 = Same Bar on Close, 1 = Next Bar at Open
PosQty = 1; 
Margin = 100;

target = Optimize("Target", 10, start1=5, end1=10, step1=1);
irsi = Optimize("RSI", 10, start2=5, end2=10, step2=1);
ima = Optimize("Mavg", 100, start3=10, end3=100, step3=20);

vola = 100 * ((StDev(log(C/Ref(C,-1)) * sqrt(252), 15)));
ratio = target/(vola+1e-9);
lev = IIf(ratio>1,1,ratio) * 100;
pctPosSize = lev/PosQty * 100/Margin;
pctPosSizeLast = LastValue(pctPosSize);

SetOption("InitialEquity",IIf(Portfolio,1000*1000,100*1000));                   
SetOption("CommissionMode",1);              
SetOption("CommissionAmount",IIf(Portfolio, 0.00, 0)); 
SetOption("AllowSameBarExit", SameBarExit);
SetOption("MaxOpenPositions",IIf(Portfolio,PosQty,2500));                
SetOption("AccountMargin",IIf(Portfolio,Margin,100));                   
SetOption("UsePrevBarEquityForPosSizing",IIf(EntryTiming==0,False,True)); 
SetOption("AllowPositionShrinking", True);   
SetTradeDelays(EntryTiming,ExitTiming,EntryTiming,ExitTiming);                             
SetOption("ActivateStopsImmediately", IIf(ExitTiming==0,False,True)); 
SetPositionSize(IIf(Portfolio,pctPosSize,1),IIf(Portfolio,spsPercentOfEquity,spsShares)); 
RoundLotSize = IIf(Portfolio,1,1); 

Buy = Sell = Short = Cover = 0;
AvgPrice = (H+L)/2;
BuyPrice = ShortPrice = IIf(EntryTiming==0,C,AvgPrice);
SellPrice = CoverPrice = IIf(ExitTiming==0,C,AvgPrice);

BUY = C>MA(C,ima) OR RSI(14) < irsi ;
SELL = C<MA(C,ima) ;

/// first run optimization
/// then run explore
/// (export result list to file)
/// @link https://forum.amibroker.com/t/help-with-staticvarget/19723/11
/// vrs 1.3 added by fxshrat
explore = Status( "action" ) == actionExplore;
indicator = Status( "action" ) == actionIndicator;
if ( explore OR indicator ) {
	SetSortColumns(1);	
	SetOption("NoDefaultColumns", 1);
	
	AddColumn(DateTime(), "Date", formatDateTime, -1, -1, 120);
	str = "";
	// iterating optimization min/max 
	for ( y = start3; y <= end3; y += step3 ) {
		for ( z = start2; z <= end2; z += step2 ) {
			for ( i = start1; i <= end1; i += step1 )	{
				izy_str = "" + i +"_" + z +"_" + y;
				modEq = StaticVarGet( "Equity_" + izy_str);
				AddColumn( modEq, "modEq_" + izy_str, 1.3 );
				psz = StaticVarGet( "ABpctPosSizeLast_" + izy_str);
				str += StrFormat("%1.1f\t",psz);
				//Plot( modEq, "modEq_"+i, colorRed );
			}
		}
	}
	AddRow(StrFormat("%s_pctPosSize:\t", Name()) + str);	
	
	Filter = Status("lastbarinrange");
	//Filter = NOT IsNull(modEq);	 
}
//
if ( Status("actionex") == actionExOptimizeBacktest )
	StaticVarSet("ABpctPosSizeLast_"+target +"_"+irsi +"_"+ima, pctPosSizeLast);
//
SetCustomBacktestProc( "", True );
if ( Status( "action" ) == actionPortfolio ) {
    bo = GetBacktesterObject();
    bo.Backtest();    
    StaticVarSet( "Equity_"+target +"_"+irsi +"_"+ima, bo.EquityArray() );
}
4 Likes

Thank you fxshrat.
I've tried with 5400 combinations for now and everything seems to be ok. I can view all of the columns in Amibroker and copy\paste them in excel.
I will try with more combinations to see how far can i go.