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()

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.

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


.

1 response

I use this function quite a bit for example after a certain number of partial fills to cancel an opening order while letting closing orders finish closing whenever they can. Spotted an uncaught crossover order, presumably fixed now with the edit above, would appreciate someone with more horsepower in their head than myself to go over this with a fine-toothed comb and see if you can find flaws or improved efficiency. This backtest could be a useful start for testing.

1
Backtest from to with initial capital
Total Returns
--
Alpha
--
Beta
--
Sharpe
--
Sortino
--
Max Drawdown
--
Benchmark Returns
--
Volatility
--
 Returns 1 Month 3 Month 6 Month 12 Month
 Alpha 1 Month 3 Month 6 Month 12 Month
 Beta 1 Month 3 Month 6 Month 12 Month
 Sharpe 1 Month 3 Month 6 Month 12 Month
 Sortino 1 Month 3 Month 6 Month 12 Month
 Volatility 1 Month 3 Month 6 Month 12 Month
 Max Drawdown 1 Month 3 Month 6 Month 12 Month
# Backtest ID: 5b02952bf3806e4420d4369f
There was a runtime error.