def test_processOrder_ask_LIM03(self): exchange = Exchange() exchange.asks = Orderbook_half('Ask', 1) exchange.bids = Orderbook_half('Bid', 100) order01 = Order('T02', 'Bid', 13, 1, 1, 0, 'LIM') order02 = Order('T01', 'Bid', 14, 3, 1, 0, 'LIM') order03 = Order('T03', 'Bid', 15, 2, 1, 0, 'LIM') exchange.add_order(order01, False) exchange.add_order(order03, False) exchange.add_order(order02, False) order02 = Order('T01', 'Ask', 6, 10, 1, 0, 'LIM') transac, actual = exchange.process_order2(12, order02, False) self.assertEqual(exchange.asks.best_qty, 7) self.assertEqual(exchange.asks.best_price, 6) self.assertEqual(exchange.bids.best_price, 14) self.assertEqual(exchange.bids.best_qty, 3) self.assertEqual(exchange.asks.n_orders, 1) self.assertEqual(exchange.bids.n_orders, 1) self.assertEqual(transac[0]['party1'], 'T03') self.assertEqual(transac[0]['qty'], 2) self.assertEqual(transac[1]['party1'], 'T02') self.assertEqual(transac[1]['qty'], 1) self.assertEqual(actual, 3)
def test_empty_po_025(self): exchange = Exchange() exchange.asks = Orderbook_half('asks', 1) exchange.bids = Orderbook_half('bids', 100) order00 = Order('T01', 'Ask', 10, 1, 1, 0, 'LIM') order01 = Order('T01', 'Bid', 3, 2, 1, 0, 'MKT') exchange.add_order(order00, False) exchange.process_order2(3, order01, False) self.assertEqual(exchange.bids.lob, collections.OrderedDict()) self.assertEqual(exchange.asks.lob, collections.OrderedDict())
def test_dec_bid(self): exchange = Exchange() exchange.asks = Orderbook_half('Ask', 1) exchange.bids = Orderbook_half('Bid', 100) order01 = Order('T01', 'Bid', 3, 5, 1, 0, 'LIM') order03 = Order('T02', 'Bid', 5, 2, 1, 0, 'LIM') exchange.add_order(order01, False) exchange.add_order(order03, False) exchange.bids.decrement_order(3, 'T01', 5) self.assertEqual(exchange.bids.n_orders, 1) self.assertEqual(exchange.bids.best_qty, 2)
def test_processOrder_bid_wrong_price(self): exchange = Exchange() exchange.asks = Orderbook_half('Ask', 1) exchange.bids = Orderbook_half('Bid', 100) order01 = Order('T02', 'Ask', 13, 1, 1, 0, 'LIM') order02 = Order('T01', 'Ask', 14, 3, 1, 0, 'LIM') order03 = Order('T03', 'Ask', 15, 2, 1, 0, 'LIM') exchange.add_order(order01, False) exchange.add_order(order03, False) exchange.add_order(order02, False) order02 = Order('T01', 'Bid', 10, 6, 1, 0, 'LIM') transac, actual = exchange.process_order2(12, order02, False) self.assertEqual(len(transac), 0)
def test_delete_best_bid03(self): exchange = Exchange() exchange.asks = Orderbook_half('Ask', 1) exchange.bids = Orderbook_half('Bid', 100) order01 = Order('T02', 'Bid', 3, 2, 1, 0, 'LIM') order03 = Order('T01', 'Bid', 5, 10, 1, 0, 'LIM') order02 = Order('T01', 'Ask', 2, 3, 1, 0, 'LIM') exchange.add_order(order01, False) exchange.add_order(order03, False) best_price_counterparty, order_del_qid, del_in_trader, trade_price, quantity_decremented = exchange.bids.delete_best( order02.tid, order02.qty) self.assertEqual(quantity_decremented, 2) self.assertEqual(exchange.bids.n_orders, 1) self.assertEqual(trade_price, 3)
def test_dec_ask02(self): exchange = Exchange() exchange.asks = Orderbook_half('Ask', 1) exchange.bids = Orderbook_half('Bid', 100) order01 = Order('T01', 'Ask', 3, 1, 1, 0, 'LIM') order03 = Order('T02', 'Ask', 5, 2, 1, 0, 'LIM') exchange.add_order(order01, False) exchange.add_order(order03, False) exchange.asks.decrement_order(3, 'T01', 1) self.assertEqual(exchange.asks.n_orders, 1) self.assertEqual( exchange.asks.lob, collections.OrderedDict([(5, [2, [[1, 2, 'T02', 1]]])])) self.assertEqual(exchange.asks.best_qty, 2)
def test_adding_exchange_bid(self): exchange = Exchange() exchange.asks = Orderbook_half('asks', 1) exchange.bids = Orderbook_half('bids', 100) order01 = Order('T01', 'Bid', 3, 1, 1, 0, 'LIM') order03 = Order('T01', 'Bid', 5, 2, 1, 0, 'LIM') exchange.bids.book_add(order01) exchange.bids.book_add(order03) self.assertEqual(exchange.bids.n_orders, 1) self.assertEqual( exchange.bids.lob, collections.OrderedDict([(5, [2, [[1, 2, 'T01', 0]]])])) order02 = Order('T01', 'Bid', 6, 3, 1, 0, 'LIM') exchange.bids.book_add(order02) self.assertEqual(exchange.bids.n_orders, 1)
def test_dec_bid(self): exchange = Exchange() exchange.asks = Orderbook_half('Ask', 1) exchange.bids = Orderbook_half('Bid', 100) order01 = Order('T01', 'Bid', 3, 5, 1, 0, 'LIM') order03 = Order('T02', 'Bid', 5, 10, 1, 0, 'LIM') exchange.add_order(order01, False) exchange.add_order(order03, False) exchange.bids.decrement_order(5, 'T02', 1) self.assertEqual(exchange.bids.n_orders, 2) self.assertEqual(exchange.bids.best_qty, 9) self.assertEqual( exchange.bids.lob, collections.OrderedDict([(5, [9, [[1, 9, 'T02', 1]]]), (3, [5, [[1, 5, 'T01', 0]]])]))
def test_processOrder_exchange_MKT06(self): exchange = Exchange() exchange.asks = Orderbook_half('Ask', 1) exchange.bids = Orderbook_half('Bid', 100) order01 = Order('T01', 'Ask', 3, 3, 1, 0, 'LIM') order03 = Order('T02', 'Ask', 5, 2, 1, 0, 'LIM') exchange.add_order(order01, False) exchange.add_order(order03, False) order02 = Order('T03', 'Bid', 6, 2, 1, 0, 'MKT') transac, actual = exchange.process_order2(12, order02, False) self.assertEqual(exchange.bids.best_qty, 0) self.assertEqual(exchange.bids.n_orders, 0) self.assertEqual(exchange.asks.n_orders, 2) self.assertEqual(transac[0]['party1'], 'T01') self.assertEqual(transac[0]['qty'], 2) self.assertEqual(actual, 2)
def test_delete(self): bookhalf = Orderbook_half('Bid', 100) order01 = Order('T01', 'Bid', 1, 1, 1, 0, 'LIM') bookhalf.book_add(order01) bookhalf.book_del(order01) self.assertEqual(bookhalf.best_qty, 0) self.assertEqual(bookhalf.n_orders, 0)
def test_add_and_del_order02(self): exchange = Exchange() exchange.asks = Orderbook_half('asks', 1) exchange.bids = Orderbook_half('bids', 100) order01 = Order('T01', 'Bid', 3, 1, 1, 0, 'LIM') exchange.add_order(order01, False) self.assertEqual(exchange.bids.n_orders, 1) exchange.del_order(2, order01, False) self.assertEqual(exchange.bids.n_orders, 0)
def test_empty_processorder(self): exchange = Exchange() exchange.asks = Orderbook_half('asks', 1) exchange.bids = Orderbook_half('bids', 100) order01 = Order('T01', 'Bid', 3, 1, 1, 0, 'MKT') transac, qty = exchange.process_order2(3, order01, False) self.assertEqual(qty, 0) self.assertEqual(exchange.bids.lob, collections.OrderedDict()) self.assertEqual(exchange.asks.lob, collections.OrderedDict())
def test_processOrder_exchange_empty01(self): exchange = Exchange() exchange.asks = Orderbook_half('Ask', 1) exchange.bids = Orderbook_half('Bid', 100) order02 = Order('T03', 'Bid', 6, 10, 1, 0, 'LIM') transac, actual = exchange.process_order2(12, order02, False) self.assertEqual(exchange.bids.best_qty, 10) self.assertEqual(exchange.bids.best_price, 6) self.assertEqual(exchange.bids.n_orders, 1) self.assertEqual(len(transac), 0) self.assertEqual(actual, 0)
def test_processOrder_bid_wp_mkt(self): exchange = Exchange() exchange.asks = Orderbook_half('Ask', 1) exchange.bids = Orderbook_half('Bid', 100) order01 = Order('T02', 'Ask', 13, 1, 1, 0, 'LIM') order02 = Order('T01', 'Ask', 14, 3, 1, 0, 'LIM') order03 = Order('T03', 'Ask', 15, 2, 1, 0, 'LIM') exchange.add_order(order01, False) exchange.add_order(order03, False) exchange.add_order(order02, False) order02 = Order('T04', 'Bid', 5, 10, 1, 0, 'MKT') transac, actual = exchange.process_order2(12, order02, False) self.assertEqual(exchange.asks.n_orders, 0) self.assertEqual(exchange.bids.n_orders, 0) self.assertEqual(transac[0]['party1'], 'T02') self.assertEqual(transac[0]['qty'], 1) self.assertEqual(transac[1]['party1'], 'T01') self.assertEqual(transac[1]['qty'], 3) self.assertEqual(transac[2]['party1'], 'T03') self.assertEqual(transac[2]['qty'], 2) self.assertEqual(actual, 6)
def test_add(self): GVWY = Trader_Giveaway('GVWY', 'T01', 0.00, 0) order01 = Order('T01', 'Bid', 1, 1, 1, 0, 'LIM') GVWY.add_order(order01, False) self.assertEqual(GVWY.orders[0], order01)
def customer_orders_new(time, last_update, traders, trader_stats, os, pending, verbose): def sysmin_check(price): if price < bse_sys_minprice: print('WARNING: price < bse_sys_min -- clipped') price = bse_sys_minprice return price def sysmax_check(price): if price > bse_sys_maxprice: # todo uncomment line below # print('WARNING: price > bse_sys_max -- clipped') price = bse_sys_maxprice return price def getorderprice(i, sched, n, mode, issuetime): # does the first schedule range include optional dynamic offset function(s)? if len(sched[0]) > 2: offsetfn = sched[0][2] if callable(offsetfn): # same offset for min and max offset_min = offsetfn(issuetime) offset_max = offset_min else: sys.exit( 'FAIL: 3rd argument of sched in getorderprice() not callable' ) if len(sched[0]) > 3: # if second offset function is specfied, that applies only to the max value offsetfn = sched[0][3] if callable(offsetfn): # this function applies to max offset_max = offsetfn(issuetime) else: sys.exit( 'FAIL: 4th argument of sched in getorderprice() not callable' ) else: offset_min = 0.0 offset_max = 0.0 pmin = sysmin_check(offset_min + min(sched[0][0], sched[0][1])) pmax = sysmax_check(offset_max + max(sched[0][0], sched[0][1])) prange = pmax - pmin stepsize = prange / (n - 1) halfstep = round(stepsize / 2.0) if mode == 'fixed': orderprice = pmin + int(i * stepsize) elif mode == 'jittered': orderprice = pmin + int(i * stepsize) + random.randint( -halfstep, halfstep) elif mode == 'random': if len(sched) > 1: # more than one schedule: choose one equiprobably s = random.randint(0, len(sched) - 1) pmin = sysmin_check(min(sched[s][0], sched[s][1])) pmax = sysmax_check(max(sched[s][0], sched[s][1])) orderprice = random.randint(pmin, pmax) else: sys.exit('FAIL: Unknown mode in schedule') orderprice = sysmin_check(sysmax_check(orderprice)) return orderprice def getissuetimes(n_traders, mode, interval, shuffle, fittointerval): interval = float(interval) if n_traders < 1: sys.exit('FAIL: n_traders < 1 in getissuetime()') elif n_traders == 1: tstep = interval else: tstep = interval / (n_traders - 1) arrtime = 0 issuetimes = [] for t in range(n_traders): if mode == 'periodic': arrtime = interval elif mode == 'drip-fixed': arrtime = t * tstep elif mode == 'drip-jitter': arrtime = t * tstep + tstep * random.random() elif mode == 'drip-poisson': # poisson requires a bit of extra work interarrivaltime = random.expovariate(n_traders / interval) arrtime += interarrivaltime else: sys.exit('FAIL: unknown time-mode in getissuetimes()') issuetimes.append(arrtime) # at this point, arrtime is the last arrival time if fittointerval and ((arrtime > interval) or (arrtime < interval)): # generated sum of interarrival times longer than the interval # squish them back so that last arrival falls at t=interval for t in range(n_traders): issuetimes[t] = interval * (issuetimes[t] / arrtime) # optionally randomly shuffle the times if shuffle: for t in range(n_traders): i = (n_traders - 1) - t j = random.randint(0, i) tmp = issuetimes[i] issuetimes[i] = issuetimes[j] issuetimes[j] = tmp return issuetimes def getschedmode(time, os): got_one = False for sched in os: if (sched['from'] <= time) and (time < sched['to']): # within the timezone for this schedule schedrange = sched['ranges'] mode = sched['stepmode'] got_one = True exit # jump out the loop -- so the first matching timezone has priority over any others if not got_one: sys.exit('Fail: time=%5.2f not within any timezone in os=%s' % (time, os)) return (schedrange, mode) n_buyers = trader_stats['n_buyers'] n_sellers = trader_stats['n_sellers'] mcGagents = [ 'LIQ', 'NOISE', 'MARKET_M', 'MOMENTUM', 'MEAN_R', 'SMS', 'SMB' ] shuffle_times = True cancellations = [] # true in the beginning if len(pending) < 1: # list of pending (to-be-issued) customer orders is empty, so generate a new one new_pending = [] # demand side (buyers) issuetimes = getissuetimes(n_buyers, os['timemode'], os['interval'], shuffle_times, True) ordertype = 'Bid' (sched, mode) = getschedmode(time, os['dem']) for t in range(n_buyers): tname = 'B%02d' % t if traders[tname].ttype not in mcGagents: issuetime = time + issuetimes[t] orderprice = getorderprice(t, sched, n_buyers, mode, issuetime) order = Order(tname, ordertype, orderprice, 1, issuetime, -3.14, 'LIM') new_pending.append(order) # supply side (sellers) issuetimes = getissuetimes(n_sellers, os['timemode'], os['interval'], shuffle_times, True) ordertype = 'Ask' (sched, mode) = getschedmode(time, os['sup']) for t in range(n_sellers): tname = 'S%02d' % t if traders[tname].ttype not in mcGagents: issuetime = time + issuetimes[t] orderprice = getorderprice(t, sched, n_sellers, mode, issuetime) order = Order(tname, ordertype, orderprice, 1, issuetime, -3.14, 'LIM') new_pending.append(order) # this is when the customer pending from the above from last round is issued else: # there are pending future orders: issue any whose timestamp is in the past new_pending = [] for order in pending: if order.time < time: # this order should have been issued by now # issue it to the trader tname = order.tid response = traders[tname].add_order(order, verbose) print("ADDED BY CUSTOMER ORDER FUNCTION : " + str(order)) if verbose: print('Customer order: %s %s' % (response, order)) if response == 'LOB_Cancel': cancellations.append(tname) if verbose: print('Cancellations: %s' % (cancellations)) # and then don't add it to new_pending (i.e., delete it) else: # this order stays on the pending list new_pending.append(order) return [new_pending, cancellations]
def test_add(self): bookhalf = Orderbook_half('Bid', 100) order01 = Order('T01', 'Bid', 1, 5, 1, 0, 'LIM') bookhalf.book_add(order01) self.assertEqual(bookhalf.best_qty, 5) self.assertEqual(bookhalf.orders['T01'], order01)