Bollinger bands


This example computes Bollinger bands using a custom-provided function packaged as a jar using the Joule SDK.

Use case configuration

File: app-bollingerbands-influxdb.env

SOURCEFILE=conf/sources/stockQuoteStream.yaml
ENGINEFILE=conf/usecases/slidingEventWindowBollingerBandsAnalytics.yaml
PUBLISHFILE=conf/publishers/influxdbBollingerBands.yaml

Pipeline configuration

This pipeline will compute the Bolinger Bands for the CVCO symbol over a sliding window of 5 events.

processing unit:
  pipeline:
    - filter:
      expression: "symbol == 'CVCO'"
      - user defined function:
          bollinger bands:
            parameters:
              deviations: 2
          fields: [ ask ]
          event history: 5

emit:
  select: "symbol, 
               ask_upper_BollingerBand, 
               ask_middle_BollingerBand, 
               ask_lower_BollingerBand"

Function Implementation

This function uses the same implementation pattern as the EMA function.

@AnalyticDefinition(
        id = "bollingerband",
        stateless = true,
        useRawColumn = true,
        description = "Bollinger Bands are a momentum indicator used in technical analysis."
)
@JsonRootName(value = "bollinger bands")
public class BollingerBands extends AnalyticsFunction<Map<String, Double>>  {

    private int deviations = 2;
    public BollingerBands(){
        super();
    }

    @Override
    public Map<String, Double> compute(Number[] values, Number previousValue, Context context) {

        Double mean = Arrays.stream(values).mapToDouble(d-> (double) d).sum() / values.length;
        double sqrtmean = 0.0;
        for(int i=0; i<values.length; i++){
            double s =  values[i].doubleValue() - mean;
            sqrtmean += s * s;
        }

        sqrtmean = Math.sqrt( sqrtmean / values.length);
        double band = deviations * sqrtmean;

        Map<String, Double> results = new HashMap<>();
        results.put("upper", mean + band);
        results.put("middle", mean );
        results.put("lower", mean - band);
        return results;
    }

    @Override
    public void setParameters(Properties parameters) {
        if( parameters != null && parameters.containsKey("deviations")) {
            deviations = Integer.parseInt(parameters.get("deviations").toString());
        }
    }

    @Override
    public String getVariablePostFixID() {
        return "bollingerband";
    }

For Joule to load and initialised the component the analytics class needs to be defined within the plugins.properties file under the META-INF/services directory

Example

# Change and add lines for your analytics classes
com.fractalworks.examples.banking.analytics.BollingerBands

Last updated