From d1225c27d17f490aa082ae9f1ec181102fc33789 Mon Sep 17 00:00:00 2001 From: Seth Ladygo Date: Fri, 2 Nov 2018 11:56:10 -0700 Subject: [PATCH] Make candlestick calc configurable --- src/main/java/ats/plugin/CandlestickCalc.java | 1 + .../ats/plugin/HeikinAshiCandlestickCalc.java | 57 +++++++++++++++++++ src/main/java/ats/plugin/OHLCPlugInView.java | 29 +++++++++- 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/main/java/ats/plugin/HeikinAshiCandlestickCalc.java diff --git a/src/main/java/ats/plugin/CandlestickCalc.java b/src/main/java/ats/plugin/CandlestickCalc.java index e9ee70d..2a539ce 100644 --- a/src/main/java/ats/plugin/CandlestickCalc.java +++ b/src/main/java/ats/plugin/CandlestickCalc.java @@ -5,6 +5,7 @@ package ats.plugin; * values. For example, OHLC or Heikin-Ashi. */ interface CandlestickCalc { + public enum Type { OHLC, HeikinAshi }; /** * Reset the calculation for the beginning of an interval. diff --git a/src/main/java/ats/plugin/HeikinAshiCandlestickCalc.java b/src/main/java/ats/plugin/HeikinAshiCandlestickCalc.java new file mode 100644 index 0000000..c832c4e --- /dev/null +++ b/src/main/java/ats/plugin/HeikinAshiCandlestickCalc.java @@ -0,0 +1,57 @@ +package ats.plugin; + +/** + * HeikinAshiCandlestickCalc calculates values using the Heikin-Ashi + * technique. + */ +class HeikinAshiCandlestickCalc implements CandlestickCalc { + private Double open; + private Double close; + private Double high; + private Double low; + + + /** + * Reset the calculation for the beginning of an interval. + */ + @Override + public void reset() { + open = null; + close = null; + high = null; + low = null; + } + + /** + * Accept a current tick value to apply to the current + * calculations. + */ + @Override + public void applyValue(double value) { + if (open == null) { + open = value; + } + + close = value; + + if (low == null) { + low = value; + } else if (low.compareTo(value) > 0) { + low = value; + } + + if (high == null) { + high = value; + } else if (high.compareTo(value) < 0) { + high = value; + } + } + + /** + * Return our calculated values up to now. + */ + @Override + public OHLCValues getValues() { + return new OHLCValues(open, high, low, close); + } +} diff --git a/src/main/java/ats/plugin/OHLCPlugInView.java b/src/main/java/ats/plugin/OHLCPlugInView.java index df288c2..3a3a2fe 100644 --- a/src/main/java/ats/plugin/OHLCPlugInView.java +++ b/src/main/java/ats/plugin/OHLCPlugInView.java @@ -27,6 +27,9 @@ public class OHLCPlugInView extends ViewSupport { private EventBean[] lastData; + /** + * Create a new plugin. + */ public OHLCPlugInView(AgentInstanceViewFactoryChainContext context, ExprNode calcTypeExpression, ExprNode timeTypeExpression, @@ -39,8 +42,32 @@ public class OHLCPlugInView extends ViewSupport { this.valueExpression = valueExpression; service = context.getStatementContext().getEventAdapterService(); - CandlestickCalc calc = new OHLCCandlestickCalc(); window = new DurationWindow(this, calc, context, intervalExpression); + CandlestickCalc calc = chooseCalc(calcTypeExpression); + } + + /** + * Return the proper CandlestickCalc according to the value of the + * calc type parameter. + */ + private CandlestickCalc chooseCalc(ExprNode calcTypeExpression) { + String calcType = exprNodeValue(calcTypeExpression); + + if (CandlestickCalc.Type.valueOf(calcType) == CandlestickCalc.Type.HeikinAshi) { + log.info("Using Heikin-Ashi calc type"); + return new HeikinAshiCandlestickCalc(); + } + + log.info("Using OHLC calc type"); + return new OHLCCandlestickCalc(); + } + + /** + * Return the string value of a node. + */ + private String exprNodeValue(ExprNode node) { + ExprEvaluator evaluator = node.getForge().getExprEvaluator(); + return (String)evaluator.evaluate(null, true, context); } /**