MAINT: added typed errors module

- added exceptions in place of asserts for expected fields for rolling
transforms.
- removed assertions with Messages in favor of typed exceptions.
This commit is contained in:
fawce
2013-03-18 14:52:51 -04:00
committed by Eddie Hebert
parent 9ad33ec941
commit 890762bde7
7 changed files with 130 additions and 61 deletions
-40
View File
@@ -1,40 +0,0 @@
# ---------------------
# Error Messages.
# User facing.
# ---------------------
class ERRORS(object):
# Raised if a user script calls the override_slippage magic
# with a slipage object that isn't a VolumeShareSlippage or
# FixedSlipapge
UNSUPPORTED_SLIPPAGE_MODEL = """
You attempted to override slippage with an unsupported class. \
Please use VolumeShareSlippage or FixedSlippage.
""".strip()
# Raised if a users script calls override_slippage magic
# after the initialize method has returned.
OVERRIDE_SLIPPAGE_POST_INIT = """
You attempted to override slippage after the simulation has \
started. You may only call override_slippage in your initialize \
method.
""".strip()
# Raised if a user script calls the override_commission magic
# with a commission object that isn't a PerShare or
# PerTrade commission
UNSUPPORTED_COMMISSION_MODEL = """
You attempted to override commission with an unsupported class. \
Please use PerShare or PerTrade.
""".strip()
# Raised if a users script calls override_commission magic
# after the initialize method has returned.
OVERRIDE_COMMISSION_POST_INIT = """
You attempted to override commission after the simulation has \
started. You may only call override_commission in your initialize \
method.
""".strip()
+12 -7
View File
@@ -23,6 +23,12 @@ from datetime import datetime
from itertools import groupby
from operator import attrgetter
from zipline.errors import (
UnsupportedSlippageModel,
OverrideSlippagePostInit,
UnsupportedCommissionModel,
OverrideCommissionPostInit
)
from zipline.sources import DataFrameSource, DataPanelSource
from zipline.utils.factory import create_simulation_parameters
from zipline.transforms.utils import StatefulTransform
@@ -40,7 +46,6 @@ from zipline.gens.composites import (
alias_dt
)
from zipline.gens.tradesimulation import TradeSimulationClient as tsc
from zipline import MESSAGES
DEFAULT_CAPITAL_BASE = float("1.0e5")
@@ -319,18 +324,18 @@ class TradingAlgorithm(object):
self.trading_client.ordering_client.transact = transact
def set_slippage(self, slippage):
assert isinstance(slippage, (VolumeShareSlippage, FixedSlippage)), \
MESSAGES.ERRORS.UNSUPPORTED_SLIPPAGE_MODEL
if not isinstance(slippage, (VolumeShareSlippage, FixedSlippage)):
raise UnsupportedSlippageModel()
if self.initialized:
raise Exception(MESSAGES.ERRORS.OVERRIDE_SLIPPAGE_POST_INIT)
raise OverrideSlippagePostInit()
self.slippage = slippage
def set_commission(self, commission):
assert isinstance(commission, (PerShare, PerTrade)), \
MESSAGES.ERRORS.UNSUPPORTED_COMMISSION_MODEL
if not isinstance(commission, (PerShare, PerTrade)):
raise UnsupportedCommissionModel()
if self.initialized:
raise Exception(MESSAGES.ERRORS.OVERRIDE_COMMISSION_POST_INIT)
raise OverrideCommissionPostInit()
self.commission = commission
def set_sources(self, sources):
+84
View File
@@ -0,0 +1,84 @@
#
# Copyright 2013 Quantopian, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
class ZiplineError(Exception):
msg = None
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
self.message = str(self)
def __str__(self):
msg = self.msg.format(**self.kwargs)
return msg
__unicode__ = __str__
__repr__ = __str__
class WrongDataForTransform(ZiplineError):
"""
Raised whenever a rolling transform is called on an event that
does not have the necessary properties.
"""
msg = "{transform} requires {fields}. Event cannot be processed."
class UnsupportedSlippageModel(ZiplineError):
"""
Raised if a user script calls the override_slippage magic
with a slipage object that isn't a VolumeShareSlippage or
FixedSlipapge
"""
msg = """
You attempted to override slippage with an unsupported class. \
Please use VolumeShareSlippage or FixedSlippage.
""".strip()
class OverrideSlippagePostInit(ZiplineError):
# Raised if a users script calls override_slippage magic
# after the initialize method has returned.
msg = """
You attempted to override slippage after the simulation has \
started. You may only call override_slippage in your initialize \
method.
""".strip()
class UnsupportedCommissionModel(ZiplineError):
"""
Raised if a user script calls the override_commission magic
with a commission object that isn't a PerShare or
PerTrade commission
"""
msg = """
You attempted to override commission with an unsupported class. \
Please use PerShare or PerTrade.
""".strip()
class OverrideCommissionPostInit(ZiplineError):
"""
Raised if a users script calls override_commission magic
after the initialize method has returned.
"""
msg = """
You attempted to override commission after the simulation has \
started. You may only call override_commission in your initialize \
method.
""".strip()
+5 -4
View File
@@ -13,10 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from numbers import Number
from collections import defaultdict
from zipline.transforms.utils import EventWindow, TransformMeta
from zipline.errors import WrongDataForTransform
class MovingAverage(object):
@@ -153,6 +153,7 @@ class MovingAverageEventWindow(EventWindow):
We only allow events with all of our tracked fields.
"""
for field in self.fields:
assert isinstance(event[field], Number), \
"Got %s for %s in MovingAverageEventWindow" % (event[field],
field)
if field not in event:
raise WrongDataForTransform(
transform="MovingAverageEventWindow",
fields=self.fields)
+13 -1
View File
@@ -13,6 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from numbers import Number
from zipline.errors import WrongDataForTransform
from zipline.transforms.utils import TransformMeta
from collections import defaultdict, deque
@@ -57,7 +59,7 @@ class ReturnsFromPriorClose(object):
self.window_length = window_length
def update(self, event):
self.assert_required_fields(event)
if self.last_event:
# Day has changed since the last event we saw. Treat
@@ -88,3 +90,13 @@ class ReturnsFromPriorClose(object):
# the current event is now the last_event
self.last_event = event
def assert_required_fields(self, event):
"""
We only allow events with a price field to be run through
the returns transform.
"""
if 'price' not in event:
raise WrongDataForTransform(
transform="ReturnsEventWindow",
fields='price')
+11 -5
View File
@@ -13,12 +13,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from numbers import Number
from collections import defaultdict
from math import sqrt
import numpy as np
from zipline.errors import WrongDataForTransform
from zipline.transforms.utils import EventWindow, TransformMeta
@@ -73,6 +73,16 @@ class MovingStandardDev(object):
window.update(event)
return window.get_stddev()
def assert_required_fields(self, event):
"""
We only allow events with a price field to be run through
the returns transform.
"""
if 'price' not in event:
raise WrongDataForTransform(
transform="StdDevEventWindow",
fields='price')
class MovingStandardDevWindow(EventWindow):
"""
@@ -90,14 +100,10 @@ class MovingStandardDevWindow(EventWindow):
self.sum_sqr = 0.0
def handle_add(self, event):
assert isinstance(event.price, Number)
self.sum += event.price
self.sum_sqr += event.price ** 2
def handle_remove(self, event):
assert isinstance(event.price, Number)
self.sum -= event.price
self.sum_sqr -= event.price ** 2
+5 -4
View File
@@ -13,10 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from numbers import Number
from collections import defaultdict
from zipline.errors import WrongDataForTransform
from zipline.transforms.utils import EventWindow, TransformMeta
@@ -100,5 +99,7 @@ class VWAPEventWindow(EventWindow):
# We need numerical price and volume to calculate a vwap.
def assert_required_fields(self, event):
assert isinstance(event.price, Number)
assert isinstance(event.volume, Number)
if 'price' not in event or 'volume' not in event:
raise WrongDataForTransform(
transform="VWAPEventWindow",
fields=self.fields)