Proper order cumulative indicator

Hey all,

I'm trying to re-create an indicator called "proper order cumulative indicator" (image attached). While I know AFL a bit, what I don't know how to do is count up the number of bars, across days, that the averages are in the "proper order" - I can obviously, for a single day, determine that the 10SMA > 20SMA > 30SMA - but how would I store the result to pass to the next day? Or am I thinking about this all wrong?

Any thoughts appreciated and thanks in advance for any help.

Try it like this,

MA1 = MA( C, 10 );
MA2 = MA( C, 20 );
MA3 = MA( C, 30 );

TrueArray = (MA1 > MA2) AND (MA2 > MA3);  // some condition

SumBars = SumSince( TrueArray == 0, TrueArray );

Plot( SumBars , "poci", ColorBlue,
styleNoTitle| styleOwnScale| styleHistogram |styleNoLabel,
5 );
// remove min,max( ie. 5 in plot ) and styleOwnScale,
// if you are using a separate chart pane.
3 Likes

@droskill, inspired by the code posted by @nsm51, here is my implementatiion to be used in a separate pane:

// https://forum.amibroker.com/t/proper-order-cumulative-indicator/39899
price = ParamField( "Price series", 3 );  // by default using Close
period1 = Param( "Period 1 - Short", 10, 5, 100, 1 );
period2 = Param( "Period 2 - Medium", 20, 6, 200, 1 );
period3 = Param( "Period 3 - Long", 30, 7, 300, 1 );

// Calculations
MA1 = MA( price, period1 );
MA2 = MA( price, period2 );
MA3 = MA( price, period3 );

Uptrend = ( MA1 > MA2 ) AND( MA2 > MA3 );
Downtrend = ( MA1 < MA2 ) AND( MA2 < MA3 );

SumUptrendBars = SumSince( Uptrend == 0, Uptrend );
SumDowntrendBars = SumSince( Downtrend == 0, Downtrend );


// Chart
colorLightLemon = colorRGB( 248, 246, 223 );
colorLightGreen = colorRGB( 206, 236, 202 );
colorLightPink = colorRGB( 249, 236, 234 );

SetChartBkGradientFill( colorLightLemon, colorLightYellow );
Plot( SumUptrendBars , "", ColorDarkGreen, styleNoTitle | styleHistogram | styleNoLabel, null, null, 0, -1, -50 );
Plot( -SumDowntrendBars , "", ColorDarkRed, styleNoTitle | styleHistogram | styleNoLabel, null, null, 0, -1, -50 );

Plot( sumUptrendBars > 0 , "", colorLightGreen, styleNoTitle | styleArea | styleOwnScale | styleNoLabel, 0, 1, 0, -1, -100 );
Plot( SumDowntrendBars > 0 , "", colorLightPink, styleNoTitle | styleArea | styleOwnScale | styleNoLabel, 0, 1, 0, -1, -100 );
PlotGrid( 0, colorBlack );

// plot the label on the right side
UpDown = iif(sumUptrendBars, sumUptrendBars, 0);
UpDown = iif(sumDowntrendBars, -sumDowntrendBars, UpDown);
Plot(Updown, "PO", colorBlue, styleNoTitle | styleNoLine);

Title = StrFormat( "{{NAME}} - " + FullName() +
                   " - {{INTERVAL}} {{DATE}} Open %g, Hi %g, Lo %g, Close %g (%.1f%%) Vol " +
                   WriteVal( V, 1.0 ) + " {{VALUES}}", O, H, L, C, SelectedValue( ROC( C, 1 ) ) );

priceSeries = WriteIf(price==C, "CLOSE", 
				WriteIf(price==O, "OPEN", 
					WriteIf(price==H, "HIGH", 
						WriteIf(price==L, "LOW", 
							WriteIf(price==Avg, "AVERAGE (H+L+C)/3", 
								WriteIf(price==OI, "VOLUME", 
									WriteIf(price==OI, "OPEN INT", "OTHER")))))));
                    

if( SelectedValue( SumUptrendBars OR SumDowntrendBars ) )
    Title = Title + "\nLandry's Proper Order - " + priceSeries + " - " + WriteIf( SumUptrendBars > 0, StrFormat( "UPTREND #%g", SelectedValue( SumUptrendBars ) ),
                                    StrFormat( "DOWNTREND #%g", SelectedValue( SumDowntrendBars ) ) );

(is there a better way to know which price series is chosen through ParamField() to avoid the multiple nested WriteIf() to determine its name?)

4 Likes

Thank you both so much - this is extremely helpful, and I learned some new stuff about AFL. Can't thank you both enough.

1 Like

Here is one way:

price = ParamField( "Price series", 3 );  // by default using Close
_N( priceseries = StrToUpper(StrTrim( _PARAM_VALUES(), "()" ) ) );
printf( "Priceseries=%s\n", priceseries );

Thanks. I never used the _PARAM_VALUES() function. TIL