Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Order process - clarification of how it works...

Hi,

I'm placing orders with the order function during the handle_data function call and understand that the order is not filled until after the current handle_data function call is finished. That's fine.

However, during the next call of handle_data, when I examine the .filled attribute of the previous order that was placed I notice that there is a difference between the .amount and .filled attributes. I understand that this conforms to your slippage model. Also fine.

What I'd like to know now is what happens on subsequent calls to handle_data. Will the system automatically continue to fill the previous order until .filled == .amount? Of do I manually have to place further orders that contain a quantity for the difference between .filled and .amount?

Also, I'm trying to code a trailing stop into my algo. I've noticed that when I place an order (style=MarketOrder) and then another separate order (style=StopOrder) within the same handle_data call, the subsequent call to handle_data both orders have been merged into one.

How should I go about changing the StopOrder price should the price evolve? Will an subsequent order (style=StopOrder) with a different price get merged with the original order or will there be multiple separate orders? Does anyone have any example code for what I'm trying to do?

Any clarification will be appreciated.
Thanks.

6 responses

Hello Andrew,

Do you have example code that illustrates the 'merging' of orders? This doesn't sound right (but then, I have limited experience with the various order types).

Regarding adjusting the stop price, you might try simply cancelling the open order, and submitting a new one.

Grant

Hi Andrew,

Regarding your first question on what happens on subsequent calls to handle_data for orders, testing showed that the system will continue to fill the previous order until filled == amount, so you don't need to call order again.

Here's a test you might find useful. Just run it in some timeframe and you'll see that the order is gradually filled without having to reorder again.

'''
Test to see how orders are filled. It submits a single large buy order and logs the ordered and filled amounts to see when the order is fully completed.

Looks like for liquid stocks (eg. ADBE), the order is always filled in the next tick but for non-liquid stocks (eg. SDD), the order is filled gradually.  
'''
def initialize(context):  
    context.order_id = None  
    # context.security = symbol('AAPL')  
    context.security = symbol('SDD')


def handle_data(context, data):  
    if context.order_id is None:  
        context.order_id = order(context.security, 10000)  
    my_order = get_order(context.order_id)  
    log.info("ordered: {}, filled: {}".format(my_order.amount, my_order.filled))  

By the way, it's interesting to note that for liquid stocks (eg. AAPL), the order is always filled in the next tick whereas for non-liquid stocks, order is gradually filled. I'm guessing Quantopian has a volume based order fill mechanism.

Thanks to all for responding.

I've been doing some experimentation with the following code:


def initialize(context):  
    context.stock = sid(24)  
    context.iterator = 0  
    context.orderid = 0  
    context.orderid2 = 0  


def handle_data(context, data):

    context.iterator += 1  
    if ( context.iterator == 1 ):  
        context.orderid = order(context.stock, 500)  
        context.orderid2 = order(context.stock, 500, style=StopOrder(1))  
    order_details = get_order(context.orderid)  
    if ( context.iterator > 1 ):  
        order(context.stock, 500, style=StopOrder(2))  

It seems, using the debugger, that during the current handle_data call where the order and stop orders are placed get_open_order() is useful as this displays the unfilled orders.

Then in the next handle_data call, if you use the order_id of the previous order (for me held in context.orderid and context.orderid2 ) in conjunction with the get_orders() instruction you can see if the order is filled or not (In my case, both are filled but more on that later). And, as correctly stated by Mete Atamel for AAPL there's no problem and the order is filled instantly. Incidentally, Mete Quantopian slippage model can be found here https://www.quantopian.com/help#ide-slippage in case you didn't know.

Once an order is filled it goes into the context.portfolio.position container. However, the amount attribute of this container seems to include the quantity for the two orders (order + stop order) which surprised me! Also, the stop order seems to get filled in the this call to handle_data which is also surprising as the data[context.stock].price is at 47.4038052. How can it have been filled when the stop price is set to 1.00USD? Will get_open_orders() show me any unfilled stop orders? I'm a little confused.

Any help will be appreciated.

Thanks.

The logic for triggering orders is in this code:

https://github.com/quantopian/zipline/blob/master/zipline/finance/slippage.py

Perhaps useful.

Grant

Thanks Grant. I'll have a look but I don't know if my python skills are strong enough to understand it all.

However, I believe I understand where I'm going wrong.

In the code, I've got a positive quantity of stocks to buy for the stop order where as what I believe I need is a negative one. This way, using the debugger again, I see that the get_open_orders() instruction displayed the outstanding stop order, which, to do a trailing stop algo can be cancelled and another order placed with a change of stop limit.

Problem solved. Thanks everyone for your support.