User defined functions
Extend the analytics ecosystem using the Analytics API
Objective
This analytic processor enables complex calculation to be executed using a provided analytical function implemented using the Analytics API. This feature also provides the ability to set a rolling number of events to be used with the calculation.
Learn different average functions which can be applied in Joule.
Average function libraryKey Features
Pluggable
Analytics API
DSL support
Example & DSL attributes
The analytic function ema
(Exponential Moving Average) is defined inline using the standard Joule DSL fragment.
user defined function:
function:
exponential moving average:
parameters:
smoothing factor: 0.33333
fields: [ ask ]
event history: 12
assign prefix: ema12
Attributes schema
fields
Fields to calculated from the event
String[]
event history
Number of rolling events to stored and used for the calculation
Integer
assign prefix
Prefix to use for the result assignment. This is used to allow the same function to be used multiple times. If this is not provided the function postfix will be applied e.g. ask_EMA
String Default: Function postfix
Further example
This example demonstrates how you would combine complex calculation with a final analytic expression to trigger an alert.
processing unit:
pipeline:
- user defined function:
function:
exponential moving average:
parameters:
smoothing factor: 0.33333
fields: [ ask ]
event history: 26
response prefix: ema26
- user defined function:
function:
exponential moving average:
parameters:
smoothing factor: 0.33333
fields: [ ask ]
event history: 12
response prefix: ema12
- analytic:
expression: "ema12_ask - ema26_ask"
assign to: macd_ask_signal
emit:
select: "symbol, macd_ask_signal"
having: "macd_ask_signal > 0.05"
Example function implementation
This is an implementation example for a custom analytics function.
Further details can be found in the Analytics API documentation.
@JsonRootName(value = "exponential moving average")
public class ExponentialMovingAverage extends AnalyticsFunction<Double> {
public static final String SMOOTH_FACTOR = "smoothing factor";
private double smoothFactor = 0.333;
public ExponentialMovingAverage() {
super();
}
@Override
public void setParameters(Properties parameters) {
if (parameters != null && parameters.containsKey(SMOOTH_FACTOR)) {
smoothFactor = Double.parseDouble(parameters.get(SMOOTH_FACTOR).toString());
}
}
@Override
public String getVariablePostFixID() {
return "EMA";
}
@Override
public Double compute(Number[] values, Number previousValue) {
if (previousValue == null) return Double.NaN;
if (Double.isNaN(previousValue.doubleValue())) {
previousValue = values[values.length - 1];
return (Double)previousValue;
}
for (Number d : values) {
previousValue = (d.doubleValue() * smoothFactor) + (previousValue.doubleValue() * (1 - smoothFactor));
}
return previousValue.doubleValue();
}
}
Last updated
Was this helpful?