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 AgentInstanceViewFactoryChainContext context;
|
||||||
private final ExprNode timestampExpression;
|
private final ExprNode timestampExpression;
|
||||||
private final ExprNode valueExpression;
|
private final ExprNode valueExpression;
|
||||||
private DurationWindow window;
|
private CandlestickWindow window;
|
||||||
private EventAdapterService service;
|
private EventAdapterService service;
|
||||||
private EventBean[] lastData;
|
private EventBean[] lastData;
|
||||||
|
|
||||||
|
|
||||||
@ -42,8 +42,8 @@ public class OHLCPlugInView extends ViewSupport {
|
|||||||
this.valueExpression = valueExpression;
|
this.valueExpression = valueExpression;
|
||||||
service = context.getStatementContext().getEventAdapterService();
|
service = context.getStatementContext().getEventAdapterService();
|
||||||
|
|
||||||
window = new DurationWindow(this, calc, context, intervalExpression);
|
|
||||||
CandlestickCalc calc = chooseCalc(calcTypeExpression);
|
CandlestickCalc calc = chooseCalc(calcTypeExpression);
|
||||||
|
window = chooseWindow(context, timeTypeExpression, intervalExpression, calc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,6 +62,27 @@ public class OHLCPlugInView extends ViewSupport {
|
|||||||
return new OHLCCandlestickCalc();
|
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.
|
* 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;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DurationWindow TODO
|
* TimeCandlestickWindow runs a CandlestickCalc across ticks for a set
|
||||||
|
* duration each window.
|
||||||
*/
|
*/
|
||||||
class DurationWindow {
|
class TimeCandlestickWindow implements CandlestickWindow {
|
||||||
private static final Logger log = LoggerFactory.getLogger(DurationWindow.class);
|
private static final Logger log = LoggerFactory.getLogger(TimeCandlestickWindow.class);
|
||||||
private static final int LATE_EVENT_SLACK_SECONDS = 5;
|
private static final int LATE_EVENT_SLACK_SECONDS = 5;
|
||||||
private static final PeriodFormatter periodFormatter = new PeriodFormatterBuilder()
|
private static final PeriodFormatter periodFormatter = new PeriodFormatterBuilder()
|
||||||
.appendDays().appendSuffix("d")
|
.appendDays().appendSuffix("d")
|
||||||
@ -39,10 +40,13 @@ class DurationWindow {
|
|||||||
private DateTime lastStartTime;
|
private DateTime lastStartTime;
|
||||||
|
|
||||||
|
|
||||||
public DurationWindow(OHLCPlugInView plugin,
|
/**
|
||||||
CandlestickCalc calc,
|
* Create a window over the given duration.
|
||||||
AgentInstanceViewFactoryChainContext context,
|
*/
|
||||||
ExprNode intervalExpression)
|
public TimeCandlestickWindow(OHLCPlugInView plugin,
|
||||||
|
CandlestickCalc calc,
|
||||||
|
AgentInstanceViewFactoryChainContext context,
|
||||||
|
ExprNode intervalExpression)
|
||||||
{
|
{
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.calc = calc;
|
this.calc = calc;
|
||||||
@ -161,7 +165,7 @@ class DurationWindow {
|
|||||||
public void scheduledTrigger(EngineLevelExtensionServicesContext esc) {
|
public void scheduledTrigger(EngineLevelExtensionServicesContext esc) {
|
||||||
handle = null; // clear out schedule handle
|
handle = null; // clear out schedule handle
|
||||||
// log.info("Callback running");
|
// log.info("Callback running");
|
||||||
DurationWindow.this.postData();
|
TimeCandlestickWindow.this.postData();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Reference in New Issue
Block a user