Hello Everyone,
Does Quantopian support Bracket Orders? and Bracket Orders with stop-limit?
It would also be interesting if we could group the algorithms into folders or packages
Hello Everyone,
Does Quantopian support Bracket Orders? and Bracket Orders with stop-limit?
It would also be interesting if we could group the algorithms into folders or packages
Not directly, but they can be coded in. See here: https://www.quantopian.com/help#ide-ordering
You can see we support limit and stop orders. I believe for a bracketed order, you would want to issue a buy order accompanied by a stop and a limit order. You would also need to be able to check the status of the stop and limit orders each bar so that you could cancel the other order. You could do this by storing the order id of your stop and limit orders and checking on them every bar after you ordered. Something like this:
order(context.sid, -50)
context.stop_order = order(context.sid, 50, style=StopOrder(30))
context.limit_order = order(context.sid, 50, style=LimitOrder(20))
Then on subsequent runs of handle_data, you would run:
if context.stop_order.stop_reached:
cancel_order(context.limit_order)
if context.limit_order.limit_reached:
cancel_order(context.stop_order)
I'm not too familiar with bracketed orders, but hopefully that helps!
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by Quantopian. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. No information contained herein should be regarded as a suggestion to engage in or refrain from any investment-related course of action as none of Quantopian nor any of its affiliates is undertaking to provide investment advice, act as an adviser to any plan or entity subject to the Employee Retirement Income Security Act of 1974, as amended, individual retirement account or individual retirement annuity, or give advice in a fiduciary capacity with respect to the materials presented herein. If you are an individual retirement or other investor, contact your financial advisor or other fiduciary unrelated to Quantopian about whether any given investment idea, strategy, product or service described herein may be appropriate for your circumstances. All investments involve risk, including loss of principal. Quantopian makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances.
Thanks Gus that is what I was doing, for a single order it is simple but for multiple orders I ended up having most of my code just to manage my orders and the strategy hidden in between.
It would be nice if the system provided and abstraction for these orders, Bracket, Trailing Order
Here are the orders supported by IB
https://www.interactivebrokers.com/en/software/webtraderguide/webtrader/orders/supported_order_types.htm
Hello,
I've send this feature request https://github.com/quantopian/zipline/issues/366 some months ago.
I'm trying to implement it myself using 2 classes one named BracketOrder and one named BOBottler.
BOBottler is responsible of giving pseudo ticket for BO order (each BO order being composed of 3 orders)
For now I'm just considering that first order (I will call it master order) is a market order.
class BracketOrder(object):
ticket = None
symbol = None
volume = None
price_SL = None
price_TP = None
price_open = None
# for stats
#price_close = None
def __init__(self, context, symbol, volume, price_stop, price_limit): #, syle=None, price_open=None):
self.context = context
self.symbol = symbol
self.volume = volume
self.price_stop = price_stop
self.price_limit = price_limit
self.order_id_master = None
self.order_id_limit = None
self.order_id_stop = None
#self.price_open = price_open
#self.style = ... # for now order 1 is only a market order
def execute(self):
self.order_id_master = order(self.symbol, self.volume)
self.order_id_limit = order(self.symbol, -self.volume, style=StopOrder(self.price_stop))
self.order_id_stop = order(self.symbol, -self.volume, style=LimitOrder(self.price_limit))
return(self.order_id_master)
def __repr__(self):
s = "<BO ticket=%s price_limit=%s price_stop=%s>" % (self.ticket, self.price_limit, self.price_stop)
return(s)
class BOBottler(object):
_ticket = 100000
data = None
_d_orders = {}
def __init__(self, context):
self.context = context
def ticket(self):
self._ticket += 1
return(self._ticket)
def update(self, data):
self.data = data
self.watch_orders_to_cancel()
def order_send(self, symbol, volume, price_SL, price_TP):
bo = BracketOrder(self.context, symbol, volume, price_SL, price_TP)
order_id_master = bo.execute()
bo.ticket = self.ticket()
self._d_orders[bo.ticket] = bo
return(bo.ticket)
def order_close(self, ticket):
pass
def order_cancel(self, ticket):
pass
def watch_orders_to_cancel(self):
for tkt, bo in self._d_orders.items():
order_stop = get_order(bo.order_id_stop)
order_limit = get_order(bo.order_id_limit)
if order_stop.stop_reached:
cancel_order(bo.order_id_limit)
print("cancel limit_order %s" % bo.order_id_limit)
if order_limit.limit_reached:
cancel_order(bo.order_id_stop)
print("cancel stop_order %s" % bo.order_id_stop)
def initialize(context):
#context.symb = sid(24) # AAPL
context.symb = symbol('AAPL')
context.first_time = True
#context.orders = {}
#context._ticket = 10000
context.bottler = BOBottler(context)
context.i = 0
# Will be called on every trade event for the securities you specify.
def handle_data(context, data):
# Implement your algorithm logic here.
# data[sid(X)] holds the trade event data for that security.
# context.portfolio holds the current portfolio state.
# Place orders with the order(SID, amount) method.
# TODO: implement your own logic here.
context.bottler.update(data)
if context.first_time:
volume = 50
p = data[context.symb].price
symb = context.symb
pSL = p*0.8
pTP = p*1.2
print("price=%s SL=%s TP=%s" % (p, pSL, pTP))
tkt = context.bottler.order_send(symb, volume, pSL, pTP)
#bo = BracketOrder(context, symb, volume, pSL, pTP)
#(tkt, order_id_1, order_id_SL, order_id_TP) = bo.execute()
print("ticket=%s" % tkt)
#context.orders[order_id] = True
context.first_time = False
context.i += 1
#if context.i == 20:
# raise(NotImplementedError)
#def finalize(context):
# print("end of backtest")
# should be fine to display some stats into log !
but I'm having some difficulties to write the watch_orders_to_cancel method.
Any help is welcome.
An other interesting feature is support of OCA orders see also https://www.quantopian.com/posts/oca-orders
because if first order of market is a limit order and it's cancelled, limit order (take profit) and stop order (stop loss) should
also be canceled.
So maybe we first need OCA order support before BO order support.