Files
ATS_Esper/epl/trading_system_1.epl
2018-11-14 20:54:27 -08:00

285 lines
9.8 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- trading_system_1.epl
--
-- Statements must be separated by an empty line.
--
-- Setup variables
--
-- The time the trading logic will begin to enter trades.
-- Exiting trades is 24/7.
create constant variable DateTime TradingStartTime = EPLHelpers.parseTime("00:00")
-- The time the trading logic will no longer enter trades.
-- Exiting trades is 24/7.
create constant variable DateTime TradingEndTime = EPLHelpers.parseTime("23:59")
-- The time frame for OHLC calculation.
-- Example values: '5s', '1m', '1h 30m', '2h', '12h', '1d'.
create constant variable string OHLCInterval = '10s'
-- The number of ticks for OHLC TB calculation.
create constant variable int OHLCTicks = 100
-- Amount to be traded, measured in units.
create constant variable int TradeSize = 10
-- How many events to use for simple moving average calculation
create constant variable int SMASize = 5
-- How many events to store for Ref() access
create constant variable int RefSize = 5
--
-- A named window that contains the current tick
--
-- Define the window as length 1, using the structure of the TickEvent
-- java class to describe what the window contains.
create window CurrentTick#length(1) as TickEvent
-- Describe how events get added to the window. This runs every time
-- a new TickEvent is posted.
insert into CurrentTick select * from TickEvent
--
-- Trading window
--
-- InTradingHours will be set to true when the current time is between
-- TradingStartTime and TradingEndTime.
create variable bool InTradingHours = false
-- Update on each tick
on TickEvent as t
set InTradingHours = EPLHelpers.inTimeRange(t.time, TradingStartTime, TradingEndTime)
--
-- A stream of OHLC values calculated from TickEvents
--
-- Send every TickEvent to the OHLC plugin. The plugin will post an
-- OHLCEvent to OHLCStream every OHLCInterval amount of time. It uses
-- TickEvent.time ("time") as the source of the timestamp, and uses
-- TickEvent.midDouble() as the value to use in the OHLC calculation.
create variant schema OHLCStream as OHLCEvent
insert into OHLCStream
select * from TickEvent#OHLC("OHLC", "time", OHLCInterval, time, midDouble)
-- Send every TickEvent to the OHLC plugin. The plugin will post an
-- OHLCEvent using Heikin-Ashi calculations to HKStream every
-- OHLCInterval amount of time. It uses TickEvent.midDouble() as the
-- value to use in the OHLC calculation.
create variant schema HKStream as OHLCEvent
insert into HKStream
select * from TickEvent#OHLC("HeikinAshi", "time", OHLCInterval, time, midDouble)
-- Send every TickEvent to the OHLC plugin. The plugin will post an
-- OHLCEvent to TBStream every OHLCTicks ticks. It uses
-- TickEvent.time ("time") as the source of the timestamp, and uses
-- TickEvent.midDouble() as the value to use in the OHLC calculation.
create variant schema TBStream as OHLCEvent
insert into TBStream
select * from TickEvent#OHLC("HeikinAshi", "ticks", OHLCTicks, time, midDouble)
-- Send every TickEvent to the OHLC plugin. The plugin will post an
-- OHLCEvent using Heikin-Ashi calculations to TBHKStream every
-- OHLCTicks ticks. It uses TickEvent.midDouble() as the value to use
-- in the OHLC calculation.
create variant schema TBHKStream as OHLCEvent
insert into TBHKStream
select * from TickEvent#OHLC("HeikinAshi", "ticks", OHLCTicks, time, midDouble)
--
-- Simple moving average streams
--
-- SMACloseStream bundles a simple moving average of the close values
-- with the values of the OHLCStream.
create schema SMACloseStream as (time DateTime,
open double,
high double,
low double,
close double,
averageClose double)
-- Average the most recent OHLC close values from OHLCStream and
-- post an event that contains open, high, low, close, and
-- SMA(close). The number of OHLC events used in the SMA calc is set
-- by the SMASize variable.
insert into SMACloseStream
select time, open, high, low, close, Avg(close) as averageClose
from OHLCStream#length(SMASize)
--
-- ValueWhen calculations
--
-- A stream that feeds B1 and B2. Each event contains a double
-- precision floating point value "low", and a timestamp called
-- "time".
create schema BStream as (low double, time DateTime)
-- Listen to the last "RefSize" number of SMACloseStream events. Look
-- for an OHLC bar with a lower average close than its neighbors. Add
-- that bar's low value and its timestamp to the stream.
insert into BStream
select prev(1, low) as low, prev(1, time) as time from SMACloseStream#length(RefSize)
where prev(0, averageClose) > prev(1, averageClose)
and prev(1, averageClose) < prev(2, averageClose)
-- Define B1 to contain the same fields as BStream
create schema B1 (low double, time DateTime)
-- B1 contains the most recent low value and time from BStream.
-- This is the last time an average close was lower
-- than the ones before and after.
-- Since the time is included in the event, no separate BT1 is needed.
insert into B1 select prev(0, low) as low, prev(0, time) as time
from BStream#length(RefSize)
-- B2 contains the *second* most recent occurrence in BStream, but is
-- otherwise the same as B1.
create schema B2 (low double, time DateTime)
insert into B2 select prev(1, low) as low, prev(1, time) as time
from BStream#length(RefSize)
-- A stream that feeds P1 and P2.
create schema PStream as (low double, time DateTime)
-- Find an OHLC bar with a higher average close than its neighbors.
-- Add that low value and its timestamp to the stream.
insert into PStream
select prev(1, low) as low, prev(1, time) as time from SMACloseStream#length(RefSize)
where prev(0, averageClose) < prev(1, averageClose)
and prev(1, averageClose) > prev(2, averageClose)
-- P1 contains the most recent low value and time from PStream.
-- This is the last time an average close was higher
-- than the ones before and after.
-- Since the time is included in the event, no separate PT1 is needed.
create schema P1 (low double, time DateTime)
insert into P1 select prev(0, low) as low, prev(0, time) as time
from PStream#length(RefSize)
-- P2 contains the second most recent occurrence in PStream.
create schema P2 (low double, time DateTime)
insert into P2 select prev(1, low) as low, prev(1, time) as time
from PStream#length(RefSize)
--
-- Long entry
--
-- A helper for LE calc. Keep track of the highest OHLC high value.
create window MaxHigh3Window#length(1) as (high double)
-- Post the largest high value on OHLCStream from the most recent
-- three bars.
insert into MaxHigh3Window
select max(high) as high from OHLCStream#length(3)
-- Long entry events contain the current tick's midpoint value,
-- timestamp, and instrument name.
create schema LongEntryStream as (current BigDecimal, time DateTime, instrument String)
-- The long entry calc below is translated from this entry in the
-- spreadsheet:
--
-- LE = C > HHV(High,3)
-- and B1 < B2
-- and P1 < P2
-- and BT1 > PT1
-- and BT2 > PT2
-- and PT1 > BT2
insert into LongEntryStream
select C.mid as current, C.time as time, C.instrument as instrument
from CurrentTick as C,
MaxHigh3Window as T,
B1#lastevent, B2#lastevent,
P1#lastevent, P2#lastevent
where C.mid > T.high
and B1.low < B2.low
and P1.low < P2.low
and EPLHelpers.laterThan(B1.time, P1.time)
and EPLHelpers.laterThan(B2.time, P2.time)
and EPLHelpers.laterThan(P1.time, B2.time)
and InTradingHours
-- Because multiple streams feed LongEntryStream (CurrentTick,
-- MaxHigh3Window, B1, B2...), an event on any of those streams causes
-- the LongEntryStream logic above to be triggered. This often causes
-- multiple LongEntryStream events to be generated for a single tick
-- when several of the feeder streams are updated at the same time.
--
-- LongEntryDistinct filters out duplicate LongEntryStream events,
-- leaving a maximum of one event per tick.
create schema LongEntryDistinct as (current BigDecimal, time DateTime,
instrument String, units int)
insert into LongEntryDistinct
select le.current as current, le.time as time,
le.instrument as instrument, TradeSize as units
from pattern [every-distinct(le.time) le=LongEntryStream]
--
-- Event logging
--
-- Log events consist of the stream name and an event description.
create schema LogStream as (stream string, event string)
-- Enable logging the events on specific streams by uncommenting
-- individual lines below. Depending on ongoing debugging needs, some
-- of these can be either helpful or too noisy. Comment/uncomment as
-- you see fit.
insert into LogStream select 'TickEvent' as stream, EPLHelpers.str(*) as event from TickEvent
insert into LogStream select 'OHLCStream' as stream, EPLHelpers.str(*) as event from OHLCStream
-- insert into LogStream select 'BStream' as stream, EPLHelpers.str(*) as event from BStream
-- insert into LogStream select 'PStream' as stream, EPLHelpers.str(*) as event from PStream
insert into LogStream select 'B1' as stream, EPLHelpers.str(*) as event from B1
insert into LogStream select 'B2' as stream, EPLHelpers.str(*) as event from B2
insert into LogStream select 'P1' as stream, EPLHelpers.str(*) as event from P1
insert into LogStream select 'P2' as stream, EPLHelpers.str(*) as event from P2
-- insert into LogStream select 'MaxHigh3Window' as stream, EPLHelpers.str(*) as event from MaxHigh3Window
-- insert into LogStream select 'LongEntryStream' as stream, EPLHelpers.str(*) as event from LongEntryStream
-- insert into LogStream select 'LongEntryDistinct' as stream, EPLHelpers.str(*) as event from LongEntryDistinct
-- TODO (for Seth): look into LogSink http://esper.espertech.com/release-7.1.0/esper-reference/html/dataflow.html#dataflow-reference-logsink