Hi all,
I would be really grateful for some help with a coding problem I have.
I am working on a trend following idea that detects when a trending stock takes a breather (I call each breather area a Base, where price levels out for a bit) from its trend and then breaks out. I am writing code that detects the Bases.
An example of the problem I'm having is with a variable called BaseLength. My code successfully calculates the baseLength when it detects a low bar in the base. I want to keep incrementing the BaseLength for subsequent bars to the right, until a break out occurs. I think I could probably change my code to use valuewhen(baseLength>0, barindex()) however I would really like to know why my current code doesn't work as it's fairly fundemental to my understanding of array processing!
My code currently says...
BaseLength = IIf(uneventfulDay AND NOT SetByLoop, ValueWhen(BaseLength>0,BaseLength+1), BaseLength);
It seems to only increment for one bar, then it propagates the same value without incrementing. I did previously using the following, which I also couldn't get to work...
BaseLength = IIf(uneventfulDay AND NOT SetByLoop, ref(BaseLength,-1)+1, BaseLength);
I attach my whole code if needed.
//================================================================================================================
function lowBar(arr, bars)
{
return arr==LLV(arr,bars);
}
//================================================================================================================
function highBar(arr, bars)
{
return arr==HHV(arr,bars);
}
//================================================================================================================
// OVERVIEW
// This code is still work in progress. Its aim is to trade trending stocks that break out from temporary breathers (called Bases in this code)
// The main terms are...
// initialBase0 - this is where the trend might begin. It is below the 200MA and is a low bar.
// newBaseStarts - a new base can start when price has risen at least 20% from the previous (or original base)
// BaseTop, BaseBottom, BaseLength describe the dimensions of the base
//
// If price drops below the BaseBottom, the BaseBottom can be lowered as long as it is not within 20% of the previous base.
// The BaseTop can rise when the BaseTop is breached within a threshold and returns within the base.
//
// For bars where nothing happens to change the dimensions of the base, there is a section that carries the values forward to the next bar for convenient referencing
// It is that section which doesn't seem to work.
// initialise variables
//------------------------------------------------------------------------------------------
BaseTop = 0;
BaseBottom = 0;
BaseNo = -1;
BaseLength = 0;
PreviousBaseTop = 9999;
minBaseLength = 10;
maxBaseLength = 100;
dVI = MA(L,200);
IsLowBar = lowbar(Low, minBaseLength);
BuyThreshold = 1.005;
BuySetup = 0;
setByLoop = 0;
// set initial base 0
//------------------------------------------------------------------------------------------
initialBase0 = islowbar AND
(
(baseNo==-1 AND L < dVI)
//OR
//(baseNo==0 AND Low < PreviousBaseTop)
);
BaseNo = IIf(initialBase0, 0, BaseNo);
PreviousBaseTop = IIf(initialBase0, Low, PreviousBaseTop);
BaseTop = IIf(initialBase0, Low, BaseTop);
BaseBottom = IIf(initialBase0, Low, BaseBottom);
BaseLength = IIf(initialBase0, 0, BaseLength);
// new base starts
//------------------------------------------------------------------------------------------
newBaseStarts = NOT initialBase0 AND islowbar AND
L >= Ref(BaseTop,-1)*1.2 AND
L > Ref(BaseBottom,-1);
previousBaseTop = IIf(newBaseStarts, Ref(BaseTop,-1),previousBaseTop);
BaseNo = IIf(newBaseStarts, Ref(BaseNo,-1)+1,BaseNo);
BaseBottom = IIf(newBaseStarts, Low,BaseBottom);
BaseTop = IIf(newBaseStarts, High,BaseTop);
// base length and base top
//------------------------------------------------------------------------------------------
for (i=minBaseLength; i<BarCount;i++)
{
// calculate length
for (x=1;(i-x)>0 AND x<= maxBaseLength AND newBaseStarts[i] ; x++)
{
// update Base Top
if (H[i-x]>BaseTop[i])
BaseTop[i] = H[i-x];
// calculate length
if (L[i-x]<BaseBottom[i])
{
// add length to bars to the left
for (z=1; z<=x; z++)
{
BaseLength[i-x+z]=z;
setByLoop[i-x+z]=1;
}
break;
}
}
}
// reset Bases when price drops
//------------------------------------------------------------------------------------------
resetBases = BaseNo > 0 AND
Ref(Low,-1)>= Ref(PreviousBaseTop,-1)*1.2 AND
Low < Ref(PreviousBaseTop,-1)*1.2;
BaseBottom = IIf(resetBases, 9999,BaseBottom);
BaseTop = IIf(resetBases, 0, BaseTop);
BaseLength = IIf(resetBases, 0, BaseLength);
PreviousBaseTop = IIf(resetBases, 9999, PreviousBaseTop);
BaseNo = IIf(resetBases, 0, BaseNo);
// lowerBaseBottom
//------------------------------------------------------------------------------------------
lowerBaseBottom = islowbar AND
L < Ref(BaseBottom, -1) AND
L > PreviousBaseTop*1.2;
BaseBottom = IIf(lowerBaseBottom, Low, BaseBottom);
// Raise BaseTop
//------------------------------------------------------------------------------------------
RaiseBaseTop = Ref(High, -1) > Ref(BaseTop,-1) AND
Ref(High, -1) < Ref(BaseTop,-1)*BuyThreshold AND
L < ref(BaseTop,-1);
BaseTop = IIf(RaiseBaseTop, HHV(H, BaseLength), BaseTop);
// Buy Signal
//------------------------------------------------------------------------------------------
BuySignal = Cross(H, BaseTop*BuyThreshold) AND
(BaseNo==1 OR BaseNo==2 OR BaseNo == 3);
BuySetup = IIf(BuySignal, 1,BuySetup);
// bring forward values if they have not been set
//------------------------------------------------------------------------------------------
uneventfulDay = NOT initialBase0 AND
NOT newBaseStarts AND
NOT resetBases;
PreviousBaseTop = IIf(uneventfulDay, Ref(PreviousBaseTop,-1), PreviousBaseTop);
//BaseTop = IIf(uneventfulDay AND NOT RaiseBaseTop, ref(BaseTop,-1),BaseTop);
BaseTop = IIf(uneventfulDay AND NOT RaiseBaseTop, ValueWhen(BaseTop>0,BaseTop),BaseTop);
BaseBottom = IIf(uneventfulDay AND NOT LowerBaseBottom, valuewhen(BaseBottom>0,BaseBottom),BaseBottom);
BaseNo = IIf(uneventfulDay, Ref(BaseNo,-1),BaseNo);
//BaseLength = IIf(uneventfulDay AND NOT SetByLoop, ref(BaseLength,-1)+1, BaseLength);
BaseLength = IIf(uneventfulDay AND NOT SetByLoop, ValueWhen(BaseLength>0,BaseLength+1), BaseLength);
CarryForward = IIf(uneventfulDay AND NOT SetByLoop, 1,0);
// Interpretation
//------------------------------------------------------------------------------------------
printf("\n\ninitialBase0 = "+initialBase0);
printf("\nnewBaseStarts="+newBaseStarts);
printf("\nBaseLength="+BaseLength);
printf("\nresetBases="+resetBases);
printf("\nuneventfulDay="+uneventfulDay);
printf("\nlowerBaseBottom="+lowerBaseBottom);
printf("\nRaiseBaseTop="+RaiseBaseTop);
printf("\n\nBaseBottom="+BaseBottom);
printf("\n\nBaseTop="+BaseTop);
printf("\nSetbyloop="+Setbyloop);
printf("\nCarryForward="+CarryForward);
_SECTION_BEGIN("Price");
SetChartOptions(0,chartShowArrows|chartShowDates);
_N(Title = StrFormat("{{NAME}} - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) ));
Plot( C, "Close", ParamColor("Color", colorDefault ), styleNoTitle | ParamStyle("Style") | GetPriceStyle() );
_SECTION_END();
_SECTION_BEGIN("MA1");
P = ParamField("Price field",-1);
Periods = Param("Periods", 200, 2, 300, 1, 10 );
Plot( MA( P, Periods ), _DEFAULT_NAME(), ParamColor( "Color", colorCycle ), ParamStyle("Style") );
_SECTION_END();