mirror of
https://github.com/wassname/catalyst.git
synced 2026-06-29 11:49:18 +08:00
ENH: Add new order statuses for broker integration
This commit is contained in:
+49
-16
@@ -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
@@ -32,7 +32,8 @@ DATASOURCE_TYPE = Enum(
|
||||
'DONE',
|
||||
'CUSTOM',
|
||||
'BENCHMARK',
|
||||
'COMMISSION'
|
||||
'COMMISSION',
|
||||
'MESSAGE'
|
||||
)
|
||||
|
||||
# Expected fields/index values for a dividend Series.
|
||||
|
||||
Reference in New Issue
Block a user