def test_FOK(): DEF_TRIGGER = sob.TRIGGER_FILL_FULL def check_aot(aot, cond, trigger, tag): check_val(aot.condition, cond, "FOK - " + tag + " - .condition") check_val(aot.trigger, trigger, "FOK - " + tag + " - .trigger") aot1 = sob.AdvancedOrderTicketFOK.build() check_aot(aot1, sob.CONDITION_FOK, DEF_TRIGGER, 'fill-full aot') aot2 = sob.AdvancedOrderTicketFOK.build(sob.TRIGGER_FILL_PARTIAL) check_aot(aot2, sob.CONDITION_FOK, sob.TRIGGER_FILL_PARTIAL, 'fill-partial aot') book = sob.SimpleOrderbook(TICK_TYPE, BOOK_MIN, BOOK_MAX) book.sell_limit(BOOK_MID, SZ) book.buy_limit(BOOK_MID, SZ * 2, advanced=aot1) md = book.market_depth() if book.volume( ) or md[BOOK_MID][0] != SZ or md[BOOK_MID][1] != sob.SIDE_ASK: raise Exception("*** ERROR fill-full FOK failed ***") o1 = book.buy_limit(BOOK_MID, SZ * 2, advanced=aot2) if book.volume() != SZ: raise Exception("*** ERROR vol(%i) != %i ***" % (book.volume(), SZ)) md = book.market_depth() if not md[BOOK_MID]: raise Exception("*** ERROR invalid market_depth elem @ %f ***" % BOOK_MID) if md[BOOK_MID][0] != SZ: raise Exception("*** ERROR reaming size @ %f (%i) != %i ***" % (BOOK_MID, md[BOOK_MID][0], SZ)) if md[BOOK_MID][1] != sob.SIDE_BID: raise Exception( "*** ERROR remaing limit not on correct side of market")
def test_OCO(): DEF_TRIGGER = sob.TRIGGER_FILL_PARTIAL def check_aot(aot, cond, trigger, is_buy, sz, limit, stop, tag): check_val(aot.condition, cond, "OCO - " + tag + " - .condition") check_val(aot.trigger, trigger, "OCO - " + tag + " - .trigger") check_val(aot.is_buy, is_buy, "OCO - " + tag + " - .is_buy") check_val(aot.size, sz, "OCO - " + tag + " - .size") check_val(aot.limit, limit, "OCO - " + tag + " - .limit") check_val(aot.stop, stop, "OCO - " + tag + " - .stop") aot_limit = sob.AdvancedOrderTicketOCO.build_limit(True, BOOK_MID, SZ) check_aot(aot_limit, sob.CONDITION_OCO, DEF_TRIGGER, True, SZ, BOOK_MID, 0, 'lmit AOT') aot_stop = sob.AdvancedOrderTicketOCO.build_stop(False, BOOK_MIN, SZ * 2) check_aot(aot_stop, sob.CONDITION_OCO, DEF_TRIGGER, False, SZ * 2, 0, BOOK_MIN, 'stop AOT') aot_stop_limit = sob.AdvancedOrderTicketOCO.build_stop_limit( True, BOOK_MID, BOOK_MAX, 1) check_aot(aot_stop_limit, sob.CONDITION_OCO, DEF_TRIGGER, True, 1, BOOK_MAX, BOOK_MID, 'stop_limit AOT') book = sob.SimpleOrderbook(TICK_TYPE, BOOK_MIN, BOOK_MAX) o1 = book.sell_limit(BOOK_MID + BOOK_INCR, SZ2, advanced=aot_limit) o2 = book.sell_stop_limit(BOOK_MID - BOOK_INCR, BOOK_MIN, SZ2, advanced=aot_stop_limit) # (L,o1.a,SZ2) # (L,o1.b,SZ) (S,o2.b,1) (SL,o2.a,SZ2) o3 = book.buy_market(SZ) # (L,o1.a,SZ2-SZ) if book.volume() != SZ + 1: raise Exception("*** ERROR vol(%i) != %i ***" % (book.volume(), SZ + 1)) md = book.market_depth() if len(md) != 1: raise Exception("*** ERROR length of market_depth dict != %i ***" % 1) x = md[BOOK_MID + BOOK_INCR] if not x: raise Exception("*** ERROR invalid market_depth elem @ %f ***" % BOOK_MID + BOOK_INCR) if x[0] != SZ2 - SZ - 1: raise Exception("*** ERROR reaming size(%i) != %i ***" % (x[0], SZ2 - SZ - 1))
def test_TrailingStop(): def check_aot(aot, cond, trigger, nticks, tag): check_val(aot.condition, cond, "TrailingStop - " + tag + " - .condition") check_val(aot.trigger, trigger, "TrailingStop - " + tag + " - .trigger") check_val(aot.nticks, nticks, "TrailingStop - " + tag + " - .nticks") aot1 = sob.AdvancedOrderTicketTrailingStop.build(NTICKS, sob.TRIGGER_FILL_FULL) check_aot(aot1, sob.CONDITION_TRAILING_STOP, sob.TRIGGER_FILL_FULL, NTICKS, '') o1 = 0 def stop_cb(msg, id1, id2, price, size): nonlocal o1 if msg == sob.MSG_TRIGGER_TRAILING_STOP_OPEN: o1 = id2 book = sob.SimpleOrderbook(TICK_TYPE, BOOK_MIN, BOOK_MAX) o1 = book.buy_limit(BOOK_MID, SZ, callback=stop_cb, advanced=aot1) oi = book.get_order_info(o1) if oi.limit != BOOK_MID or oi.order_type != sob.ORDER_TYPE_LIMIT: raise Exception("*** ERROR (!) invalid OrderInfo") if not oi.advanced or oi.advanced.nticks != NTICKS \ or oi.advanced.condition != sob.CONDITION_TRAILING_STOP: raise Exception("*** ERROR (1) invalid OrderInfo.advanced") book.sell_market(SZ) oi = book.get_order_info(o1) if oi.limit != 0 or oi.stop != (BOOK_MID - (NTICKS*BOOK_INCR)) \ or oi.order_type != sob.ORDER_TYPE_STOP: raise Exception("*** ERROR (2) invalid OrderInfo") if not oi.advanced or oi.advanced.condition != sob.CONDITION_TRAILING_STOP_ACTIVE: raise Exception("*** ERROR (2) invalid OrderInfo.advanced") book.sell_limit(BOOK_MID + 10 * BOOK_INCR, SZ) book.buy_market(SZ) oi = book.get_order_info(o1) if oi.stop != BOOK_MID or oi.order_type != sob.ORDER_TYPE_STOP: raise Exception("*** ERROR (3) invalid OrderInfo") if not oi.advanced or oi.advanced.condition != sob.CONDITION_TRAILING_STOP_ACTIVE: raise Exception("*** ERROR (3) invalid OrderInfo.advanced")
def test_TrailingBracket(): def check_aot(aot, cond, trigger, stop_nticks, target_nticks, tag): check_val(aot.condition, cond, "TrailingBracket - " + tag + " - .condition") check_val(aot.trigger, trigger, "TrailingBracket - " + tag + " - .trigger") check_val(aot.stop_nticks, stop_nticks, "TrailingBracket - " + tag + " - .stop_nticks") check_val(aot.target_nticks, target_nticks, "TrailingBracket - " + tag + " - .target_nticks") aot2 = sob.AdvancedOrderTicketTrailingBracket.build( NTICKS, NTICKS, sob.TRIGGER_FILL_FULL) check_aot(aot2, sob.CONDITION_TRAILING_BRACKET, sob.TRIGGER_FILL_FULL, NTICKS, NTICKS, '') o1 = 0 def stop_cb(msg, id1, id2, price, size): nonlocal o1 if msg == sob.MSG_TRIGGER_BRACKET_OPEN or msg == sob.MSG_TRIGGER_BRACKET_CLOSE: o1 = id2 book = sob.SimpleOrderbook(TICK_TYPE, BOOK_MIN, BOOK_MAX) o1 = book.buy_limit(BOOK_MID, SZ, callback=stop_cb, advanced=aot2) oi = book.get_order_info(o1) if not oi.advanced or oi.advanced.condition != sob.CONDITION_TRAILING_BRACKET: raise Exception("*** ERROR (1a) invalid OrderInfo.advanced") book.sell_limit(BOOK_MID, SZ) oi = book.get_order_info(o1) if not oi.advanced or oi.advanced.condition != sob.CONDITION_TRAILING_BRACKET_ACTIVE: raise Exception("*** ERROR (1b) invalid OrderInfo.advanced") book.sell_limit(BOOK_MID + BOOK_INCR, SZ) book.buy_market(SZ) oi = book.get_order_info(o1) if not oi.advanced or oi.advanced.stop != (BOOK_MID - (NTICKS - 1) * BOOK_INCR): raise Exception("*** ERROR (1c) invalid OrderInfo.advanced") book.buy_market(SZ) if book.market_depth(): raise Exception("*** ERROR orders still exists in book ***")
def test_AON(): aot = sob.AdvancedOrderTicketAON.build() check_val(aot.condition, sob.CONDITION_AON, "AON.condition") check_val(aot.trigger, sob.TRIGGER_NONE, "AON.trigger") book = sob.SimpleOrderbook(TICK_TYPE, BOOK_MIN, BOOK_MAX) def cb(msg, id1, id2, price, size): pass #print("AON callback: ", msg, id1, id2, price, size) o1 = book.sell_limit(BOOK_MID + BOOK_INCR, SZ, cb) o2 = book.buy_limit(BOOK_MID + BOOK_INCR, SZ, cb) o3 = book.sell_limit(BOOK_MID + BOOK_INCR, SZ, cb) o4 = book.sell_limit(BOOK_MID + BOOK_INCR * 2, SZ, cb) o5 = book.buy_limit(BOOK_MID + BOOK_INCR * 2, SZ * 2, cb, advanced=aot) if book.bid_size() != 0: raise Exception("*** ERROR bid size(%i) != %i ***" % (book.bid_size(), 0)) if book.ask_size() != 0: raise Exception("*** ERROR ask size(%i) != %i ***" % (book.ask_size(), 0)) if book.volume() != SZ * 3: raise Exception("*** ERROR volume(%i) != %i ***" % (book.volume(), SZ * 3)) #book.dump_buy_limits() #book.dump_sell_limits() #book.dump_aon_buy_limits() #book.dump_aon_sell_limits() o6 = book.sell_limit(BOOK_MID + BOOK_INCR, SZ, cb) o7 = book.sell_limit(BOOK_MID + BOOK_INCR * 2, SZ, cb) o8 = book.buy_limit(BOOK_MID + BOOK_INCR * 2, int(SZ * 1.5), cb, advanced=aot) #book.dump_limits() #book.dump_stops() #book.dump_aon_limits() if book.volume() != SZ * 4.5: raise Exception("*** ERROR volume(%i) != %i ***" % (book.volume(), SZ * 4.5)) oi = book.get_order_info(o7) if oi.limit != BOOK_MID + BOOK_INCR * 2: raise Exception("*** ERROR order_info.limit(%f) != %f ***" % (oi.limit, BOOK_MID + BOOK_INCR * 2)) if oi.size != SZ * .5: raise Exception("*** ERROR order_info.size(%i) != %i ***" % (oi.size, SZ * .5)) if not book.pull_order(o7): raise Exception("*** ERROR failed to remove order 'o7', id: %i" % o7) oi = book.get_order_info(o8) if oi: raise Exception("*** ERROR order_info should be None ***") if book.pull_order(o8): raise Exception( "*** ERROR successfully to removed order 'o8', id: %i" % o8) #book.dump_aon_buy_limits() #book.dump_aon_sell_limits() book = sob.SimpleOrderbook(TICK_TYPE, BOOK_MIN, BOOK_MAX) book.sell_limit(BOOK_MID + BOOK_INCR, SZ, cb, aot) book.sell_limit(BOOK_MID + BOOK_INCR * 2, SZ, cb, aot) tabs = book.total_aon_bid_size() taas = book.total_aon_ask_size() tas = book.total_aon_size() if tabs != 0: raise Exception("*** ERROR total_aon_bid_size(%i) != %i ***" % (tabs, 0)) if taas != 2 * SZ: raise Exception("*** ERROR total_aon_ask_size(%i) != %i ***" % (taas, 2 * SZ)) if tas != 2 * SZ: raise Exception("*** ERROR total_aon_size(%i) != %i ***" % (tas, 2 * SZ)) #book.dump_aon_buy_limits() #book.dump_aon_sell_limits() #book.dump_aon_limits() o9 = book.buy_limit(BOOK_MIN, 1, advanced=aot) md = book.aon_market_depth() if len(md) != 3: raise Exception("*** ERROR len(aon_market_depth)(%i) != %i ***" % (len(md), 3)) if BOOK_MIN not in md: raise Exception("*** ERROR level(%f) not in aon_market_depth) ***" % BOOK_MIN) buysz = md[BOOK_MIN][0] if buysz != 1: raise Exception("*** ERROR aon buy size @ %f(%i) != %i ***" % (BOOK_MIN, buysz, 1)) o10 = book.replace_with_buy_limit(o9, BOOK_MIN + BOOK_INCR, SZ, cb) if not o10: raise Exception("*** ERROR failed to replace order %i ***" % o9) if not book.pull_order(o10): raise Exception("*** ERROR failed to pull order %i ***" % o10) md = book.aon_market_depth() if len(md) != 2: raise Exception("*** ERROR len(aon_market_depth)(%i) != %i ***" % (len(md), 2)) if BOOK_MID + BOOK_INCR not in md: raise Exception("*** ERROR level(%f) not in aon_market_depth) ***" % BOOK_MID + BOOK_INCR) if BOOK_MID + BOOK_INCR * 2 not in md: raise Exception("*** ERROR level(%f) not in aon_market_depth) ***" % BOOK_MID + BOOK_INCR * 2) book.buy_limit(BOOK_MID + BOOK_INCR * 2, int(SZ * 2.5), cb) bs = book.bid_size() tbs = book.total_bid_size() ts = book.total_size() if bs != SZ / 2: raise Exception("*** ERROR bid_size(%i) != %i ***" % (bs, SZ / 2)) if tbs != SZ / 2: raise Exception("*** ERROR tota_bid_size(%i) != %i ***" % (tbs, SZ / 2)) if ts != SZ / 2: raise Exception("*** ERROR total_size(%i) != %i ***" % (ts, SZ / 2)) tabs = book.total_aon_bid_size() tas = book.total_aon_size() if tabs != 0: raise Exception("*** ERROR total_aon_bid_size(%i) != %i ***" % (tabs, 0)) if tas != 0: raise Exception("*** ERROR total_aon_size(%i) != %i ***" % (tas, 0)) md = book.aon_market_depth() if len(md) != 0: raise Exception("*** ERROR len(aon_market_depth)(%i) != %i ***" % (len(md), 0))
def test_BRACKET(): DEF_TRIGGER = sob.TRIGGER_FILL_PARTIAL AOT = sob.AdvancedOrderTicketBRACKET def check_aot(aot, cond, trigger, is_buy, loss_stop, loss_limit, target_limit, tag): check_val(aot.condition, cond, "BRACKET - " + tag + " - .condition") check_val(aot.trigger, trigger, "BRACKET - " + tag + " - .trigger") check_val(aot.is_buy, is_buy, "BRACKET - " + tag + " - .is_buy") check_val(aot.loss_stop, loss_stop, "BRACKET - " + tag + " - .loss_stop") check_val(aot.loss_limit, loss_limit, "BRACKET - " + tag + " - .loss_limit") check_val(aot.target_limit, target_limit, "BRACKET - " + tag + " - .target_limit") aot_ssl = AOT.build_sell_stop_limit(BOOK_MID, BOOK_MIN, BOOK_MAX, sob.TRIGGER_FILL_FULL) check_aot(aot_ssl, sob.CONDITION_BRACKET, sob.TRIGGER_FILL_FULL, False, BOOK_MID, BOOK_MIN, BOOK_MAX, 'sell_stop_limit fill-partial AOT') aot_bsl = AOT.build_buy_stop_limit(BOOK_MID, BOOK_MAX, BOOK_MIN, sob.TRIGGER_FILL_FULL) check_aot(aot_bsl, sob.CONDITION_BRACKET, sob.TRIGGER_FILL_FULL, True, BOOK_MID, BOOK_MAX, BOOK_MIN, 'buy_stop_limit fill-full AOT') aot_ss = AOT.build_sell_stop(BOOK_MID, BOOK_MAX, sob.TRIGGER_FILL_FULL) check_aot(aot_ss, sob.CONDITION_BRACKET, sob.TRIGGER_FILL_FULL, False, BOOK_MID, 0, BOOK_MAX, 'sell_stop fill-full AOT') aot_bs = AOT.build_buy_stop(BOOK_MID, BOOK_MIN, sob.TRIGGER_FILL_FULL) check_aot(aot_bs, sob.CONDITION_BRACKET, sob.TRIGGER_FILL_FULL, True, BOOK_MID, 0, BOOK_MIN, 'buy_stop fill-partial AOT') o1 = 0 def stop_cb(msg, id1, id2, price, size): nonlocal o1 if msg == sob.MSG_TRIGGER_BRACKET_OPEN: o1 = id2 book = sob.SimpleOrderbook(TICK_TYPE, BOOK_MIN, BOOK_MAX) o1 = book.buy_limit(BOOK_MID, SZ, callback=stop_cb, advanced=aot_ssl) oi = book.get_order_info(o1) if not oi.advanced or oi.advanced.condition != sob.CONDITION_BRACKET: raise Exception("*** ERROR (1a) invalid OrderInfo.advanced") book.sell_limit(BOOK_MID, SZ) # (L, o1.b.1, SZ) # (SL,o1.b.2,SZ) md = book.market_depth() if not md[BOOK_MAX]: raise Exception("*** ERROR invalid limit @ %f ***" % BOOK_MAX) if md[BOOK_MAX][0] != SZ: raise Exception("*** ERROR reaming size @ %f (%i) != %i ***" % (BOOK_MAX, md[BOOK_MAX][0], SZ)) if md[BOOK_MAX][1] != sob.SIDE_ASK: raise Exception( "*** ERROR bracket target not on correct side of market") oi = book.get_order_info(o1) if not oi.advanced or oi.advanced.condition != sob.CONDITION_BRACKET_ACTIVE: raise Exception("*** ERROR (1b) invalid OrderInfo.advanced") book.buy_limit(BOOK_MAX, SZ) md = book.market_depth() if md: raise Exception("*** ERROR orders still exists in book ***") o1 = book.sell_limit(BOOK_MID, SZ, callback=stop_cb, advanced=aot_bs) oi = book.get_order_info(o1) if not oi.advanced or oi.advanced.condition != sob.CONDITION_BRACKET: raise Exception("*** ERROR (2a) invalid OrderInfo.advanced") book.buy_limit(BOOK_MID, SZ) md = book.market_depth() if not md[BOOK_MIN]: raise Exception("*** ERROR invalid limit @ %f ***" % BOOK_MIN) #if md[BOOK_MIN][0] != 100*SZ: # raise Exception("*** ERROR reaming size @ %f (%i) != %i ***" % # (BOOK_MIN, md[BOOK_MIN][0],100*SZ)) if md[BOOK_MIN][1] != sob.SIDE_BID: raise Exception( "*** ERROR bracket target not on correct side of market") oi = book.get_order_info(o1) if not oi.advanced or oi.advanced.condition != sob.CONDITION_BRACKET_ACTIVE: raise Exception("*** ERROR (2b) invalid OrderInfo.advanced") book.sell_limit(BOOK_MIN, SZ) md = book.market_depth() #if md[BOOK_MIN][0] != 99*SZ: # raise Exception("*** ERROR orders still exists in book ***") null_fd = os.open(os.devnull, os.O_RDWR) err_fd = os.dup(2) os.dup2(null_fd, 2) try: book.buy_market(1) # check nothing above except: return finally: os.dup2(err_fd, 2) os.close(null_fd) raise Exception("*** ERROR sell orders were still active ***")
def test_OTO(): DEF_TRIGGER = sob.TRIGGER_FILL_PARTIAL def check_aot(aot, cond, trigger, is_buy, sz, limit, stop, tag): check_val(aot.condition, cond, "OTO - " + tag + " - .condition") check_val(aot.trigger, trigger, "OTO - " + tag + " - .trigger") check_val(aot.is_buy, is_buy, "OTO - " + tag + " - .is_buy") check_val(aot.size, sz, "OTO - " + tag + " - .size") check_val(aot.limit, limit, "OTO - " + tag + " - .limit") check_val(aot.stop, stop, "OTO - " + tag + " - .stop") aot_limit = sob.AdvancedOrderTicketOTO.build_limit(True, BOOK_MID, SZ) check_aot(aot_limit, sob.CONDITION_OTO, DEF_TRIGGER, True, SZ, BOOK_MID, 0, 'limit AOT') aot_stop = sob.AdvancedOrderTicketOTO.build_stop(False, BOOK_MIN, SZ * 2) check_aot(aot_stop, sob.CONDITION_OTO, DEF_TRIGGER, False, SZ * 2, 0, BOOK_MIN, 'stop AOT') aot_stop_limit = sob.AdvancedOrderTicketOTO.build_stop_limit( True, BOOK_MID, BOOK_MAX, 1) check_aot(aot_stop_limit, sob.CONDITION_OTO, DEF_TRIGGER, True, 1, BOOK_MAX, BOOK_MID, 'stop_limit AOT') aot_market = sob.AdvancedOrderTicketOTO.build_market(False, SZ * 100) check_aot(aot_market, sob.CONDITION_OTO, DEF_TRIGGER, False, SZ * 100, 0, 0, 'market AOT') book = sob.SimpleOrderbook(TICK_TYPE, BOOK_MIN, BOOK_MAX) o2 = 0 def stop_cb(msg, id1, id2, price, size): nonlocal o2 if msg == sob.MSG_TRIGGER_OTO: o2 = id2 o1 = book.sell_limit(BOOK_MID + BOOK_INCR, SZ2, advanced=aot_limit) o2 = book.buy_stop_limit(BOOK_MID + BOOK_INCR, BOOK_MAX, SZ, callback=stop_cb, advanced=aot_stop) # (L,o1.a,SZ2) # (SL,o2.a,SZ) o3 = book.buy_market(SZ) # (L,o1.a,SZ2-SZ-SZ) # (L,o1.b,SZ) # (SL,o2.b,SZ*2) if book.volume() != SZ + SZ: raise Exception("*** ERROR vol(%i) != %i ***" % (book.volume(), SZ + SZ)) md = book.market_depth() if len(md) != 2: raise Exception("*** ERROR length of market_depth dict != %i ***" % 2) xl = md[BOOK_MID] if not xl: raise Exception("*** ERROR invalid market_depth elem @ %f ***" % BOOK_MID) if xl[0] != SZ: raise Exception("*** ERROR reaming size @ %f (%i) != %i ***" % (BOOK_MID, xl[0], SZ)) xs = md[BOOK_MID + BOOK_INCR] if not xs: raise Exception("*** ERROR invalid market_depth elem @ %f ***" % BOOK_MID + BOOK_INCR) if xs[0] != SZ2 - SZ - SZ: raise Exception("*** ERROR reaming size @ %f (%i) != %i ***" % (BOOK_MID + BOOK_INCR, xs[0], SZ2 - SZ - SZ)) if not book.pull_order(o2): raise Exception("*** ERROR failed to remove OTO'd stop, id: %i" % o2)