BUG: Fix handling of STOP, LIMIT and STOP LIMIT Orders

Includes specific handling of Buy Stop, Sell Stop, Buy Limit, Sell
Limit, Buy Stop Limit and Sell Stop Limit orders.
This commit is contained in:
Peter Cawthron
2013-10-16 15:14:58 +01:00
committed by Eddie Hebert
parent 0c71f95016
commit 28f86bc14e
2 changed files with 40 additions and 16 deletions
+4 -2
View File
@@ -282,13 +282,16 @@ class Order(object):
Update internal state based on price triggers and the
trade event's price.
"""
stop_reached, limit_reached = \
stop_reached, limit_reached, sl_stop_reached = \
check_order_triggers(self, event)
if (stop_reached, limit_reached) \
!= (self.stop_reached, self.limit_reached):
self.dt = event.dt
self.stop_reached = stop_reached
self.limit_reached = limit_reached
if sl_stop_reached:
# Change the STOP LIMIT order into a LIMIT order
self.stop = None
def handle_split(self, split_event):
ratio = split_event.ratio
@@ -329,7 +332,6 @@ class Order(object):
For a market order, True.
For a stop order, True IFF stop_reached.
For a limit order, True IFF limit_reached.
For a stop-limit order, True IFF (stop_reached AND limit_reached)
"""
if self.stop and not self.stop_reached:
return False
+36 -14
View File
@@ -31,30 +31,52 @@ def check_order_triggers(order, event):
For market orders, will return (False, False).
For stop orders, limit_reached will always be False.
For limit orders, stop_reached will always be False.
For stop limit orders a Boolean is returned to flag
that the stop has been reached.
Orders that have been triggered already (price targets reached),
the order's current values are returned.
"""
if order.triggered:
return (order.stop_reached, order.limit_reached)
return (order.stop_reached, order.limit_reached, False)
stop_reached = False
limit_reached = False
# if the stop price is reached, simply set stop_reached
sl_stop_reached = False
if order.stop is not None:
if (order.direction * (event.price - order.stop) <= 0):
# convert stop -> limit or market
stop_reached = True
if order.limit is not None:
if order.amount > 0:
# This is a BUY STOP LIMIT order
if event.price >= order.stop:
sl_stop_reached = True
if event.price <= order.limit:
limit_reached = True
else:
# This is a SELL STOP LIMIT order
if event.price <= order.stop:
sl_stop_reached = True
if event.price >= order.limit:
limit_reached = True
else:
if order.amount > 0:
# This is a BUY STOP order
if event.price >= order.stop:
stop_reached = True
else:
# This is a SELL STOP order
if event.price <= order.stop:
stop_reached = True
else:
if order.amount > 0:
# This is BUY LIMIT order
if event.price <= order.limit:
limit_reached = True
else:
# This is a SELL LIMIT order
if event.price >= order.limit:
limit_reached = True
# if the limit price is reached, we execute this order at
# (event.price + simulated_impact)
# we skip this order with a continue when the limit is not reached
if order.limit is not None:
# if limit conditions not met, then continue
if (order.direction * (event.price - order.limit) <= 0):
limit_reached = True
return (stop_reached, limit_reached)
return (stop_reached, limit_reached, sl_stop_reached)
def transact_stub(slippage, commission, event, open_orders):