Some code to let you know the state of a partially filled order. cls_opn_crs()
Example:
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(o.id) # 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)
amt = c.portfolio.positions[o.sid].amount
if (amt - o.filled) * o.amount < 0: # close or x
if abs(o.amount) > abs(amt - o.filled):
if abs(amt) - abs(o.filled) < 0:
return 3 # crossed 0 shares and now opening
else: return 2 # x crossover
else: return 0 # close
else: return 1 # open
.