# ScaleIn/ScaleOut if forecast position is 10% higher/lower than current pos

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.

There's a detailed knowledge base article on the Amibroker site covering how to achieve this.

Note the comment in the code where it uses a 0.5% (0.005) threshold. There you can set it to use your 10% (0.1) threshold instead.

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++)
{

//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 so much for taking a look at it.

You are missing `}` at the bottom of your code.

Tip: Use Edit> Prettify Selection.

1 Like

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 );

//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);

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++ )
{

//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
}

``````