ENH: Add new order statuses for broker integration

This commit is contained in:
John Ricklefs
2014-06-06 11:32:17 -04:00
parent bb6e9c26c0
commit ec20b3be8a
2 changed files with 51 additions and 17 deletions
+49 -16
View File
@@ -38,10 +38,11 @@ from zipline.utils.protocol_utils import Enum
ORDER_STATUS = Enum(
'OPEN',
'FILLED',
'CANCELLED'
'CANCELLED',
'REJECTED',
'HELD',
)
class Blotter(object):
def __init__(self):
@@ -84,9 +85,9 @@ class Blotter(object):
amount > 0 :: Buy/Cover
amount < 0 :: Sell/Short
Market order: order(sid, amount)
Limit order: order(sid, amount, LimitOrder(price))
Stop order: order(sid, amount, StopOrder(price))
StopLimit order: order(sid, amount, StopLimitOrder(price))
Limit order: order(sid, amount, style=LimitOrder(limit_price))
Stop order: order(sid, amount, style=StopOrder(stop_price))
StopLimit order: order(sid, amount, style=StopLimitOrder(limit_price, stop_price))
"""
if amount == 0:
# Don't bother placing orders for 0 shares.
@@ -113,20 +114,42 @@ class Blotter(object):
return order.id
def cancel(self, order_id):
def cancel(self, order_id, rejected=False, reason=False):
if order_id not in self.orders:
return
cur_order = self.orders[order_id]
if cur_order.open:
# if the order has already been rejected, do not update its status to
# cancelled
if cur_order.broker_status == ORDER_STATUS.REJECTED:
return
if cur_order.open or rejected:
order_list = self.open_orders[cur_order.sid]
if cur_order in order_list:
order_list.remove(cur_order)
if cur_order in self.new_orders:
self.new_orders.remove(cur_order)
cur_order.cancel()
cur_order.cancel(rejected)
cur_order.dt = self.current_dt
if reason:
cur_order.reason = reason
# we want this order's new status to be relayed out
# along with newly placed orders.
self.new_orders.append(cur_order)
def hold(self, order_id, reason):
if order_id not in self.orders:
return
cur_order = self.orders[order_id]
if cur_order.open:
if cur_order in self.new_orders:
self.new_orders.remove(cur_order)
cur_order.hold()
cur_order.dt = self.current_dt
cur_order.reason = reason
# we want this order's new status to be relayed out
# along with newly placed orders.
self.new_orders.append(cur_order)
@@ -208,12 +231,13 @@ class Order(object):
# get a string representation of the uuid.
self.id = id or self.make_id()
self.dt = dt
self.reason = ''
self.created = dt
self.sid = sid
self.amount = amount
self.filled = filled
self.commission = commission
self._cancelled = False
self.broker_status = ORDER_STATUS.OPEN
self.stop = stop
self.limit = limit
self.stop_reached = False
@@ -226,7 +250,7 @@ class Order(object):
def to_dict(self):
py = copy(self.__dict__)
for field in ['type', 'direction', '_cancelled']:
for field in ['type', 'direction']:
del py[field]
py['status'] = self.status
return py
@@ -274,18 +298,27 @@ class Order(object):
@property
def status(self):
if self._cancelled:
if self.broker_status in [ORDER_STATUS.REJECTED,
ORDER_STATUS.CANCELLED]:
return ORDER_STATUS.CANCELLED
elif not self.open_amount:
self.broker_status = ORDER_STATUS.FILLED
return ORDER_STATUS.FILLED
else:
return ORDER_STATUS.OPEN
return ORDER_STATUS.FILLED \
if not self.open_amount else ORDER_STATUS.OPEN
def cancel(self, rejected=False):
if rejected:
self.broker_status = ORDER_STATUS.REJECTED
else:
self.broker_status = ORDER_STATUS.CANCELLED
def cancel(self):
self._cancelled = True
def hold(self):
self.broker_status = ORDER_STATUS.HELD
@property
def open(self):
return self.status == ORDER_STATUS.OPEN
return self.status in [ORDER_STATUS.OPEN, ORDER_STATUS.HELD]
@property
def triggered(self):
+2 -1
View File
@@ -32,7 +32,8 @@ DATASOURCE_TYPE = Enum(
'DONE',
'CUSTOM',
'BENCHMARK',
'COMMISSION'
'COMMISSION',
'MESSAGE'
)
# Expected fields/index values for a dividend Series.