Sigscaleout Trade list contracts not showing the full contracts entered

Hi,

  1. When I use buy = sigscaleout for scalling out 50% of the position.

  2. Balance position is exited using sell.

  3. The profit calculation is correct in the trade list and detailed tradelist for the full qty.

  4. the trade list contracts column is showing only the quantity that was sold using “sell”. The total buy qty is not displayed.

  5. What settings should i change for the trade list to show the full qty.

Without seeing your code and being able to reproduce what you are seeing, I would suggest you look at this first.

https://www.amibroker.com/guide/h_pyramid.html

IMPORTANT: Please note that backtester treats trade that you scale-in/out as SINGLE trade (i.e. will show single row in trade list). The only difference versus plain trade is that it will calculate average entry price (and avg. entry fx rate) based on all partial entries and average exit price (and avg. exit fx rate) based on all parial exits and will show average prices in entry/exit price field. The commission is of course applied correctly to each (partial) entry/exit depending on partial buy/sell size.

If you want to see details about scaling you have to run backtest in “DETAIL LOG” mode as only then you will see how scaling-in /out works and how average prices are calculated.

1 Like

Hi,

thanks for your reply. Adding my code below. And more over I have another problem. The sellprice assigned inside the for loop is not working. Coverprice works. So I have assinged sellprice out of the loop again.

Thanks


function Round2TickSize( aValue ) // for  rounding the prices to ticksize
{
    TickInv = 1 / TickSize;
    return ( round( aValue * TickInv ) / TickInv );
}

function RoundLotSizer( aValue )
{
    roundlot = Int( aValue / RoundLotSize ) * RoundLotSize; // Note: RoundLotSize is an array of same values
    return roundlot;
}


SetOption( "CommissionMode", 1 );
SetOption( "CommissionAmount", 0.02 );
SetOption( "InitialEquity", 1000000 );
SetOption( "FuturesMode", True );
SetOption( "AllowSameBarExit", True );
SetOption( "UsePrevBarEquityForPosSizing", True );
SetOption( "ReverseSignalForcesExit", True );
// Initial Parameters

Market_end_time = 152500;

DN = DateNum();
TN = TimeNum();

Shares = 10*RoundLotSize;

Market_open_time = ValueWhen( Day() != Ref( Day(), -1 ), TN, 1 );
// Trail Stop

per3 = Optimize( "TSL Multiple (ATR)", 3, 3, 5, 1 );
ATR0 = Ref( atr( 14 ), -1 );
multiRisk = 2;
partialTgtTP = 0.5;

// freeze timing.
rangeh = Ref(HHV( H, 14 ),-1);
rangel = Ref(LLV( L, 14 ),-1);


// Buy sell short cover
Buy0 = Cross( H, rangeh ) ;
//sell0 = cover0 = TN == Market_end_time;

Short0 = Cross( rangel, L );



// Stop management

//initialize buy,sell...
Buy = Sell = Short = Cover = Null;
tslarr = Null;
tslsarr = Null;
profitltgt = profitStgt = Null;
sl = 0;
SellPrice = BuyPrice = ShortPrice = CoverPrice = null;
//flag indicates whether you are in Long,Short position
Bflag = sflag = selltype = longbalance = shortbalance = longentry = shortentry = longexit = shortexit =  0;

//barcount means the number of bars/candles in chart/data being analysed
//i is a counter for indexing arrays
for( i = 4; i < BarCount; i++ )
{
    // Long
    longbalance[i] = longbalance[i - 1];

    //Entry side Long
    if( buy0[i] AND sflag == 0 AND bflag == 0 AND  TN[i] > Market_open_time[i] AND  TN[i] < Market_end_time )
    {
        Buy[i] = 1;
        bflag = 1;
        BuyPrice[i] = Max( rangeh[i] + TickSize, Open[i] );
        tslarr[i] = round2ticksize( Max( rangel[i], L[i - 1] - ( per3 - 1 ) * ATR0[i] ) );
        profitLTgt[i] = round2ticksize( ( BuyPrice[i] - tslarr[i] ) * multiRisk + BuyPrice[i] );
        longentry[i] = longbalance[i] = shares;
        partialTPDone = 0;

    }

    // TL Stop
    if( bflag == 1 )
    {
        tslarr[i] = round2ticksize( Max( rangel[i], Max( tslarr[i - 1], H[i - 1] - per3 * ATR0[i] ) ) );
        profitLTgt[i] = Max( profitLTgt[i], profitLTgt[i - 1] );

    }

    // Exit Sell
    //Tgt reached
    if( High[i] >= profitlTgt[i]  AND  bflag == 1 AND partialTgtTP > 0 AND partialTPDone == 0 )
    {
        SellPrice[i] = profitltgt[i] ;
        selltype[i] = 1;
        partialTPDone = 1;
        Buy[i] = sigScaleOut;
        longexit[i] = roundlotsizer( longbalance[i] * ( partialTgtTP ) );
        longbalance[i] = longbalance[i] - longexit[i];

    }
    // stop hit
    else
        if( L[i] <= tslarr[i - 1]  AND bflag == 1 )
        {
            SellPrice[i] = tslarr[i - 1] ;
            selltype[i] = 2;
            Sell[i] = 1;
            bflag = 0;
            profittgt[i] = Null;
            tslarr[i] = Null;
            longexit[i] = longbalance[i];
            longbalance[i] = 0;
        }
        // market closed
        else
            if( TN[i] == Market_end_time  AND bflag == 1 )
            {
                SellPrice = C[i];
                selltype[i] = 1;
                Sell[i] = 1;
                bflag = 0;
                profittgt[i] = Null;
                tslarr[i] = Null;
                longexit[i] = longbalance[i];
                longbalance[i] = 0;
            }




////code for short-cover
    shortBalance[i] = shortBalance[i - 1];

    //Short Entry
    if( short0[i] AND sflag == 0 AND bflag ==0  AND TN[i] > Market_open_time[i] AND TN[i] < Market_end_time )
    {
        Short[i] = 1;
        sflag = 1;
        ShortPrice[i] = Min( rangel[i] - TickSize, Open[i] );
        tslsarr[i] = round2ticksize( min( rangeh[i], H[i - 1] + ( per3 - 1 ) * ATR0[i] ) );
        profitSTgt[i] = round2ticksize( ShortPrice[i] - ( tslsarr[i] - ShortPrice[i] ) * multirisk );
        shortentry[i] = shortbalance[i] = shares ;
        partialTPDone = 0;
    }

    // Trailing Stop
    if( sflag )
    {
        if( IsNull( tslsarr[i - 1] ) )slval = 999999999;
        else slval = tslsarr[i - 1];

        tslsarr[i] = round2ticksize( Min( rangeh[i], Min( slval, L[i - 1] + per3 * ATR0[i] ) ) );
        profitSTgt[i] = Max( profitSTgt[i - 1], profitSTgt[i] ) ;


    }

    //Tgt hit
    if( L[i] <= ProfitStgt[i] AND sflag == 1 AND partialTgtTP > 0 AND partialTPDone == 0 )
    {
        CoverPrice[i] = ProfitStgt[i];
        partialTPDone = 1;
        shortexit[i] = RoundLotSizer( shortBalance[i] * ( partialTgtTP ) );
        shortbalance[i] -= shortexit[i];
        Short[i] = sigScaleOut;


    }
    // Stophit
    else
        if( ( H[i] >= tslsarr[i - 1] ) AND sflag == 1 )
        {
            CoverPrice[i] = tslsarr[i - 1];
            Cover[i] = 1;
            sflag = 0;
            ProfitStgt[i] = Null;
            tslsarr[i] = Null;
            shortexit[i] = shortbalance[i];
            shortBalance[i] = 0;
        }
        // Last bar
        else
            if( TN[i] == Market_end_time  AND sflag == 1 )
            {
                CoverPrice[i] = C[i];
                Cover[i] = 1;
                sflag = 0;
                ProfitStgt[i] = Null;
                tslsarr[i] = Null;
                shortexit[i] = shortbalance[i];
                shortBalance[i] = 0;
            }


}

// Sellprice assigned in the loop is  not working. the bactester is using bar high for long trades sellprice if the following line is not added. 
SellPrice = IIf( selltype == 1, Ref( profitltgt, -1 ), IIf( selltype == 2, Min( Ref( tslarr, -1 ), Open ), Close ) );

SetPositionSize( longentry + shortentry,  spsShares );
SetPositionSize( longexit, spsShares * ( Buy == sigScaleOut ) );
SetPositionSize( shortexit, spsShares * ( Short == sigScaleOut ) );


//display

Plot( rangeh, "LongEntryAbove", colorGreen, styleLine );
Plot( rangel, "ShortEntryBelow", colorRed, styleLine );
Plot( C, "Price", colorDefault, styleCandle );
Plot( Ref(tslsarr,-1), "tslsarr", colorAqua, styleDots );
Plot( Ref(tslarr,-1), "tslarr", colorBlueGrey, styleDots );
Plot( profitltgt, "LongPft", colorGold, styleDots | styleNoRescale );
Plot( profitStgt, "ShortPft", colorGold, styleDots | styleNoRescale );
_N( Title = StrFormat( "{{NAME}} - {{INTERVAL}} {{DATE}} Open %.2f, Hi %.2f, Lo %.2f, Close %.2f (%.1f%%)\n {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ) );
/* Plot Buy and Sell Signal Arrows */

PlotShapes( IIf( Buy == 1, shapeUpArrow, shapeNone ), colorGreen, 0, L, Offset = -40 );
PlotShapes( IIf( Cover, shapehollowUpArrow, shapeNone ), colorAqua, 0, L, Offset = -45 );
PlotShapes( IIf( Sell, shapeDownArrow, shapeNone ), colorRed, 0, H, Offset = -45 );
PlotShapes( IIf( Short==1, shapehollowDownArrow, shapeNone ), colorRed, 0, H, Offset = -45 );
PlotShapes( IIf( Buy > 1, shapedownArrow, shapeNone ), colorAqua, 0, H, Offset = -40 );
PlotShapes( IIf( Short > 1, shapehollowUpArrow, shapeNone ), colorBlueGrey, 0, L, Offset = -40 );
Title = Title + StrFormat( "\nLong P: %.f, tSL: %.2f, Buyprice: %.2f,  Longbalance: %.f,\n TslShort: %.2f, ShortPrice: %.2f , profitSTgt: %.2f, shortB: %.f", profitLtgt, tslarr, BuyPrice,  LongBalance, tslsarr, ShortPrice, profitSTgt, shortbalance );

The number of shares displayed in the trade list is the final number held, after all the scaling has been done, when the trade is finally exited.

I haven’t gone through your code, but to get the number of shares at entry onto the trade list, you’ll need to use the custom backtester to produce your own trade level custom metric.

First you’ll need to capture the number of shares at the entry. You can do this by looping through the open trade list on each bar and checking if trade.EntryDateTime is equivalent to DateTime() for the bar you’re on. Then retrieve trade.shares, and store it in a variable named with the trade.symbol and the trade.EntryDateTime, using VarSet or StaticVarSet.

Then at the end of the process, loop through the closed trade list and output a trade level custom metric using trade.EntryDateTime and trade.Symbol to retrieve the value from the stored variable. You can also loop through the open trade list at this point and perform the same task, in order to get a value for every trade.

It should be achievable using the High-Level CBI, but if you’re not already familiar with the CBI you’ll need to become proficient in that first. This link explains it in detail: http://www.amibroker.org/userkb/2008/03/16/amibroker-custom-backtester-interface-2/

This link explains how to produce trade level metrics: https://www.amibroker.com/guide/a_custommetrics.html

1 Like