I am testing a long only EOD continuous trading system that provides a score indicating the number of shares I should hold, daily.
Rather than trade daily, which is too expensive, I need to scale in/scale out only when today´s forecast position size (no. of shares) is 10%+ above/below my existing (previous) position size.
I have read the pyramiding guide https://www.amibroker.com/guide/h_pyramid.html, plus reviewed numerous examples in the forum but can’t figure out a solution. I hint that going the CBT route might be an option but I am afraid I don’t have the required coding skills for that.
Any guidance would be much appreciated.
Thank you very much MacAllan for your help. Since my position size is based on number of shares instead of percent of equity, I have tweaked the code in the example, but I am not very confident with my changes tbh. Also, I get the following error and can't execute it as it currently is:
"Condition in IF, WHILE, FOR statements
has to be Numeric or Boolean type.
You can not use array here,
please use [] (array subscript operator)
to access array elements"
Here is the tweaked code:
Score = 1130; // This is just an example, in reality I'll use a formula to calculate the //desired number of shares
Setpositionsize(Score, spsShares);
SetOption("UseCustomBacktestProc", True );
if( Status("action") == actionPortfolio )
{
bo = GetBacktesterObject();
bo.PreProcess(); // Initialize backtester
for(bar=0; bar < BarCount; bar++)
{
bo.ProcessTradeSignals( bar );
//CurEquity = bo.Equity; // I don't think I need this as I use number of shares
for( pos = bo.GetFirstOpenPos(); pos; pos = bo.GetNextOpenPos() )
{
posval = pos.GetPositionValue();
price = pos.GetPrice( bar, "C" );
shares = posval/price; // Calculate the number of shares held currently
diff = Score / shares; // Desired shared divided by current shares
// rebalance only if difference between desired and
// current number of shares is greater than 10% ->ScaleIn
// or number of shares is lower than -10% ->ScaleOut
if( diff != 0 AND
abs( diff ) > 1.1 OR abs( diff ) < 0.9)
{
bo.ScaleTrade( bar, pos.Symbol, diff < 0, price, abs( diff ) ); // I don't understand this so can´t say if I need to change anything
}
}
}
bo.PostProcess(); // Finalize backtester
Thank you TrendSurfer, yes I have now corrected a couple errors and added the full code using some simplified rules for this example. The CBT part is the one where I am having trouble as it does neither scale in nor scale out, it just sells the whole position.
// I want to scalein/scaleout if desired number of shares projected is 10%+ above/below my current share holding
InitialEquity= 100000;
NumPosic= 20;
SetOption("MaxOpenLong",NumPosic);
SetOption("MaxOpenPositions",NumPosic);
SetOption("ExtraColumnsLocation",1);
SetOption("CommissionMode",1); //
SetOption("CommissionAmount", 0.0); // No commisions for this example
SetOption("InitialEquity", InitialEquity);
SetOption( "AllowSameBarExit", False );
SetOption( "ReverseSignalForcesExit", False );
SetOption( "HoldMinBars", 1 );
SetOption( "AccountMargin", 100 );
SetTradeDelays(0,0,0,0); // No delays
BuyPrice=ShortPrice=SellPrice=CoverPrice= C;
//Number of Shares desired (example)
score = MA(C, 20)-MA(C, 40);
PositionScore = score;
SharesDesired = 0.001 * InitialEquity / ATR(20); // I leave InitialEquity rather than Equity in order to simply things for this example
SetPositionSize(SharesDesired, spsShares);
// BUY AND SELL EXECUTION
Buy = Score > 0;
Sell = Score < 0;
//SCALEIN SCALEOUT BASED ON FORUM GUIDANCE
SetOption( "UseCustomBacktestProc", True );
if( Status( "action" ) == actionPortfolio )
{
bo = GetBacktesterObject();
bo.PreProcess(); // Initialize backtester
for( bar = 0; bar < BarCount; bar++ )
{
bo.ProcessTradeSignals( bar );
//CurEquity = bo.Equity;
for( pos = bo.GetFirstOpenPos(); pos; pos = bo.GetNextOpenPos() )
{
posval = pos.GetPositionValue();
//diff = posval - 0.01 * EachPosPercent * CurEquity;
price = pos.GetPrice( bar, "C" );
shares = posval / price; // Calculate the number of shares held currently
diff = SharesDesired[ bar ] / shares;
// scale in if difference between number of shares desired and number of current shares held is > 10%
// scale out if difference between number of shares desired and number of current shares held is < 10%
if( diff != 0 AND
abs( diff ) > 1.1 OR
abs( diff ) < 0.9 ) //
//abs( diff ) > price )
{
bo.ScaleTrade( bar, pos.Symbol, diff < 0, price, abs( diff ) ); // I don´t know what this does or if it makes any sense
}
}
}
bo.PostProcess(); // Finalize backtester
}