Use Case 5

Goal

Implement Tushar S. Chande's VIDYA as published in Stock&Commodities V10:3. Corresponding EasyLanguage is:
User Function
Inputs:Length(NumericSimple), Smooth(NumericSimple);
Vars: Up(0), Dn(0), UpSum(0), DnSum(0), AbsCMO(0), SC(0);
Up=IFF(Close>Close[1], Close-Close[1],0);
Dn=IFF(Close<Close[1],AbsValue(Close-Close[1]),0);
UpSum=Summation(Up,Length);
DnSum=Summation(Dn,Length);
If UpSum+DnSum >0 then
AbsCMO=AbsValue((UpSum-DnSum)/(UpSum+DnSum));
SC= 2/(Smooth+1);
If Currentbar=Length then VIDYA=close;
If Currentbar>Length then
VIDYA=(SC*AbsCMO*Close)+((1-(SC*AbsCMO))*VIDYA[1]);

Indicator
Inputs: Length(9), Smooth(12),PCT(1);
Value1=VIDYA(Length,Smooth):
If Value1>0 then begin
    Plot1(Value1,"VIDYA");
    Plot2(Value1*((100+PCT)/100),"UpBand");
    Plot3(Value1*((100-PCT)/100),"DnBand");
End;

Solution

Define the indicator:

class VIDYA extends VarBuilder
{
    private Var up, dn;
    private double length, sc;
    Out midLine, upBand, dnBand;

    // Constructor
    VIDYA( double pLength, double pSmooth )
    {
       length = pLength;
       sc     = 2.0/(pSmooth+1.0);
    }

    pre()
    {
       midLine = mapOut( "VIDYA"  );
       upBand  = mapOut( "UpBand" ):
       dnBand  = mapOut( "DnBand" );
    }

    iter()
    { 
       if( input > input.previous() )
          up.data = input-input.previous();
       else
          up.data = 0.0;

       if( input.previous() > input )
          dn.data = input.previous()-input;
       else
          dn.data = 0.0;

       double upsum  = dn.sum(length);
       double dnsum  = up.sum(length);
       double absCMO = 0.0;

       if( upsum+dnsum > 0.0 )
          absCMO = abs((upsum-dnsum)/(upsum+dnsum));

       if( !midLine.valid )
          midLine.data = input.data;      
       else
          midLine.data = (sc*absCMO*input)+((1.0-(sc*absCMO))*midLine.previous());

       upBand.data  = midLine * (101.0/100.0);
       dnBand.data  = midLine * ( 99.0/100.0);
   }
}

In the indicator definition, "input" represents the default variable of the input time series. See UC-1 for an example where non-default inputs are used.

Example of usage of the new indicator:

// Get Microsoft market data.
TimeSeries ts1 = db.get("US.NASDAQ.STOCK", "MSFT");

// Use ts1 as input and ts2 will refer to the output.
VIDYA vidya = new VIDYA(9,12);
TimeSeries ts2 = vidya.exec(ts1);

// Display the output.
for( int i=0; i < ts2.size; i++ )
{
   print ts2.get("VIDYA").data[i];
   print ts2.get("UpBand").data[i];
   print ts2.get("DnBand").data[i];
}
 

WARNING: Work in progress, solution provided is a vague proposal in no particular language and is VERY likely to change as the design/interface is defined.