Array with repeat pattern for exploration with LINREGSLOPE

Hi Everyone,
I am trying to create an AFL to do exploration with LINREGSLOPE.
AFL Function Reference - LINREGSLOPE (amibroker.com)
I need an array with repeated pattern of 19,18,17...,0 for lookback period of 20 days. This array will be used to calculate the highest upper bound that passes through one of the highs and the lowest bound that passes through one of the lows.

lookback = 20;
x_axis = array of repeated pattern of 19,18,...0
slope = LinRegSlope( Close, lookback );
m = ValueWhen( x_axis == 19, slope);
upper_bound = High - m * x_axis;
lower_bound = Low - m * x_axis;
my_ub = HHV(upper_bound,lookback);
my_lb = LLV(lower_bound,lookback);
Filter = x_axis == 19;
SetOption("NoDefaultColumns",True);
AddTextColumn(Name(),"Ticker");
AddColumn(DateTime(),"Date",formatDateTime);
AddColumn(m,"slope",1.2);
AddColumn(my_ub,"Upper bound",1.2);
AddColumn(my_lb,"Lower bound",1.2);

Upper and Lower Bound

Thanks in advance.

x_axis = 19-BarIndex()%20;
Plot(x_axis, "x_axis", colorDefault );
2 Likes

Thank you very much for your very prompt reply. Sorry, I was not so clear on the number pattern. Possible for it to start from Barcount - 1 ?

Like this?

lookback = 20;
x_axis = Reverse(BarsSince(BarIndex()%lookback==0));

Or like this?

lookback = 20;
x_axis = lookback-1-BarIndex()%lookback;
x_axis = Reverse(x_axis);
1 Like

@fxshrat, Thank you very much indeed. This code of yours works perfectly.

x_axis = lookback-1-BarIndex()%lookback;
x_axis = Reverse(x_axis);
1 Like

Here is the working AFL.

lookback = 20;
x_axis = lookback-1-BarIndex()%lookback;
x_axis = Reverse(x_axis);
slope = LinRegSlope( Close, lookback );
m = IIf(x_axis == 19, m=slope, ValueWhen( x_axis == 19, slope, 0));
upper_bound = High - m * x_axis;
lower_bound = Low - m * x_axis;
my_ub = HighestSince(x_axis == 0, upper_bound);
my_lb = LowestSince(x_axis == 0, lower_bound);
Filter = x_axis == 19;
SetOption("NoDefaultColumns",True);
AddTextColumn(Name(),"Ticker");
AddColumn(DateTime(),"Date",formatDateTime);
AddColumn(m,"slope",1.2);
AddColumn(my_ub,"Upper bound",1.2);
AddColumn(my_lb,"Lower bound",1.2);

A further refinement to the AFL code.

dt_start = DateTimeConvert(2,Status("rangefromdate"));
dt_end = DateTimeConvert(2,Status("rangetodate"));
last_bi = Lookup(BarIndex(),dt_end,-1);
lookback = 20;
// Setup array with lookback-1..0 repeating sequence
x_axis = lookback-1-BarIndex()%lookback;
x_axis = Reverse(x_axis);
// Shift lookback-1 to lastbarinrange
if (LastValue(BarIndex()) != last_bi) {
	x_axis = Ref(x_axis, LastValue(BarIndex()) - last_bi);
}
intercept = LinRegIntercept( Close, lookback );
slope = LinRegSlope( Close, lookback );
//
// compute linear regression coefficients
m = IIf(x_axis == lookback - 1, m=slope, ValueWhen( x_axis == lookback - 1, slope, 0));
c_intercept = IIf(x_axis == lookback - 1, c_intercept=intercept, ValueWhen( x_axis == lookback - 1, intercept, 0));
High_c = High - m * x_axis;
hbound = HighestSince(x_axis == 0, High_c);
Low_c = Low - m * x_axis;
lbound = LowestSince(x_axis == 0, Low_c);
//Filter = x_axis == lookback - 1;
Filter =1;
if ((MarketID() != 1 AND MarketID() != 2 AND MarketID() != 3) OR StrFind(Name(),"_D") !=0) {
	Filter = 0;
}

SetOption("NoDefaultColumns",True);
AddTextColumn(Name(),"Ticker");
AddColumn(DateTime(),"Scan Date",formatDateTime);
AddTextColumn(SectorID(1),"Sector");
AddTextColumn(IndustryID(1),"Industry");
AddColumn(x_axis,"x_axis",1.0);
AddColumn(slope,"slope",1.2);
AddColumn(m,"M",1.2);
AddColumn(c_intercept,"C",1.2);
AddColumn(hbound,"high bound",1.2);
AddColumn(lbound,"low bound",1.2);
AddColumn((hbound-c_intercept)/Close*100,"H Gap",1.2);
AddColumn((c_intercept-lbound)/Close*100,"L Gap",1.2);
AddColumn((hbound-lbound)/Close*100,"HL Gap",1.2);

This exploration will only produce one result in each lookback period starting from "rangetodate". I would like to have it generate results for all days within "rangefromdate" to "rangetodate". It's ok if this is not possible as I have already done it with my external script. Just curious to know how to do it in AFL.

I manage to code it for lookback period of 10 but the AFL does not look efficient. If experts here can give some pointers to a more compact code and that would be much appreciated.

lookback = 10;
m = LinRegSlope( Close, lookback );
// Search for high bound
h0 = Ref(H,-9);
h1 = Ref(H,-8);
h2 = Ref(H,-7);
h3 = Ref(H,-6);
h4 = Ref(H,-5);
h5 = Ref(H,-4);
h6 = Ref(H,-3);
h7 = Ref(H,-2);
h8 = Ref(H,-1);
h9 = H;
ch0 = h0 - m * 0;
ch1 = h1 - m * 1;
ch2 = h2 - m * 2;
ch3 = h3 - m * 3;
ch4 = h4 - m * 4;
ch5 = h5 - m * 5;
ch6 = h6 - m * 6;
ch7 = h7 - m * 7;
ch8 = h8 - m * 8;
ch9 = h9 - m * 9;
upper_bound = IIf(ch0 > ch1, ch0, ch1);
upper_bound = IIf(upper_bound > ch2, upper_bound, ch2);
upper_bound = IIf(upper_bound > ch3, upper_bound, ch3);
upper_bound = IIf(upper_bound > ch4, upper_bound, ch4);
upper_bound = IIf(upper_bound > ch5, upper_bound, ch5);
upper_bound = IIf(upper_bound > ch6, upper_bound, ch6);
upper_bound = IIf(upper_bound > ch7, upper_bound, ch7);
upper_bound = IIf(upper_bound > ch8, upper_bound, ch8);
upper_bound = IIf(upper_bound > ch9, upper_bound, ch9);
// Search for low bound
l0 = Ref(L,-9);
l1 = Ref(L,-8);
l2 = Ref(L,-7);
l3 = Ref(L,-6);
l4 = Ref(L,-5);
l5 = Ref(L,-4);
l6 = Ref(L,-3);
l7 = Ref(L,-2);
l8 = Ref(L,-1);
l9 = L;
cl0 = l0 - m * 0;
cl1 = l1 - m * 1;
cl2 = l2 - m * 2;
cl3 = l3 - m * 3;
cl4 = l4 - m * 4;
cl5 = l5 - m * 5;
cl6 = l6 - m * 6;
cl7 = l7 - m * 7;
cl8 = l8 - m * 8;
cl9 = l9 - m * 9;
lower_bound = IIf(cl0 < cl1, cl0, cl1);
lower_bound = IIf(lower_bound < cl2, lower_bound, cl2);
lower_bound = IIf(lower_bound < cl3, lower_bound, cl3);
lower_bound = IIf(lower_bound < cl4, lower_bound, cl4);
lower_bound = IIf(lower_bound < cl5, lower_bound, cl5);
lower_bound = IIf(lower_bound < cl6, lower_bound, cl6);
lower_bound = IIf(lower_bound < cl7, lower_bound, cl7);
lower_bound = IIf(lower_bound < cl8, lower_bound, cl8);
lower_bound = IIf(lower_bound < cl9, lower_bound, cl9);
Filter = 1;
SetOption("NoDefaultColumns",True);
AddTextColumn(Name(),"Ticker");
AddColumn(DateTime(),"Date",formatDateTime);
AddColumn(m,"slope",1.2);
AddColumn(lower_bound,"Lower bound",1.2);
AddColumn(upper_bound,"Upper bound",1.2);
AddColumn((upper_bound-lower_bound)/Close*100,"Range",1.2);
/// @link https://forum.amibroker.com/t/array-with-repeat-pattern-for-exploration-with-linregslope/24684/9
lookback = 10;
m = LinRegSlope( Close, lookback );
x_axis = lookback-1-BarIndex()%lookback;
x_axis = Reverse(x_axis);

upper_bound = 0;
lower_bound = 1e9;
for ( i = 0; i < lookback; i++ ) {	
	mi = m*i;
	shift = lookback-i-1;
	ch = Ref(H,-shift)-mi;
	cl = Ref(L,-shift)-mi;
	// Search for high bound
	upper_bound = Max(upper_bound, ch);
	// Search for low bound
	lower_bound = Min(lower_bound, cl);
}

Filter = 1;
AddSummaryRows(63, 1.2);
AddColumn(m,"slope",1.2);
AddColumn(lower_bound,"Lower bound",1.2);
AddColumn(upper_bound,"Upper bound",1.2);
AddColumn((upper_bound-lower_bound)/Close*100,"Range",1.2);
2 Likes

@fxshrat, Thanks for the code. Changing lookback period will be a lot easier.

Maybe I should explain what is the purpose of this. When entering a trade, the first thing in mind is stop loss. The volatility of each stock is not the same. This code is to provide a quick check whether the targeted stop loss is sufficient.

2 Likes

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