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:
Positionscore works fine:
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.
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!