def testOpenRewind(self): #in this case we have a sl/tp, and get a bar which triggers them both #when this happens, we cancel both the orders and unwind the original position #as if it never happened. If this is happening a lot you need lower time frame data #stop loss/take profit b1 = Bar(self.sym, "20010102-230000,EURUSD,0.9507,0.9510,0.9499,0.9506") #buy order at 9505 o1 = Order(self.sym, dir=Order.BUY, type=Order.MARKET, level=0.9505, size=10000) #stop loss at 9499 sl = Order(self.sym, dir=Order.SELL, type=Order.STOP, level=0.9499, size=-10000) #take profit at 9510 tp = Order(self.sym, dir=Order.SELL, type=Order.LIMIT, level=0.9510, size=-10000) #stop loss hit cancels tp and vice versa Order.OCO(sl, tp) #when the order is filled it activates sl/tp o1.trigger(sl, tp) self.bt.book.add(o1, sl, tp) self.bt.next_bar(self.sym, b1) #the order should be filled self.aEq(len(self.bt.poslist.open), 1) self.aItEq([sl.id, tp.id], self.bt.book.active) self.bt.next_bar(self.sym, b1) self.aEq(len(self.bt.poslist.open), 0) self.aEq(len(self.bt.poslist.closed), 0) self.aEq(len(self.bt.poslist.rewinded), 1) self.aEq(len(self.bt.book.active), 0) self.aEq(self.bt.equity, 100000)
def testSL(self): #stop loss/take profit 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.9509,0.9499,0.9506") #buy order at 9505 o1 = Order(self.sym, dir=Order.BUY, type=Order.MARKET, level=0.9505, size=10000) #stop loss at 9499 sl = Order(self.sym, dir=Order.SELL, type=Order.STOP, level=0.9499, size=-10000) #take profit at 9510 tp = Order(self.sym, dir=Order.SELL, type=Order.LIMIT, level=0.9510, size=-10000) #stop loss hit cancels tp and vice versa Order.OCO(sl, tp) #when the order is filled it activates sl/tp o1.trigger(sl, tp) self.bt.book.add(o1, sl, tp) self.bt.next_bar(self.sym, b1) #the order should be filled self.aEq(len(self.bt.poslist.open), 1) self.aItEq([sl.id, tp.id], self.bt.book.active) self.bt.next_bar(self.sym, b2) self.aEq(len(self.bt.poslist.open), 0) self.aEq(len(self.bt.poslist.closed), 1) self.aEq(len(self.bt.book.active), 0) self.aEq(self.bt.equity, 99994)
def test_trigger(self): o1 = Order() o2 = Order() o1.trigger(o2) self.aEq(len(o1.triggers), 1) self.aIn(o2.id, o1.triggers) self.aEq(o2.trigger_parent, o1.id) self.aEq(o2.triggered(), True)
def testAddTriggered(self): o1 = Order(self.sym, dir=Order.BUY, type=Order.MARKET, level=1.0000, size=10000) o2 = Order(self.sym, dir=Order.SELL, type=Order.LIMIT, level=1.1000, size=-10000) o1.trigger(o2) p1 = self.pl.add(o1, datetime.now()) p2 = self.pl.add(o2, datetime.now()) self.aEq([p1], self.pl.closed) self.aEq([], self.pl.open)
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 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 test_trigger_iter(self): o1 = Order() o2 = Order() o3 = Order() o1.trigger(o2, o3) self.aEq(len(o1.triggers), 2) self.aIn(o2.id, o1.triggers) self.aIn(o3.id, o1.triggers) self.aEq(o2.trigger_parent, o1.id) self.aEq(o2.triggered(), True) self.aEq(o3.trigger_parent, o1.id) self.aEq(o3.triggered(), True)
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 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)