How to reset variables in a loop with backtestRegularraw

Hi all,

I hope that my questions are not too basic but I am not an experienced developer.
I am trying a code with more complex exit strategies. The logic from a business view is quite simple:

  • if the bars since buy is 100 bars we have a trailing stop after a minimum profit of X and a stop loss of Y.
  • After 100 bars we have a minimum expected win and a new trailing stop.

The buy signal is in impulse mode (and not state). Securities should be ranked with the 100 day ROC.
There is no real sell signal, it all depends on the exit strategy.
The applystop functions did not work in the portfolio mode and so I switched to the custom loop.

My problem is that with SetBacktestMode( backtestRegular ) my positionscore does not work. The best securities are not taken into account. But all variables in my loop are resetted. So I switched to SetBacktestMode( backtestRegularRaw ) and the positionscore works but the variables in the loop do not work . The variables start when the first buysignal appears and not with my first buytrade of the backtester. All variables from my loop are not reset with the backtest buy and backtest sell.

My expectation is that the code below triggers a buy in the backtest and starts the buycounter.

        if( Buy[ i ]  AND priceatbuy == 0 AND  onBuy == 0 )
        { priceatbuy = BuyPrice[ i ];
            OnBuy =  1;
            buycounter = 1 ;     }

Note I deactivated “// else Buy[ i ] = 0;” in the full code below because it eliminates the positionscore.
How can I reset the buycounter and all other variables if the backtester enters a buy (and not my old active buysignal).

Example Qualcomm:
My entry is on 26.9.20 with quote 70.31677:
image
Positionscore works fine:
image
My buycounter is at 67 and the buyprice is 53.21 on the entry date. That means that my 100 day check with the minimum profit is too early and the buyprice is wrong.
image
Here is the code:

SetBacktestMode( backtestRegularRaw );
#include_once "Formulas\Norgate Data\Norgate Data Functions.afl";
/* Symbols: */
index = "$NDX"; indexFilter = NorgateIndexConstituentTimeSeries( index );
spy = Foreign( "$SPXTR", "C" );
OnSecondLastBarOfDelistedSecurity = !IsNull( GetFnData( "DelistingDate" ) ) AND( BarIndex() == ( LastValue( BarIndex() ) - 1 ) OR DateTime() >= GetFnData( "DelistingDate" ) ) ;
OnLastTwoBarsOfDelistedSecurity = !IsNull( GetFnData( "DelistingDate" ) ) AND( BarIndex() >= ( LastValue( BarIndex() ) - 1 ) OR DateTime() >= GetFnData( "DelistingDate" ) );
setOption( "InitialEquity", 100000 ); RoundLotSize = 1;
maxopenpos = 5 ; SetOption( "MaxOpenPositions", maxopenpos ); SetPositionSize( 100 / maxopenpos, spsPercentOfEquity );
SetOption( "CommissionMode" , 3 );
SetOption( "CommissionAmount" , 0.01 );
/* Entry: */
medterm = 100 ;
PositionScore = 100 + ROC( Close, medterm );
buysignal = //
    Name() != "LBTYA" AND Name() != "GOOGL" AND Name() != "FOXA" and
    C  > ma( C, medterm )   AND spy > MA( spy, medterm )  ;
Buy =    indexFilter AND  NOT OnLastTwoBarsOfDelistedSecurity   AND
         Ref( buysignal, -1 )  ;
Sell = DateTime() == GetFnData( "DelistingDate" ) OR OnSecondLastBarOfDelistedSecurity ;
/* Exit: */
stopmin = 15;
firstproftmin = 30 ;
firsttrlmin = 30 ;
secondproftmin = 50 ;
secondtrlmin = 20;
lngprftmin = 15;

/*Loop: */
{
    highsincebuyarray = buycounterarray = priceatbuyarray = exita = Null ;
    buycounter = priceatbuy = highsincebuy =  onBuy =  exit = exitb = 0;
    minbars = 10 ;
    for( i = 0; i < BarCount; i++ )
    {
        if( Buy[ i ]  AND priceatbuy == 0 AND  onBuy == 0 )
        {
            priceatbuy = BuyPrice[ i ];
            OnBuy =  1;
            buycounter = 1 ;
        }
        // else         Buy[ i ] = 0;
        if( priceatbuy > 0 AND OnBuy = 1 )
        {
            if( Sell[i] == 1 )
            {
                exit = 1   ;
            }
            buycounter =  buycounter + 1;
            buycounterarray[i] = buycounter;
            highsincebuy = Max( High[ i ], highsincebuy );
            highsincebuyarray[i] = highsincebuy;
            priceatbuyarray[i] = priceatbuy;
            if( //StopLoss
                buycounter >= minbars AND  Low[ i ] <= ( 1 - stopmin / 100 ) * priceatbuy   )
            {
                exit = 1   ;
            }
            if( //1st Trailing
                buycounter <= medterm AND  buycounter >= minbars AND
                highsincebuy >= ( 1 + firstproftmin / 100 ) * priceatbuy AND
                Low[ i ] <= ( 1 - firsttrlmin / 100 ) * highsincebuy )
            {
                exit = 1   ;
            }
            if( //2nd Trailing
                buycounter > medterm AND buycounter >= minbars AND   highsincebuy >= ( 1 + secondproftmin / 100 ) * priceatbuy
                AND Low[ i ] <= ( 1 - secondtrlmin / 100 ) * highsincebuy            )
            {
                exit = 1   ;
            }
            if( // Profit minimum nach 200 Bars
                buycounter > medterm AND  Low[ i ] <= ( 1 + lngprftmin / 100 ) * priceatbuy )
            {
                exit = 1   ;
            }
            if( exit >= 1 )
            {
                Sell[ i ] =  1;
                Buy[ i] =   priceatbuy =  exit = highsincebuy =  OnBuy = tradeCount = buycounter = 0    ;
            }
        }
    }
}
Filter =  indexFilter AND Name() != "LBTYA" AND  NOT OnLastTwoBarsOfDelistedSecurity;
Plot( buycounterarray, "buycount", IIf( buycounterarray < medterm, colorWhite, colorBlack ), styleOwnScale )  ;
Plot( priceatbuyarray, "buyprice", colorgreen, styleOwnScale )  ;
Plot( highsincebuyarray, "hsincebuy", colorblack, styleOwnScale )  ;
AddColumn( buysignal, "Rnk", 1, IIf( buysignal, colorGreen, colorRed ), IIf( buysignal, colorGreen, colorRed ), 80 );
AddColumn( Buy, "Buy", 1.2 );
AddColumn( ROC( Close, medterm ), "ROC", 1.2 );
AddColumn( PositionScore, "ROC", 1.2 );
SetSortColumns( -3, -4 );

I tried exrem and the ranking under https://www.amibroker.com/kb/2014/11/26/handling-limit-orders-in-the-backtester/ but it did not work.

Thanks for your support!

1 Like

I think I can solve my issue only with the exit strategy in a CBT. So I will keep the entry code in the current format and move the exit part to the CBT. This will be my first CBT ... quite exiting :wink: