Duplicate: Data holes, was: NBarStop Not Working

Hi All,

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);

NBarStop

If i extend the backtest period, that same position continues to be held, and occupies one of the 10 position spots.NBarStop

Most likely your data is totally unaligned and has holes. It was already discussed on this forum. Use search before posting duplicate threads:

1 Like

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.

3 Likes

Incredible @portfoliobuilder ! Thank you my friend, that appears to have resolved the issue. Your help is greatly appreciated :pray: :pray:

Delisting data-wise is just one huge data hole. Keep in mind that exits can only be acted upon when there is trading activity on given day.

1 Like

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.