Skip to content

Commit

Permalink
ENH: Well formed exception for any value passed to OrderStyle
Browse files Browse the repository at this point in the history
This commit adds support for arbitrary objects in addition to NaN
and infinity values. The object well be returned in string format
as part of the error message.
  • Loading branch information
CaptainKanuk committed Aug 26, 2014
1 parent 15f33d3 commit c721233
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 38 deletions.
13 changes: 12 additions & 1 deletion tests/test_execution_styles.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,18 @@ class ExecutionStyleTestCase(TestCase):
for delta in range(1, 10)
]

INVALID_PRICES = [(-1,), (-1.0,), (0 - epsilon,), (float('nan'),)]
class ArbitraryObject():
def __str__(self):
return """This should yield a bad order error when
passed as a stop or limit price."""

INVALID_PRICES = [
(-1,),
(-1.0,),
(0 - epsilon,),
(float('nan'),),
(ArbitraryObject(),),
]

def setUp(self):
setup_logger(self)
Expand Down
65 changes: 28 additions & 37 deletions zipline/finance/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

import zipline.utils.math_utils as zp_math

from math import isnan
from numpy import isfinite

from zipline.errors import BadOrderParameters

Expand Down Expand Up @@ -82,16 +82,8 @@ def __init__(self, limit_price, exchange=None):
Store the given price.
"""

if isnan(limit_price):
raise BadOrderParameters(
msg="""Attempted to place an order with a limit price
of NaN."""
)
check_stoplimit_prices(limit_price, 'limit')

if limit_price < 0:
raise BadOrderParameters(
msg="Can't place a limit with a negative price."
)
self.limit_price = limit_price
self._exchange = exchange

Expand All @@ -112,16 +104,8 @@ def __init__(self, stop_price, exchange=None):
Store the given price.
"""

if isnan(stop_price):
raise BadOrderParameters(
msg="""Attempted to place an order with a stop price
of NaN."""
)
check_stoplimit_prices(stop_price, 'stop')

if stop_price < 0:
raise BadOrderParameters(
msg="Can't place a stop order with a negative price."
)
self.stop_price = stop_price
self._exchange = exchange

Expand All @@ -142,25 +126,9 @@ def __init__(self, limit_price, stop_price, exchange=None):
Store the given prices
"""

if isnan(limit_price):
raise BadOrderParameters(
msg="""Attempted to place an order with a limit price
of NaN."""
)
if isnan(stop_price):
raise BadOrderParameters(
msg="""Attempted to place an order with a stop price
of NaN."""
)
check_stoplimit_prices(limit_price, 'limit')

if limit_price < 0:
raise BadOrderParameters(
msg="Can't place a limit with a negative price."
)
if stop_price < 0:
raise BadOrderParameters(
msg="Can't place a stop order with a negative price."
)
check_stoplimit_prices(stop_price, 'stop')

self.limit_price = limit_price
self.stop_price = stop_price
Expand Down Expand Up @@ -201,3 +169,26 @@ def asymmetric_round_price_to_penny(price, prefer_round_down,
if zp_math.tolerant_equals(rounded, 0.0):
return 0.0
return rounded


# Check to make sure the stop/limit prices are reasonable and raise
# an exception if not.
def check_stoplimit_prices(price, label):
try:
if not isfinite(price):
raise BadOrderParameters(
msg="""Attempted to place an order with a {} price
of {}.""".format(label, price)
)
# This catches arbitrary objects
except TypeError:
raise BadOrderParameters(
msg="""Attempted to place an order with a {} price
of {}.""".format(label, price)
)

if price < 0:
raise BadOrderParameters(
msg="""Can't place a {} order
with a negative price.""".format(label)
)

0 comments on commit c721233

Please sign in to comment.