This function uses the same implementation pattern as the EMA function.
publicclassBollingerBandsimplementsAnalyticsFunction<Map<String,Double>> {privateint deviations =2;publicBollingerBands(){} @OverridepublicMap<String,Double> compute(Number[] values,Number previousValue) {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