I am attempting to set an N-Bar stop of 31 days, and am getting instances in the back test of trades held longer than the N-bar stop amount specified. Am I doing something wrong?
#include_once "Formulas\Norgate Data\Norgate Data Functions.afl"
SetOption("MaxOpenPositions", 10);
SetPositionSize( 10, spsPercentOfEquity );
SetTradeDelays(1,1,1,1);
//Check market trend
SetForeign("$SPX");
IndexTrendPeriod = 270;
IndexDownTrend = C < MA(C,IndexTrendPeriod);
RestorePriceArrays();
stockInIndex = NorgateIndexConstituentTimeSeries("$SPX");
DownDay1 = C < Ref(C,-1);
DownDay2 = Ref(C,-1) < Ref(C,-2);
DownDay3 = Ref(C,-2) < Ref(C,-3);
DD1ROC = (C - Ref(C,-1)) / Ref(C,-1);
DD2ROC = (Ref(C,-1) - Ref(C,-2)) / Ref(C,-2);
DD3ROC = (Ref(C,-2) - Ref(C,-3)) / Ref(C,-3);
// **********************************************************************************************************************
// Clenow Position Rank - Exponential regression to get slope, past number of days specified by lookBack parameter
LookBack = 90 ;
slopeArray = ln(Close);
linSlope = LinRegSlope(slopeArray, lookBack);
eSlope = exp(linSlope);
// Annualize slope = (1 + slope)^250
annualSlope = (eSlope^250)-1;
// Calculate R2 (coefficient of determination) of the exponential price regression line
bi = BarIndex();
R2 = (Correlation(slopeArray, bi, lookBack))^2;
// Multiply annualized slope by R2 to get volatility-adjusted annualized slope
adjSlope = R2 * annualSlope;
// Rank based on volatility-adjusted annualized slope
PositionScore = adjSlope;
// ************************************************************************************************************************
EntrySignal = StockInIndex AND DownDay1 AND DownDay2 AND DownDay3 AND (DD1ROC < DD2ROC) AND (DD2ROC < DD3ROC) AND NOT IndexDownTrend;
HighestHighDays = 10;
ExitSignal = C >= HHV(C, HighestHighDays);
Buy = EntrySignal AND NOT IndexDownTrend;
Sell = ExitSignal ;
Buy = ExRem(Buy,Sell);
Sell = ExRem(Sell,Buy);
StopBars = 31;
ApplyStop(stopTypeNBar, StopmodeBars, StopBars);
Filter = Buy OR Sell;
AddColumn( IIf(Buy,'B','S'), "Signal", formatChar);
AddColumn( adjslope,"Position Rank", 1.2);
AddColumn(C, "Close", 1.2);
Thank you @Tomasz . My apologies for missing that. I have been reading through a number of different threads and still cannot figure out how to solve the issue.
I use Norgate Premium Data, am using the "S&P 500 Current and Past" watchlist, have pad & align turned on, and have gone to "tools => Database purify" but still see a number of positions held in my back test for many multiples beyond the N bars specified. Would you please point me in the right direction as to how to tell the system to eliminate these positions? You were correct in that there appears to be no more bars only a few days after the position was entered. How do I tell the system to eliminate these positions, rather than hold an Open Long for thousands of days? Thank you, any guidance is greatly appreciated!
@nicolasvaughan I can't replicate your problem but perhaps you need to review how you are using your historical watchlists from Norgate. They include delisted stocks and Norgate provides you with instructions that you have not used in your code. https://norgatedata.com/amibroker-faq.php
Scroll down to the discussion,
"How do I exit a position in a backtest prior to a stock being delisted?"
Where they suggest adding lines like this
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") );
Buy = Buy AND NOT OnLastTwoBarsOfDelistedSecurity;
Sell = Sell OR OnSecondLastBarOfDelistedSecurity;
I don't know if that will solve your problem but appears necessary to add to your code anyway.