wrote this as a first attempt (including a trigger that will re-order a lower amount at rejected as most rejected orders come from over ordering or no shorts availabkle). This function needs to be called in handle_data or as frequent schedule function like this:
checkorders(context, data)
and every order call need to be a bit different:
either
checkorders(context, data, oid=order_target_percent(sid, i) )
or
oid=order_target_percent(sid, i)
checkorders(context, data, oid )
The Function to copy:
def checkorders(context, data, oid=None):
if 'orderlog' not in context:
#init var
context.orderlog=[]
orderlog = np.copy(context.orderlog)
if oid ==None:
# check orders:
for o in orderlog:
oo = get_order(o)
if oo.status in [1]:
context.orderlog.remove(o)
elif oo.status in [2]:
#action for cancelled
log.info('\n\n!Cancelled order found for '+str(oo.amount)+ ' shares for '+str(oo.sid)+' at '+str(oo.created)+' with reason: '+str(oo.reason)+'. Already filled: '+ str(oo.filled)+'. Doing: nothing..... \n\n')
context.orderlog.remove(o)
elif oo.status in [3]:
# rejections are involuntary (and usually include a message from a broker indicating why the order was rejected) while cancels are typically user-driven.
log.info('\n\n!Rejected order found for '+str(oo.amount)+ ' shares for '+str(oo.sid)+' at '+str(oo.created)+' with reason: '+ str(oo.reason) +'. Already filled: '+ str(oo.filled)+'. Trying again with 95% of the amount left to fill\n\n')
context.orderlog.remove(o)
checkorders(context, data, oid=order(oo.sid,int((oo.amount-oo.filled)*0.95)))
elif oo.status in [0,4]:
#Open or held status, held is usually due finding shorts to borrow or other shady broker reasons
continue
else:
log.info('\n\nWARNING !!! Unknown status discovered!!! -- order object below:\n')
log.info(oo)
else:
# Add order ID to log and check next minute
context.orderlog.append(oid)