Back to Community
Order state on partial fills, close, open or crossover

Some code to let you know the state of a partially filled order. cls_opn_crs()


oos = get_open_orders()  
for s in oos:  
    for o in oos[s]:                             # loop thru open orders  
        if cls_opn_crs(context, o) in [1, 3]:    # if opening, not closing  
            if o.filled < o.amount * .10:        # if partial fill and very small  
                cancel_order(               # cancel remaining  

The idea is that an order so thinly traded on open (at some threshold you determine) can also have a difficult time closing which can be very bad if the price is moving in the wrong direction when the time comes.

About the return from cls_opn_crs():
1: A straightup opening order, from 0 shares, it is a simple increasing number of shares away from zero, or for example an increase of allocation from 100 shares to 300 shares, or -50 shares to -112 shares.
3: Crossover opening portion. For example where a position was 100 shares and an order was entered for -500 shares (targeting -400), and at least 100 (or -100 depending on how you think of it) of the previous position have been filled, now passing 0 and into negative territory. Was long, is now short and increasing the number of short shares (more negative). This is now an order that is opening (greater magnitude in the number of shares).

0: Closing order, reduction in shares toward 0
2: Closing toward zero however merely the closing portion of a crossover order

A change from -50 shares to -35 shares (or 50 to 35) is considered a "closing" order (0) here even though the target is not 0.

def cls_opn_crs(c, o):      # c = context    o = order object  
    # Whether order is closing, opening or crossover (short to long or reverse)  
    if c.portfolio.positions[o.sid].amount * o.amount < 0:   # close or crossover  
        if abs(c.portfolio.positions[o.sid].amount) < abs(o.amount - o.filled):  
            if abs(c.portfolio.positions[o.sid].amount) - abs(o.filled) < 0:  
                  return 3  # crossed 0 shares and now opening  
            else: return 2  # cross closing  
        else:     return 0  # closing  
    else:         return 1  # opening