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:2fields: [ ask ]event history:5emit: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")publicclassBollingerBandsextendsAnalyticsFunction<Map<String,Double>> {privateint deviations =2;publicBollingerBands(){ super(); } @OverridepublicMap<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 =newHashMap<>();results.put("upper", mean + band);results.put("middle", mean );results.put("lower", mean - band);return results; } @OverridepublicvoidsetParameters(Properties parameters) {if( parameters !=null&¶meters.containsKey("deviations")) { deviations =Integer.parseInt(parameters.get("deviations").toString()); } } @OverridepublicStringgetVariablePostFixID() {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 classescom.fractalworks.examples.banking.analytics.BollingerBands