Exemple #1
0
class TestBackTest(unittest.TestCase):

	def setUp(self):
		self.sym = "EURUSD"
		self.aEq = self.assertEqual
		self.aIn = self.assertIn
		self.aRaise = self.assertRaises
		self.aItEq = self.assertItemsEqual
		self.bt = BackTest()

	def tearDown(self):
		pass

	def bar_close(self, sym, b):
		print "bar_close: ", b.date

	def testAddSym(self):
		
		f = "yo" 
		self.bt.add_input(self.sym, f, bartype=Bar)
		self.aEq([(self.sym, f, Bar)], self.bt.inputs)
		self.aEq(self.bt.bars.keys(), [self.sym])

	def testBuyMarket(self):

		b1 = Bar(self.sym, "20010102-230000,EURUSD,0.9507,0.9509,0.9505,0.9506")
		o1 = Order(self.sym, dir=Order.BUY, type=Order.MARKET, level=0.9508, size=10000) 
		self.bt.book.add(o1)
	
		#self.bt.bar_close = self.bar_close

		self.bt.next_bar(self.sym, b1)
		
		#should have an open position
		self.aEq(len(self.bt.poslist.open), 1)
		p = self.bt.poslist.open[0]
		self.aEq(p.order_id, o1.id)
		self.aEq(p.mark, b1.cl)
		self.aEq(p.entry, o1.level)

	def testBuyLimit(self):

		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.9500,0.9506")
		o1 = Order(self.sym, dir=Order.BUY, type=Order.LIMIT, level=0.9501, size=10000) 
		self.bt.book.add(o1)
	
		self.bt.next_bar(self.sym, b1)
		
		#should be no fill for b1 
		self.aEq(len(self.bt.poslist.open), 0)

		self.bt.next_bar(self.sym, b2)
		self.aEq(len(self.bt.poslist.open), 1)

	def testBuyStop(self):

		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.9511,0.9500,0.9506")
		o1 = Order(self.sym, dir=Order.BUY, type=Order.STOP, level=0.9510, size=10000) 
		self.bt.book.add(o1)
	
		self.bt.next_bar(self.sym, b1)
		self.aEq(len(self.bt.poslist.open), 0)

		self.bt.next_bar(self.sym, b2)
		self.aEq(len(self.bt.poslist.open), 1)

	def testSellLimit(self):

		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.9511,0.9505,0.9506")
		o1 = Order(self.sym, dir=Order.SELL, type=Order.LIMIT, level=0.9510, size=-10000) 
		self.bt.book.add(o1)
	
		self.bt.next_bar(self.sym, b1)
		self.aEq(len(self.bt.poslist.open), 0)

		self.bt.next_bar(self.sym, b2)
		self.aEq(len(self.bt.poslist.open), 1)

	def testSellStop(self):

		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")
		o1 = Order(self.sym, dir=Order.SELL, type=Order.STOP, level=0.9499, size=-10000) 
		self.bt.book.add(o1)
	
		self.bt.next_bar(self.sym, b1)
		self.aEq(len(self.bt.poslist.open), 0)

		self.bt.next_bar(self.sym, b2)
		self.aEq(len(self.bt.poslist.open), 1)

	def testTP(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.9511,0.9505,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, 100005)

	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 testRewind(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.9509,0.9505,0.9506")
		b2 = 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, b2)
		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 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) 
Exemple #2
0
class TestBackTest(unittest.TestCase):

	def setUp(self):
		self.sym = "EURUSD"
		self.aEq = self.assertEqual
		self.aIn = self.assertIn
		self.aRaise = self.assertRaises
		self.aItEq = self.assertItemsEqual
		self.bt = BackTest()

	def tearDown(self):
		pass

	def bar_close(self, sym, b):
		print "bar_close: ", b.date

	def testAddSym(self):
		
		f = "yo" 
		self.bt.add_input(self.sym, f, bartype=Bar)
		self.aEq([(self.sym, f, Bar)], self.bt.inputs)
		self.aEq(self.bt.bars.keys(), [self.sym])

	def testBuyMarket(self):

		b1 = Bar(self.sym, "20010102-230000,EURUSD,0.9507,0.9509,0.9505,0.9506")
		o1 = Order(self.sym, dir=Order.BUY, type=Order.MARKET, level=0.9508, size=10000) 
		self.bt.book.add(o1)
	
		#self.bt.bar_close = self.bar_close

		self.bt.next_bar(self.sym, b1)
		
		#should have an open position
		self.aEq(len(self.bt.poslist.open), 1)
		p = self.bt.poslist.open[0]
		self.aEq(p.order_id, o1.id)
		self.aEq(p.mark, b1.cl)
		self.aEq(p.entry, o1.level)

	def testBuyLimit(self):

		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.9500,0.9506")
		o1 = Order(self.sym, dir=Order.BUY, type=Order.LIMIT, level=0.9501, size=10000) 
		self.bt.book.add(o1)
	
		self.bt.next_bar(self.sym, b1)
		
		#should be no fill for b1 
		self.aEq(len(self.bt.poslist.open), 0)

		self.bt.next_bar(self.sym, b2)
		self.aEq(len(self.bt.poslist.open), 1)

	def testBuyStop(self):

		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.9511,0.9500,0.9506")
		o1 = Order(self.sym, dir=Order.BUY, type=Order.STOP, level=0.9510, size=10000) 
		self.bt.book.add(o1)
	
		self.bt.next_bar(self.sym, b1)
		self.aEq(len(self.bt.poslist.open), 0)

		self.bt.next_bar(self.sym, b2)
		self.aEq(len(self.bt.poslist.open), 1)

	def testSellLimit(self):

		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.9511,0.9505,0.9506")
		o1 = Order(self.sym, dir=Order.SELL, type=Order.LIMIT, level=0.9510, size=-10000) 
		self.bt.book.add(o1)
	
		self.bt.next_bar(self.sym, b1)
		self.aEq(len(self.bt.poslist.open), 0)

		self.bt.next_bar(self.sym, b2)
		self.aEq(len(self.bt.poslist.open), 1)

	def testSellStop(self):

		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")
		o1 = Order(self.sym, dir=Order.SELL, type=Order.STOP, level=0.9499, size=-10000) 
		self.bt.book.add(o1)
	
		self.bt.next_bar(self.sym, b1)
		self.aEq(len(self.bt.poslist.open), 0)

		self.bt.next_bar(self.sym, b2)
		self.aEq(len(self.bt.poslist.open), 1)

	def testTP(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.9511,0.9505,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, 100005)

	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 testRewind(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.9509,0.9505,0.9506")
		b2 = 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, b2)
		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 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)