mirror of
https://github.com/wassname/catalyst.git
synced 2026-09-09 11:19:23 +08:00
ENH: Added informative message for calling order in init.
Previously, calling order() in initalize resulted in a weird stack trace. It now returns a well formulated error that is readable to the user through the API. Adding a slippage kwarg to test_algorithm and simfactor was necessary because slippage can only be called during init. Previously initaliazed was never set to true and calls to init-only function were sprinkled around the code in non-init sections. Code changes were to enforce init-only rules.
This commit is contained in:
+16
-1
@@ -29,6 +29,7 @@ import zipline.utils.factory as factory
|
||||
import zipline.utils.simfactory as simfactory
|
||||
|
||||
from zipline.errors import (
|
||||
OrderDuringInitialize,
|
||||
RegisterTradingControlPostInit,
|
||||
TradingControlViolation,
|
||||
)
|
||||
@@ -53,6 +54,7 @@ from zipline.test_algorithms import (
|
||||
api_algo,
|
||||
api_symbol_algo,
|
||||
call_all_order_methods,
|
||||
call_order_in_init,
|
||||
handle_data_api,
|
||||
handle_data_noop,
|
||||
initialize_api,
|
||||
@@ -585,7 +587,8 @@ def handle_data(context, data):
|
||||
self._algo_record_float_magic_should_pass('nan')
|
||||
|
||||
def test_order_methods(self):
|
||||
"""Only test that order methods can be called without error.
|
||||
"""
|
||||
Only test that order methods can be called without error.
|
||||
Correct filling of orders is tested in zipline.
|
||||
"""
|
||||
test_algo = TradingAlgorithm(
|
||||
@@ -602,6 +605,18 @@ def handle_data(context, data):
|
||||
|
||||
output, _ = drain_zipline(self, zipline)
|
||||
|
||||
def test_order_in_init(self):
|
||||
"""
|
||||
Test that calling order in initialize
|
||||
will return an error
|
||||
"""
|
||||
with self.assertRaises(OrderDuringInitialize):
|
||||
test_algo = TradingAlgorithm(
|
||||
script=call_order_in_init,
|
||||
sim_params=self.sim_params,
|
||||
)
|
||||
set_algo_instance(test_algo)
|
||||
|
||||
|
||||
class TestHistory(TestCase):
|
||||
def test_history(self):
|
||||
|
||||
@@ -27,6 +27,7 @@ from six import iteritems, exec_
|
||||
from operator import attrgetter
|
||||
|
||||
from zipline.errors import (
|
||||
OrderDuringInitialize,
|
||||
OverrideCommissionPostInit,
|
||||
OverrideSlippagePostInit,
|
||||
RegisterTradingControlPostInit,
|
||||
@@ -76,7 +77,6 @@ DEFAULT_CAPITAL_BASE = float("1.0e5")
|
||||
|
||||
|
||||
class TradingAlgorithm(object):
|
||||
|
||||
"""
|
||||
Base class for trading algorithms. Inherit and overload
|
||||
initialize() and handle_data(data).
|
||||
@@ -531,6 +531,13 @@ class TradingAlgorithm(object):
|
||||
|
||||
Raises an UnsupportedOrderParameters if invalid arguments are found.
|
||||
"""
|
||||
|
||||
# Make sure we're not in init before we order.
|
||||
if not self.initialized:
|
||||
raise OrderDuringInitialize(
|
||||
msg="order() can only be called from within handle_data()"
|
||||
)
|
||||
|
||||
if style:
|
||||
if limit_price:
|
||||
raise UnsupportedOrderParameters(
|
||||
|
||||
@@ -137,6 +137,13 @@ class UnsupportedOrderParameters(ZiplineError):
|
||||
msg = "{msg}"
|
||||
|
||||
|
||||
class OrderDuringInitialize(ZiplineError):
|
||||
"""
|
||||
Raised if order is called during initialize()
|
||||
"""
|
||||
msg = "{msg}"
|
||||
|
||||
|
||||
class TradingControlViolation(ZiplineError):
|
||||
"""
|
||||
Raised if an order would violate a constraint set by a TradingControl.
|
||||
|
||||
@@ -97,7 +97,12 @@ class TestAlgorithm(TradingAlgorithm):
|
||||
at the close of a simulation.
|
||||
"""
|
||||
|
||||
def initialize(self, sid, amount, order_count, sid_filter=None):
|
||||
def initialize(self,
|
||||
sid,
|
||||
amount,
|
||||
order_count,
|
||||
sid_filter=None,
|
||||
slippage=None):
|
||||
self.count = order_count
|
||||
self.sid = sid
|
||||
self.amount = amount
|
||||
@@ -108,6 +113,9 @@ class TestAlgorithm(TradingAlgorithm):
|
||||
else:
|
||||
self.sid_filter = [self.sid]
|
||||
|
||||
if slippage is not None:
|
||||
self.set_slippage(slippage)
|
||||
|
||||
def handle_data(self, data):
|
||||
# place an order for amount shares of sid
|
||||
if self.incr < self.count:
|
||||
@@ -241,7 +249,6 @@ class RecordAlgorithm(TradingAlgorithm):
|
||||
class TestOrderAlgorithm(TradingAlgorithm):
|
||||
def initialize(self):
|
||||
self.incr = 0
|
||||
self.sale_price = None
|
||||
|
||||
def handle_data(self, data):
|
||||
if self.incr == 0:
|
||||
@@ -633,6 +640,7 @@ class BatchTransformAlgorithm(TradingAlgorithm):
|
||||
self.iter = 0
|
||||
|
||||
self.set_slippage(FixedSlippage())
|
||||
self.initialized = True
|
||||
|
||||
def handle_data(self, data):
|
||||
self.history_return_price_class.append(
|
||||
@@ -943,6 +951,17 @@ def handle_data(context, data):
|
||||
order(symbol(0), 1)
|
||||
"""
|
||||
|
||||
call_order_in_init = """
|
||||
from zipline.api import (order)
|
||||
|
||||
def initialize(context):
|
||||
order(0, 10)
|
||||
pass
|
||||
|
||||
def handle_data(context, data):
|
||||
pass
|
||||
"""
|
||||
|
||||
call_all_order_methods = """
|
||||
from zipline.api import (order,
|
||||
order_value,
|
||||
|
||||
@@ -62,7 +62,8 @@ def create_test_zipline(**config):
|
||||
order_amount,
|
||||
order_count,
|
||||
sim_params=config.get('sim_params',
|
||||
factory.create_simulation_parameters())
|
||||
factory.create_simulation_parameters()),
|
||||
slippage=config.get('slippage'),
|
||||
)
|
||||
|
||||
# -------------------
|
||||
@@ -94,13 +95,6 @@ def create_test_zipline(**config):
|
||||
if transforms is not None:
|
||||
test_algo.set_transforms(transforms)
|
||||
|
||||
# -------------------
|
||||
# Slippage
|
||||
# ------------------
|
||||
slippage = config.get('slippage', None)
|
||||
if slippage is not None:
|
||||
test_algo.set_slippage(slippage)
|
||||
|
||||
# ------------------
|
||||
# generator/simulator
|
||||
sim = test_algo.get_generator()
|
||||
|
||||
Reference in New Issue
Block a user