def setUp(self): self.sym = "EURUSD" self.aEq = self.assertEqual self.aIn = self.assertIn self.aItEq = self.assertItemsEqual self.aRaise = self.assertRaises self.debug = False #self.ob = OrderBook(debug=True) self.ob = OrderBook(self.debug)
class TestOrderBookObject(unittest.TestCase): def setUp(self): self.sym = "EURUSD" self.aEq = self.assertEqual self.aIn = self.assertIn self.aItEq = self.assertItemsEqual self.aRaise = self.assertRaises self.debug = False #self.ob = OrderBook(debug=True) self.ob = OrderBook(self.debug) def tearDown(self): #self.ob = OrderBook(self.debug) pass def testAddSingle(self): o1 = Order() self.ob.add(o1) #adding an order should add it to the active queue of the book self.aEq(len(self.ob.active), 1) self.aIn(o1.id, self.ob.active) #and set its state to active self.aEq(o1.state, Order.ACTIVE) #test single dup self.aRaise(InvalidOrderException, self.ob.add, o1) def testAddIter(self): tl = (Order(), Order(), Order()) self.ob.add(tl) self.aItEq([x.id for x in tl], self.ob.active) for o in tl: self.aEq(o.state, Order.ACTIVE) #test dupes are detected self.aRaise(InvalidOrderException, self.ob.add, tl[0]) self.aRaise(InvalidOrderException, self.ob.add, tl) def testAddMult(self): o1 = Order() o2 = Order() o3 = Order() self.ob.add(o1, o2, o3) self.aItEq([o1.id, o2.id, o3.id], self.ob.active) for o in (o1, o2, o3): self.aEq(o.state, Order.ACTIVE) self.aRaise(InvalidOrderException, self.ob.add, o1, o2, o3) def testAddPending(self): o1 = Order() o2 = Order() #must still add o2 o1.trigger(o2) #triggered orders should be set to pending an added to pending queue self.ob.add(o1, o2) self.aEq(o1.state, Order.ACTIVE) self.aEq(o2.state, Order.PENDING) self.aIn(o2.id, self.ob.pending) def testCancel(self): o1 = Order() o2 = Order() self.ob.add(o1, o2) self.ob.cancel(o1) #cancel by id self.ob.cancel(o2.id) self.aEq(o1.state, Order.CANCELLED) self.aEq(o2.state, Order.CANCELLED) self.aItEq([o1.id, o2.id], self.ob.cancelled) #cancel a non existent order returns false self.aEq(self.ob.cancel(None), False) self.aEq(self.ob.cancel(-1), False) def testCancelTriggers(self): o1 = Order() o2 = Order() o3 = Order() o1.trigger(o2) o2.trigger(o3) self.ob.add(o1, o2, o3) #cancel o1 should cancel o2 as well and add both to the cancelled queue self.aEq(self.ob.cancel(o1), True) self.aEq(o1.state, Order.CANCELLED) self.aEq(o2.state, Order.CANCELLED) self.aEq(o3.state, Order.CANCELLED) self.aItEq([o1.id, o2.id, o3.id], self.ob.cancelled) def testCancelAll(self): o1 = Order() o2 = Order() o3 = Order() o4 = Order() o1.trigger(o2) o1.trigger(o3) self.ob.add(o1, o2, o3, o4) self.ob.cancel_all() self.aItEq([o1.id, o2.id, o3.id, o4.id], self.ob.cancelled) def testFill(self): o1 = Order() self.ob.add(o1) self.aEq(self.ob.fill(o1), True) self.aEq(o1.state, Order.FILLED) self.aEq([o1.id], self.ob.filled) self.aEq(self.ob.fill(None), False) self.aEq(self.ob.fill(o1), False) def testFillTrigger(self): o1 = Order() o2 = Order() o1.trigger(o2) self.ob.add(o1, o2) self.aEq(o2.state, Order.PENDING) self.aEq(self.ob.fill(o1), True) self.aEq(o2.state, Order.ACTIVE) self.aEq([o2.id], self.ob.active) def testFillCancel(self): o1 = Order() o2 = Order() o1.cancel(o2) self.ob.add(o1, o2) self.aEq(self.ob.fill(o1), True) self.aEq(o2.state, Order.CANCELLED) self.aEq([o2.id], self.ob.cancelled) def testGetFills(self): o1 = Order(self.sym, dir=Order.BUY, type=Order.LIMIT, level=0.9551, size=1) o2 = Order(symbol="NOPE", dir=Order.BUY, type=Order.LIMIT, level=0.9551, size=1) b1 = Bar(self.sym, "20010102-230000,EURUSD,0.9507,0.9509,0.9505,0.9506") b2 = Bar(self.sym, "20010102-230000,EURUSD,0.9507,0.9560,0.9505,0.9506") self.ob.add(o1) self.ob.add(o2) self.aEq([], self.ob.get_fills(b1)) self.aEq([o1], self.ob.get_fills(b2)) #market orders always get filled the next bar #the "fill price" is really just the level set on the order ... o3 = Order(self.sym, dir=Order.BUY, type=Order.MARKET, level=0.9551, size=1) self.ob.add(o3) self.aEq([o3], self.ob.get_fills(b1))