mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-29 11:18:20 +08:00
ENH: Add option of instantly filling orders.
This commit is contained in:
committed by
Eddie Hebert
parent
31b85239f3
commit
65637b9430
@@ -22,6 +22,7 @@ import zipline.utils.factory as factory
|
||||
from zipline.test_algorithms import (TestRegisterTransformAlgorithm,
|
||||
RecordAlgorithm,
|
||||
TestOrderAlgorithm,
|
||||
TestOrderInstantAlgorithm,
|
||||
TestOrderValueAlgorithm,
|
||||
TestTargetAlgorithm,
|
||||
TestOrderPercentAlgorithm,
|
||||
@@ -186,3 +187,10 @@ class TestTransformAlgorithm(TestCase):
|
||||
data_frequency='daily'
|
||||
)
|
||||
algo.run(self.df)
|
||||
|
||||
def test_order_instant(self):
|
||||
algo = TestOrderInstantAlgorithm(sim_params=self.sim_params,
|
||||
data_frequency='daily',
|
||||
instant_fill=True)
|
||||
|
||||
algo.run(self.df)
|
||||
|
||||
@@ -112,6 +112,8 @@ class TradingAlgorithm(object):
|
||||
else:
|
||||
self.data_frequency = None
|
||||
|
||||
self.instant_fill = kwargs.pop('instant_fill', False)
|
||||
|
||||
# Override annualizer if set
|
||||
if 'annualizer' in kwargs:
|
||||
self.annualizer = kwargs['annualizer']
|
||||
|
||||
@@ -85,6 +85,13 @@ class AlgorithmSimulator(object):
|
||||
return self.EMISSION_TO_PERF_KEY_MAP[
|
||||
self.algo.perf_tracker.emission_rate]
|
||||
|
||||
def process_event(self, event):
|
||||
process_trade = self.algo.blotter.process_trade
|
||||
for txn, order in process_trade(event):
|
||||
self.algo.perf_tracker.process_event(txn)
|
||||
self.algo.perf_tracker.process_event(order)
|
||||
self.algo.perf_tracker.process_event(event)
|
||||
|
||||
def transform(self, stream_in):
|
||||
"""
|
||||
Main generator work loop.
|
||||
@@ -117,6 +124,8 @@ class AlgorithmSimulator(object):
|
||||
self.algo.perf_tracker.process_event(event)
|
||||
|
||||
else:
|
||||
if self.algo.instant_fill:
|
||||
events = []
|
||||
|
||||
for event in snapshot:
|
||||
if event.type == DATASOURCE_TYPE.SPLIT:
|
||||
@@ -129,12 +138,12 @@ class AlgorithmSimulator(object):
|
||||
if event.type == DATASOURCE_TYPE.BENCHMARK:
|
||||
self.algo.set_datetime(event.dt)
|
||||
bm_updated = True
|
||||
|
||||
process_trade = self.algo.blotter.process_trade
|
||||
for txn, order in process_trade(event):
|
||||
self.algo.perf_tracker.process_event(txn)
|
||||
self.algo.perf_tracker.process_event(order)
|
||||
self.algo.perf_tracker.process_event(event)
|
||||
# If we are instantly filling orders we process
|
||||
# them after handle_data().
|
||||
if not self.algo.instant_fill:
|
||||
self.process_event(event)
|
||||
else:
|
||||
events.append(event)
|
||||
|
||||
# Update our portfolio.
|
||||
self.algo.set_portfolio(
|
||||
@@ -155,6 +164,12 @@ class AlgorithmSimulator(object):
|
||||
self.algo.perf_tracker.process_event(order)
|
||||
self.algo.blotter.new_orders = []
|
||||
|
||||
# If we are instantly filling we execute orders
|
||||
# in this iteration rather than the next.
|
||||
if self.algo.instant_fill:
|
||||
for event in events:
|
||||
self.process_event(event)
|
||||
|
||||
# The benchmark is our internal clock. When it
|
||||
# updates, we need to emit a performance message.
|
||||
if bm_updated:
|
||||
|
||||
@@ -234,6 +234,24 @@ class TestOrderAlgorithm(TradingAlgorithm):
|
||||
self.order(0, 1)
|
||||
|
||||
|
||||
class TestOrderInstantAlgorithm(TradingAlgorithm):
|
||||
def initialize(self):
|
||||
self.incr = 0
|
||||
self.last_price = None
|
||||
|
||||
def handle_data(self, data):
|
||||
if self.incr == 0:
|
||||
assert 0 not in self.portfolio.positions
|
||||
else:
|
||||
assert self.portfolio.positions[0]['amount'] == \
|
||||
self.incr, "Orders not filled immediately."
|
||||
assert self.portfolio.positions[0]['last_sale_price'] == \
|
||||
self.last_price, "Orders was not filled at last price."
|
||||
self.incr += 2
|
||||
self.order_value(0, data[0].price * 2.)
|
||||
self.last_price = data[0].price
|
||||
|
||||
|
||||
class TestOrderValueAlgorithm(TradingAlgorithm):
|
||||
def initialize(self):
|
||||
self.incr = 0
|
||||
|
||||
Reference in New Issue
Block a user