Scaleout. Did I do it right?

i have attempted to scaleout in my code. However i dont know how to read the data properly. for eg in the highlighted report, i notice only part of it is exitted. it could be my misunderstanding. can someone help me read thsi report?

I am scaling out based on the code in line numbers 215-223

SetOption( "MaxOpenPositions", 5 ); // This sets maximum number of open positions to 5


SetChartOptions( 0, chartShowArrows | chartShowDates );
_N( Title = StrFormat( "{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) Vol " + WriteVal( V, 1.0 ) + " {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ) );
//https://www.raoufx.com/trading%20with%20ichimoku%20clouds%20the%20essential%20guide%20to%20ichimoku%20kinko%20hyo%20technical%20analysis.pdf
Plot( C, "Close", colorDefault, styleNoTitle | GetPriceStyle() );
_SECTION_BEGIN( "Tenkan-Sen" );
TenkanPer = Param( "Tenkan-Sen Period", 9, 1, 100, 1 );
TenkanCol = ParamColor( "Tenkan-Sen Color", colorRed );
TenkanSty = ParamStyle( "Tenkan-Sen Style", styleLine | styleThick );
Tenkan = ( HHV( H, TenkanPer ) + LLV( L, TenkanPer ) ) / 2;
Plot( Tenkan, "Tenkan", TenkanCol, TenkanSty );
_SECTION_END();

_SECTION_BEGIN( "Kijun-Sen" );
KijunPer = Param( "Kijun-Sen Period", 22, 1, 100, 1 ); // using 22 instead of 26 as there are only 22 trading days in a month.
KijunCol = ParamColor( "Kijun-Sen Color", colorBlue );
KijunSty = ParamStyle( "Kijun-Sen Style", styleLine | styleThick );
Kijun = ( HHV( H, KijunPer ) + LLV( L, KijunPer ) ) / 2;
Plot( Kijun, "Kijun", KijunCol, KijunSty );
_SECTION_END();

_SECTION_BEGIN( "Chikou Span" );
ChikouShft = Param( "Chikou Span Shift", 22, 1, 100, 1 ); // using 22 instead of 26 as there are only 22 trading days in a month.
ChikouCol = ParamColor( "Chikou Span Color", colorViolet );
ChikouSty = ParamStyle( "Chikou Span Style", styleLine | styleNoLabel );
Chikou = C;
Plot( Chikou, "", ChikouCol, ChikouSty, Null, Null, -ChikouShft );
_SECTION_END();

_SECTION_BEGIN( "Senkou-Kumo" );
SenkouKumoShft = Param( "Senkou-Kumo Shift", 21, 0, 100, 1 );
_SECTION_END();

_SECTION_BEGIN( "Senkou Span A" );
SenkouACol = ParamColor( "Senkou Span A Color", colorSeaGreen );
SenkouASty = ParamStyle( "Senkou Span A Style", styleLine );
SenkouA = ( Tenkan + Kijun ) / 2;
Plot( SenkouA, "Senkou A", SenkouACol, SenkouASty, Null, Null, SenkouKumoShft ) ;
_SECTION_END();

_SECTION_BEGIN( "Senkou Span B" );
SenkouBPer = Param( "Senkou Span B Period", 42, 1, 200, 1 );
SenkouBCol = ParamColor( "Senkou Span B Color", colorPink );
SenkouBSty = ParamStyle( "Senkou Span B Style", styleLine );
SenkouB = ( HHV( H, SenkouBPer ) + LLV( L, SenkouBPer ) ) / 2;
Plot( SenkouB, "Senkou B", SenkouBCol, SenkouBSty, Null, Null, SenkouKumoShft ) ;
_SECTION_END();

_SECTION_BEGIN( "Kumo" );
KumoUpCol = ParamColor( "Kumo UP Color", colorSeaGreen );
KumoDnCol = ParamColor( "Kumo DN Color", colorPink );
PlotOHLC( SenkouA, SenkouA, SenkouB, SenkouB, "", IIf( SenkouA > SenkouB, KumoUpCol, KumoDnCol ), styleCloud | styleNoLabel, Null, Null, SenkouKumoShft );
_SECTION_END();
// need to fiture out how many HH7 i got since the Tenkan < Kijun and how many since Tenkan > Kijun
// i need to take the first HH7 signal.
// optimize the target ranges
ATRTargetRange = 3.5; //Optimize("ATRTargetRange",2,.1,5,.1);
MaxBarsAFterSignal = Optimize( "MaxBarsAfterSignal", 3, 1, 5, 1 );
VolumeMA = Optimize( "VolumeMA", 1.2, .7, 5, .1 );
RANGE = H - L;
hh7 = RANGE == HHV( RANGE, 7 );
dailyRange = ATR( 14 );
longHH7 = C > O AND hh7 ;
shortHH7 = C < O AND hh7;
crossedLong = Cross( Tenkan, Kijun );
crossedShort = Cross( Kijun, Tenkan );
crossedShort_barssince = BarsSince( crossedShort );
PlotShapes( crossedShort*shapeSmallCircle, colorYellow, layer = 0, L + range / 2 );
PlotShapes( crossedLong*shapeSmallDownTriangle, colorYellow, layer = 0, L + range / 2 );
PlotShapes( hh7*shapeDigit7, colorYellow, layer = 0, L + range / 2 );
String1 = Name();
String2 = "-IDEALPRO-CASH";
forex = StrMatch( String1, "*" + String2 );
GappedUp = GapUp();
GappedDown = GapDown();
volumeCheck = forex OR( V > MA( V, 50 ) * VolumeMA  AND MA( V, 50 ) > 250000 );
pricecheck = forex OR MA( C, 15 ) > 1 ; //AND  MA( C, 15 )<40;
//volumeCheck = pricecheck=True;
LongSignal_Tenkan = ( Tenkan > Kijun AND BarsSince( Cross( Tenkan, Kijun ) ) < 3 );
LongSignal_Kijun = ( Tenkan < Kijun );
LongSignal = volumeCheck AND pricecheck AND hh7 AND C > O    AND( LongSignal_Tenkan  OR LongSignal_Kijun );

// do all declarations
i = 0;
breakoutprice = Null;
stopprice = Null;
entryPrice = Null;
entryBar = -1;
inLongPosition = False;
Scaledout = False;

countHH7 = 0;
countLongHH7SinceCrossedShort = SumSince( crossedShort AND BarsSince( crossedShort ) < BarsSince( crossedLong ) , longHH7 ) ;
countLongHH7SinceCrossedLong = SumSince( crossedLong AND BarsSince( crossedShort ) > BarsSince( crossedLong )  , longHH7 ) ;
atrvalue = ATR( 14 );
dt = DateTime() ;
Sell = Buy = 0;

PlotShapes( LongSignal*shapeDigit2, colorPink, layer = 0, L - range / 4 );
entryDate = Null;
SignalBar = 0;

for( i = 1; i < BarCount; i++ )

{


    if( LongSignal[i] AND !inLongPosition )

    {
        // store the low so i can cancel the buy signal if it goes below low
        // mark the breakotu price so i can enter long when it enters breakout price
        breakoutprice = High[i];
        stopprice = Low[i];
        SignalBar = i;

        _TRACE( DateTimeToStr( dt[i] , 3 ) +  "got signal  "  + " buy price" + breakoutprice  + " loop id " + i );
    }

    if( inLongPosition == False AND  !IsNull( breakoutprice ) AND i > SignalBar ) // if high crosses breakout price then enter position.
    {
        _TRACE( DateTimeToStr( dt[i] , 3 ) + "checking  breakout price " + breakoutprice   + " loop id " + i );

        if( High[i] > breakoutprice AND( i - SignalBar <= MaxBarsAFterSignal ) ) // we will not look for trades that signalled >5 days
        {
            inLongPosition = True;
            Buy[i] = True;

            if( GappedUp[i] AND Open[i] > breakoutprice )
            {
                entryPrice = BuyPrice[i] = Open[i];
                _TRACE( DateTimeToStr( dt[i] , 3 ) + "Gapped up" + "open price" + Open[i] + "breakuot price " + breakoutprice   + " loop id " + i );
            }
            else
            {
                entryPrice = BuyPrice[i] = breakoutprice;
            }

            entryBar = i;
            countHH7 = 0;
            Scaledout = False;
            entryDate = DateTimeToStr( dt[i] , 3 )  ;
            StaticVarSet( FullName() + entryDate, countHH7 );
            StaticVarSet( FullName() + "L" + entryDate, countLongHH7SinceCrossedShort[i] - countLongHH7SinceCrossedLong[i] );
            StaticVarSet( FullName() + "hh7beforeentry" + entryDate, countLongHH7SinceCrossedLong[i - 1] ); // this is to count hh7 after it turns long but before entry. it does not include entry bar but includes signal bar
            StaticVarSet( FullName() + "entryRisk" + entryDate, ( breakoutprice - stopprice ) / breakoutprice ); // entry risk is (entry price-stop price)/entry price
            StaticVarSet( FullName() + "BreakoutRange" + entryDate, ( breakoutprice - stopprice ) / dailyRange[i] ); // entry risk is (entry price-stop price)/entry price
            StaticVarSet( FullName() + "EntryGapUp" + entryDate, GappedUp[i] );  // gappedup on entry
            StaticVarSet( FullName() + "BarDelays" + entryDate, i - SignalBar ); // how many bars after entry did i get signal.

            _TRACE( DateTimeToStr( dt[i] , 3 ) + "got long "   + " buy price" + breakoutprice );


        }
        else
        {
            if( Low[i] < stopprice OR( i - SignalBar > 5 ) ) // we will not look for trades that signalled >5 days
            {
                // reset and cleanup
                breakoutprice = Null;
                stopprice = Null;
                _TRACE( DateTimeToStr( dt[i] , 3 ) + "cleaned out  price and cancelled " );
                PlotText( "CAncelled Long", C[i], i, colorBlack, bkcolor = colorDefault, yoffset = 0 ) ;
            }

        }

    }

    if( inLongPosition AND i > entryBar )
    {
        if( hh7[i] AND H[i] > breakoutprice )
        {
            countHH7 += 1;

            StaticVarSet( FullName() + entryDate, countHH7 );
            _TRACE( DateTimeToStr( dt[i] , 3 ) + FullName() + entryDate );

            if( Low[i] > entryPrice )
            {
                stopprice = entryPrice;
            }


        }

        if( Low[i] < stopprice )// close and cleanup
        {
            Sell[i] = True;

            if( GappedDown[i] AND Open[i] < stopprice )
            {
                SellPrice[i] = Open[i];
                stopprice = Null;
            }
            else
            {
                SellPrice[i] = stopprice;
                entryPrice = Null;
            }


            inLongPosition = False;
            _TRACE( DateTimeToStr( dt[i] , 3 ) +  "stopped  long "  + " stopprice" + Low[i] );
            breakoutprice = Null;
            entryPrice = Null;
            entryBar = -1;


        }
        else
        {
            targetprice_scaleout = breakoutprice + .5 * ATRTargetRange * atrvalue[i];
            targetprice = breakoutprice + ATRTargetRange * atrvalue[i];

            if( High[i] >=   targetprice_scaleout AND  Scaledout == False )
            {
                Scaledout = True;
                Buy[ i ] = sigScaleOut;
                SellPrice[i] =  targetprice_scaleout ;
            }

            if( High[i] >=   targetprice )
            {
                Sell[i] = True;
                SellPrice[i] =  targetprice ;
                _TRACE( DateTimeToStr( dt[i] , 3 ) + "got target "   + " targetprice" + ( breakoutprice + atrvalue[i] ) );
                inLongPosition = False;
                breakoutprice = Null;
                stopprice = Null;
                entryPrice = Null;
                entryBar = -1;

            }

        }

    }

}






//Buy = LongSignal; //=h>ValueWhen(LongSignal,High,1);// AND LowestSince(LongSignal,Low,1)>ValueWhen(LongSignal,Low,1);

Filter = true;
Short = Cover = False;
AddColumn( LongSignal, "LongSignal" );
AddColumn( countLongHH7SinceCrossedShort, "countLongHH7SinceCrossedShort" );
AddColumn( countLongHH7SinceCrossedLong, "countLongHH7SinceCrossedLong" );

//AddColumn(C>ValueWhen(LongSignal,High,1) ,"buysignal");
//AddColumn(LowestSince(Ref(LongSignal,1),Low,1),"lowestlow");

SetCustomBacktestProc( "" );

/* Now custom-backtest procedure follows */
if( Status( "action" ) == actionPortfolio )
{
    bo = GetBacktesterObject();

    bo.Backtest( 1 ); // run default backtest procedure

    // iterate through closed trades first
    for( trade = bo.GetFirstTrade(); trade; trade = bo.GetNextTrade() )
    {
        // do your calculations involving trade objects (list of closed trades)
        _TRACE( "inside backtester" );

        countHH7 = StaticVarGet( trade.FullName + DateTimeToStr( trade.EntryDateTime , 3 ) );  // your value here

        countLongHH7SinceCrossedShort = StaticVarGet( trade.FullName + "L" + DateTimeToStr( trade.EntryDateTime , 3 ) );
        trade.AddCustomMetric( "HH7bars", countHH7 );

        trade.AddCustomMetric( "BeforeCrossHH7", countLongHH7SinceCrossedShort );

        trade.AddCustomMetric( "hh7beforeentry", StaticVarGet( trade.FullName + "hh7beforeentry"  + DateTimeToStr( trade.EntryDateTime , 3 ) ) );
        trade.AddCustomMetric( "EntryRisk", StaticVarGet( trade.FullName + "entryRisk"  + DateTimeToStr( trade.EntryDateTime , 3 ) ) ); // entry risk is (entry price-stop price)/entry price
        trade.AddCustomMetric( "BreakoutRange", StaticVarGet( trade.FullName + "BreakoutRange"  + DateTimeToStr( trade.EntryDateTime , 3 ) ) ); // entry risk is (entry price-stop price)/entry price
        trade.AddCustomMetric( "EntryGapUp", StaticVarGet( trade.FullName + "EntryGapUp"  + DateTimeToStr( trade.EntryDateTime , 3 ) ) ); // gapped up on entry.
        trade.AddCustomMetric( "BarDelays", StaticVarGet( trade.FullName +  "BarDelays"  + DateTimeToStr( trade.EntryDateTime , 3 ) ) ); // how many bars after signal did i enter

    }

    bo.ListTrades();
}

SetPositionSize( 10, spsPercentOfPosition * ( Buy == sigScaleOut ) ); // scale out 50% of position


A good start point to understand the results is to select detail log in Report tab of Analysis configuration.

OMG: i have used AB for centuries but never looked at its power properly. This blows Ninjatrader out of the water. TJ is a true genius.
can i add my custom variables to the detailed log?

Yes you can, inside your custom backtester code you can use
bo.RawTextOutput("any text\tSecond column"); to output whatever you wish

http://www.amibroker.com/guide/a_custombacktest.html

2 Likes