Add configurable candlestick window types
This commit is contained in:
17
src/main/java/ats/plugin/CandlestickWindow.java
Normal file
17
src/main/java/ats/plugin/CandlestickWindow.java
Normal file
@ -0,0 +1,17 @@
|
||||
package ats.plugin;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
/**
|
||||
* A CandlestickWindow runs a CandlestickCalc across a number of
|
||||
* ticks and sends
|
||||
*/
|
||||
interface CandlestickWindow {
|
||||
public enum Type { time, ticks };
|
||||
|
||||
/**
|
||||
* Process a tick with the given time and value.
|
||||
*/
|
||||
public void update(DateTime timestamp, double value);
|
||||
|
||||
}
|
||||
@ -22,8 +22,8 @@ public class OHLCPlugInView extends ViewSupport {
|
||||
private final AgentInstanceViewFactoryChainContext context;
|
||||
private final ExprNode timestampExpression;
|
||||
private final ExprNode valueExpression;
|
||||
private DurationWindow window;
|
||||
private EventAdapterService service;
|
||||
private CandlestickWindow window;
|
||||
private EventAdapterService service;
|
||||
private EventBean[] lastData;
|
||||
|
||||
|
||||
@ -42,8 +42,8 @@ public class OHLCPlugInView extends ViewSupport {
|
||||
this.valueExpression = valueExpression;
|
||||
service = context.getStatementContext().getEventAdapterService();
|
||||
|
||||
window = new DurationWindow(this, calc, context, intervalExpression);
|
||||
CandlestickCalc calc = chooseCalc(calcTypeExpression);
|
||||
window = chooseWindow(context, timeTypeExpression, intervalExpression, calc);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,6 +62,27 @@ public class OHLCPlugInView extends ViewSupport {
|
||||
return new OHLCCandlestickCalc();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the proper window according to the value of the
|
||||
* calc type parameter.
|
||||
* @param intervalExpression
|
||||
*/
|
||||
private CandlestickWindow chooseWindow(AgentInstanceViewFactoryChainContext context,
|
||||
ExprNode timeTypeExpression,
|
||||
ExprNode intervalExpression,
|
||||
CandlestickCalc calc)
|
||||
{
|
||||
String timeType = exprNodeValue(timeTypeExpression);
|
||||
|
||||
if (CandlestickWindow.Type.valueOf(timeType) == CandlestickWindow.Type.time) {
|
||||
log.info("Using time based window type");
|
||||
return new TimeCandlestickWindow(this, calc, context, intervalExpression);
|
||||
}
|
||||
|
||||
log.info("Using ticks based window type");
|
||||
return new TicksCandlestickWindow(this, calc, context, intervalExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the string value of a node.
|
||||
*/
|
||||
|
||||
87
src/main/java/ats/plugin/TicksCandlestickWindow.java
Normal file
87
src/main/java/ats/plugin/TicksCandlestickWindow.java
Normal file
@ -0,0 +1,87 @@
|
||||
package ats.plugin;
|
||||
|
||||
import com.espertech.esper.core.context.util.AgentInstanceViewFactoryChainContext;
|
||||
import com.espertech.esper.epl.expression.core.ExprEvaluator;
|
||||
import com.espertech.esper.epl.expression.core.ExprNode;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* TicksCandlestickWindow runs a CandlestickCalc across a set number
|
||||
* of ticks for each window.
|
||||
*/
|
||||
class TicksCandlestickWindow implements CandlestickWindow {
|
||||
private static final Logger log = LoggerFactory.getLogger(TicksCandlestickWindow.class);
|
||||
private final AgentInstanceViewFactoryChainContext context;
|
||||
/** How many ticks in each window? */
|
||||
private final long windowTicks;
|
||||
private OHLCPlugInView plugin;
|
||||
private CandlestickCalc calc;
|
||||
/** How many ticks into the window we are. */
|
||||
private long currentTick = 0;
|
||||
/** The time the window started. */
|
||||
private DateTime windowStartTime;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new window that calculates across a set number of
|
||||
* ticks.
|
||||
*/
|
||||
public TicksCandlestickWindow(OHLCPlugInView plugin,
|
||||
CandlestickCalc calc,
|
||||
AgentInstanceViewFactoryChainContext context,
|
||||
ExprNode intervalExpression)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.calc = calc;
|
||||
this.context = context;
|
||||
windowTicks = parseTickCount(intervalExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the time period specified by the given expression value.
|
||||
*/
|
||||
private long parseTickCount(ExprNode intervalExpression) {
|
||||
ExprEvaluator evaluator = intervalExpression.getForge().getExprEvaluator();
|
||||
Object o = evaluator.evaluate(null, true, context);
|
||||
log.warn("OBJECT " + o.getClass());
|
||||
return new Long((Integer)o).longValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a tick with the given time and value.
|
||||
*/
|
||||
public void update(DateTime timestamp, double value) {
|
||||
ensureWindow(timestamp);
|
||||
calc.applyValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure our window times are set up and current.
|
||||
* @param timestamp
|
||||
*/
|
||||
public void ensureWindow(DateTime timestamp) {
|
||||
if (windowStartTime == null)
|
||||
windowStartTime = timestamp;
|
||||
|
||||
currentTick++;
|
||||
log.info("tick ", currentTick);
|
||||
|
||||
if (currentTick < windowTicks) return;
|
||||
|
||||
OHLCValues values = calc.getValues();
|
||||
if (values == null) {
|
||||
log.info("No data to post");
|
||||
return;
|
||||
}
|
||||
|
||||
plugin.postEvent(new OHLCEvent(windowStartTime, values));
|
||||
|
||||
// reset for next window
|
||||
calc.reset();
|
||||
currentTick = 0;
|
||||
windowStartTime = null;
|
||||
}
|
||||
}
|
||||
@ -17,10 +17,11 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* DurationWindow TODO
|
||||
* TimeCandlestickWindow runs a CandlestickCalc across ticks for a set
|
||||
* duration each window.
|
||||
*/
|
||||
class DurationWindow {
|
||||
private static final Logger log = LoggerFactory.getLogger(DurationWindow.class);
|
||||
class TimeCandlestickWindow implements CandlestickWindow {
|
||||
private static final Logger log = LoggerFactory.getLogger(TimeCandlestickWindow.class);
|
||||
private static final int LATE_EVENT_SLACK_SECONDS = 5;
|
||||
private static final PeriodFormatter periodFormatter = new PeriodFormatterBuilder()
|
||||
.appendDays().appendSuffix("d")
|
||||
@ -39,10 +40,13 @@ class DurationWindow {
|
||||
private DateTime lastStartTime;
|
||||
|
||||
|
||||
public DurationWindow(OHLCPlugInView plugin,
|
||||
CandlestickCalc calc,
|
||||
AgentInstanceViewFactoryChainContext context,
|
||||
ExprNode intervalExpression)
|
||||
/**
|
||||
* Create a window over the given duration.
|
||||
*/
|
||||
public TimeCandlestickWindow(OHLCPlugInView plugin,
|
||||
CandlestickCalc calc,
|
||||
AgentInstanceViewFactoryChainContext context,
|
||||
ExprNode intervalExpression)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.calc = calc;
|
||||
@ -161,7 +165,7 @@ class DurationWindow {
|
||||
public void scheduledTrigger(EngineLevelExtensionServicesContext esc) {
|
||||
handle = null; // clear out schedule handle
|
||||
// log.info("Callback running");
|
||||
DurationWindow.this.postData();
|
||||
TimeCandlestickWindow.this.postData();
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user