def setUp(self): base_currency = "GBP" leverage = 20 equity = Decimal("100000.00") risk_per_trade = Decimal("0.02") ticker = TickerMock() events = {} self.port = Portfolio(ticker, events, base_currency=base_currency, leverage=leverage, equity=equity, risk_per_trade=risk_per_trade)
def setUp(self): base_currency = "GBP" leverage = 20 equity = Decimal("100000.00") risk_per_trade = Decimal("0.02") ticker = TickerMock() events = {} self.port = Portfolio( ticker, events, base_currency=base_currency, leverage=leverage, equity=equity, risk_per_trade=risk_per_trade )
instrument = "GBP_USD" # Create the OANDA market price streaming class # making sure to provide authentication commands prices = StreamingForexPrices(settings.STREAM_DOMAIN, settings.ACCESS_TOKEN, settings.ACCOUNT_ID, instrument, events) # Create the strategy/signal generator, passing the # instrument and the events queue strategy = TestStrategy(instrument, events) # Create the portfolio object that will be used to # compare the OANDA positions with the local, to # ensure backtesting integrity. portfolio = Portfolio(prices, events, equity=equity) # Create the execution handler making sure to # provide authentication commands execution = OANDAExecutionHandler(settings.API_DOMAIN, settings.ACCESS_TOKEN, settings.ACCOUNT_ID) # Create two separate threads: One for the trading loop # and another for the market price streaming class trade_thread = threading.Thread(target=trade, args=(events, strategy, portfolio, execution, heartbeat)) price_thread = threading.Thread(target=prices.stream_to_queue, args=[]) # Start both threads
class TestPortfolio(unittest.TestCase): def setUp(self): base_currency = "GBP" leverage = 20 equity = Decimal("100000.00") risk_per_trade = Decimal("0.02") ticker = TickerMock() events = {} self.port = Portfolio(ticker, events, base_currency=base_currency, leverage=leverage, equity=equity, risk_per_trade=risk_per_trade) def test_add_position_long(self): position_type = "long" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() self.port.add_new_position(position_type, currency_pair, units, ticker) ps = self.port.positions[currency_pair] self.assertEquals(ps.position_type, position_type) self.assertEquals(ps.currency_pair, currency_pair) self.assertEquals(ps.units, units) self.assertEquals(ps.avg_price, ticker.prices[currency_pair]["ask"]) self.assertEquals(ps.cur_price, ticker.prices[currency_pair]["bid"]) def test_add_position_short(self): position_type = "short" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() self.port.add_new_position(position_type, currency_pair, units, ticker) ps = self.port.positions[currency_pair] self.assertEquals(ps.position_type, position_type) self.assertEquals(ps.currency_pair, currency_pair) self.assertEquals(ps.units, units) self.assertEquals(ps.avg_price, ticker.prices[currency_pair]["bid"]) self.assertEquals(ps.cur_price, ticker.prices[currency_pair]["ask"]) def test_add_position_units_long(self): position_type = "long" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.add_position_units(alt_currency_pair, units) self.assertFalse(apu) # Add a position and test for real position self.port.add_new_position(position_type, currency_pair, units, ticker) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") apu = self.port.add_position_units(currency_pair, units) self.assertTrue(apu) self.assertEqual(ps.avg_price, Decimal("1.511385")) def test_add_position_units_short(self): position_type = "short" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.add_position_units(alt_currency_pair, units) self.assertFalse(apu) # Add a position and test for real position self.port.add_new_position(position_type, currency_pair, units, ticker) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") apu = self.port.add_position_units(currency_pair, units) self.assertTrue(apu) self.assertEqual(ps.avg_price, Decimal("1.51103")) def test_remove_position_units_long(self): position_type = "long" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.remove_position_units(alt_currency_pair, units) self.assertFalse(apu) # Add a position and then add units to it self.port.add_new_position(position_type, currency_pair, units, ticker) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") add_units = Decimal("8000") apu = self.port.add_position_units(currency_pair, add_units) self.assertEqual(ps.units, 10000) self.assertEqual(ps.avg_price, Decimal("1.516122")) # Test removal of (some) of the units ticker.prices["GBPUSD"]["bid"] = Decimal("1.52017") ticker.prices["GBPUSD"]["ask"] = Decimal("1.52134") ticker.prices["USDGBP"]["bid"] = Decimal("0.65782") ticker.prices["USDGBP"]["ask"] = Decimal("0.65732") remove_units = Decimal("3000") rpu = self.port.remove_position_units(currency_pair, remove_units) self.assertTrue(rpu) self.assertEqual(ps.units, Decimal("7000")) self.assertEqual(self.port.balance, Decimal("100007.99")) def test_remove_position_units_short(self): position_type = "short" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.remove_position_units(alt_currency_pair, units) self.assertFalse(apu) # Add a position and then add units to it self.port.add_new_position(position_type, currency_pair, units, ticker) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") add_units = Decimal("8000") apu = self.port.add_position_units(currency_pair, add_units) self.assertEqual(ps.units, 10000) self.assertEqual(ps.avg_price, Decimal("1.51568")) # Test removal of (some) of the units ticker.prices["GBPUSD"]["bid"] = Decimal("1.52017") ticker.prices["GBPUSD"]["ask"] = Decimal("1.52134") ticker.prices["USDGBP"]["bid"] = Decimal("0.65782") ticker.prices["USDGBP"]["ask"] = Decimal("0.65732") remove_units = Decimal("3000") rpu = self.port.remove_position_units(currency_pair, remove_units) self.assertTrue(rpu) self.assertEqual(ps.units, Decimal("7000")) self.assertEqual(self.port.balance, Decimal("99988.84")) def test_close_position_long(self): position_type = "long" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.remove_position_units(alt_currency_pair, units) self.assertFalse(apu) # Add a position and then add units to it self.port.add_new_position(position_type, currency_pair, units, ticker) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") add_units = Decimal("8000") apu = self.port.add_position_units(currency_pair, add_units) self.assertEqual(ps.units, 10000) self.assertEqual(ps.avg_price, Decimal("1.516122")) # Test removal of (some) of the units ticker.prices["GBPUSD"]["bid"] = Decimal("1.52017") ticker.prices["GBPUSD"]["ask"] = Decimal("1.52134") ticker.prices["USDGBP"]["bid"] = Decimal("0.65782") ticker.prices["USDGBP"]["ask"] = Decimal("0.65732") remove_units = Decimal("3000") rpu = self.port.remove_position_units(currency_pair, remove_units) self.assertTrue(rpu) self.assertEqual(ps.units, Decimal("7000")) self.assertEqual(self.port.balance, Decimal("100007.99")) # Close the position cp = self.port.close_position(currency_pair) self.assertTrue(cp) self.assertRaises(ps) # Key doesn't exist self.assertEqual(self.port.balance, Decimal("100026.64")) def test_close_position_short(self): position_type = "short" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.remove_position_units(alt_currency_pair, units) self.assertFalse(apu) # Add a position and then add units to it self.port.add_new_position(position_type, currency_pair, units, ticker) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") add_units = Decimal("8000") apu = self.port.add_position_units(currency_pair, add_units) self.assertEqual(ps.units, 10000) self.assertEqual(ps.avg_price, Decimal("1.51568")) # Test removal of (some) of the units ticker.prices["GBPUSD"]["bid"] = Decimal("1.52017") ticker.prices["GBPUSD"]["ask"] = Decimal("1.52134") ticker.prices["USDGBP"]["bid"] = Decimal("0.65782") ticker.prices["USDGBP"]["ask"] = Decimal("0.65732") remove_units = Decimal("3000") rpu = self.port.remove_position_units(currency_pair, remove_units) self.assertTrue(rpu) self.assertEqual(ps.units, Decimal("7000")) self.assertEqual(self.port.balance, Decimal("99988.84")) # Close the position cp = self.port.close_position(currency_pair) self.assertTrue(cp) self.assertRaises(ps) # Key doesn't exist self.assertEqual(self.port.balance, Decimal("99962.80"))
pairs = ["GBPUSD"] # Create the OANDA market price streaming class # making sure to provide authentication commands prices = StreamingForexPrices(settings.STREAM_DOMAIN, settings.ACCESS_TOKEN, settings.ACCOUNT_ID, pairs, events) # Create the strategy/signal generator, passing the # instrument and the events queue strategy = TestStrategy(pairs, events) # Create the portfolio object that will be used to # compare the OANDA positions with the local, to # ensure backtesting integrity. portfolio = Portfolio(prices, events, equity=equity, backtest=False) # Create the execution handler making sure to # provide authentication commands execution = OANDAExecutionHandler(settings.API_DOMAIN, settings.ACCESS_TOKEN, settings.ACCOUNT_ID) # Create two separate threads: One for the trading loop # and another for the market price streaming class trade_thread = threading.Thread(target=trade, args=(events, strategy, portfolio, execution, heartbeat)) price_thread = threading.Thread(target=prices.stream_to_queue, args=[]) # Start both threads
class TestPortfolio(unittest.TestCase): def setUp(self): home_currency = "GBP" leverage = 20 equity = Decimal("100000.00") risk_per_trade = Decimal("0.02") ticker = TickerMock() events = {} self.port = Portfolio( ticker, events, home_currency=home_currency, leverage=leverage, equity=equity, risk_per_trade=risk_per_trade ) def test_add_position_long(self): position_type = "long" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] self.assertEquals(ps.position_type, position_type) self.assertEquals(ps.currency_pair, currency_pair) self.assertEquals(ps.units, units) self.assertEquals(ps.avg_price, ticker.prices[currency_pair]["ask"]) self.assertEquals(ps.cur_price, ticker.prices[currency_pair]["bid"]) def test_add_position_short(self): position_type = "short" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] self.assertEquals(ps.position_type, position_type) self.assertEquals(ps.currency_pair, currency_pair) self.assertEquals(ps.units, units) self.assertEquals(ps.avg_price, ticker.prices[currency_pair]["bid"]) self.assertEquals(ps.cur_price, ticker.prices[currency_pair]["ask"]) def test_add_position_units_long(self): position_type = "long" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.add_position_units( alt_currency_pair, units ) self.assertFalse(apu) # Add a position and test for real position self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") apu = self.port.add_position_units( currency_pair, units ) self.assertTrue(apu) self.assertEqual(ps.avg_price, Decimal("1.511385")) def test_add_position_units_short(self): position_type = "short" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.add_position_units( alt_currency_pair, units ) self.assertFalse(apu) # Add a position and test for real position self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") apu = self.port.add_position_units( currency_pair, units ) self.assertTrue(apu) self.assertEqual(ps.avg_price, Decimal("1.51103")) def test_remove_position_units_long(self): position_type = "long" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.remove_position_units( alt_currency_pair, units ) self.assertFalse(apu) # Add a position and then add units to it self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") add_units = Decimal("8000") apu = self.port.add_position_units( currency_pair, add_units ) self.assertEqual(ps.units, 10000) self.assertEqual(ps.avg_price, Decimal("1.516122")) # Test removal of (some) of the units ticker.prices["GBPUSD"]["bid"] = Decimal("1.52017") ticker.prices["GBPUSD"]["ask"] = Decimal("1.52134") ticker.prices["USDGBP"]["bid"] = Decimal("0.65782") ticker.prices["USDGBP"]["ask"] = Decimal("0.65732") remove_units = Decimal("3000") rpu = self.port.remove_position_units( currency_pair, remove_units ) self.assertTrue(rpu) self.assertEqual(ps.units, Decimal("7000")) self.assertEqual(self.port.balance, Decimal("100007.99")) def test_remove_position_units_short(self): position_type = "short" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.remove_position_units( alt_currency_pair, units ) self.assertFalse(apu) # Add a position and then add units to it self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") add_units = Decimal("8000") apu = self.port.add_position_units( currency_pair, add_units ) self.assertEqual(ps.units, 10000) self.assertEqual(ps.avg_price, Decimal("1.51568")) # Test removal of (some) of the units ticker.prices["GBPUSD"]["bid"] = Decimal("1.52017") ticker.prices["GBPUSD"]["ask"] = Decimal("1.52134") ticker.prices["USDGBP"]["bid"] = Decimal("0.65782") ticker.prices["USDGBP"]["ask"] = Decimal("0.65732") remove_units = Decimal("3000") rpu = self.port.remove_position_units( currency_pair, remove_units ) self.assertTrue(rpu) self.assertEqual(ps.units, Decimal("7000")) self.assertEqual(self.port.balance, Decimal("99988.83")) def test_close_position_long(self): position_type = "long" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.remove_position_units( alt_currency_pair, units ) self.assertFalse(apu) # Add a position and then add units to it self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") add_units = Decimal("8000") apu = self.port.add_position_units( currency_pair, add_units ) self.assertEqual(ps.units, 10000) self.assertEqual(ps.avg_price, Decimal("1.516122")) # Test removal of (some) of the units ticker.prices["GBPUSD"]["bid"] = Decimal("1.52017") ticker.prices["GBPUSD"]["ask"] = Decimal("1.52134") ticker.prices["USDGBP"]["bid"] = Decimal("0.65782") ticker.prices["USDGBP"]["ask"] = Decimal("0.65732") remove_units = Decimal("3000") rpu = self.port.remove_position_units( currency_pair, remove_units ) self.assertTrue(rpu) self.assertEqual(ps.units, Decimal("7000")) self.assertEqual(self.port.balance, Decimal("100007.99")) # Close the position cp = self.port.close_position(currency_pair) self.assertTrue(cp) self.assertRaises(ps) # Key doesn't exist self.assertEqual(self.port.balance, Decimal("100026.63")) def test_close_position_short(self): position_type = "short" currency_pair = "GBPUSD" units = Decimal("2000") ticker = TickerMock() # Test for no position alt_currency_pair = "USDCAD" apu = self.port.remove_position_units( alt_currency_pair, units ) self.assertFalse(apu) # Add a position and then add units to it self.port.add_new_position( position_type, currency_pair, units, ticker ) ps = self.port.positions[currency_pair] # Test for addition of units ticker.prices["GBPUSD"]["bid"] = Decimal("1.51878") ticker.prices["GBPUSD"]["ask"] = Decimal("1.51928") ticker.prices["USDGBP"]["bid"] = Decimal("0.65842") ticker.prices["USDGBP"]["ask"] = Decimal("0.65821") add_units = Decimal("8000") apu = self.port.add_position_units( currency_pair, add_units ) self.assertEqual(ps.units, 10000) self.assertEqual(ps.avg_price, Decimal("1.51568")) # Test removal of (some) of the units ticker.prices["GBPUSD"]["bid"] = Decimal("1.52017") ticker.prices["GBPUSD"]["ask"] = Decimal("1.52134") ticker.prices["USDGBP"]["bid"] = Decimal("0.65782") ticker.prices["USDGBP"]["ask"] = Decimal("0.65732") remove_units = Decimal("3000") rpu = self.port.remove_position_units( currency_pair, remove_units ) self.assertTrue(rpu) self.assertEqual(ps.units, Decimal("7000")) self.assertEqual(self.port.balance, Decimal("99988.83")) # Close the position cp = self.port.close_position(currency_pair) self.assertTrue(cp) self.assertRaises(ps) # Key doesn't exist self.assertEqual(self.port.balance, Decimal("99962.77"))
portfolio.output_results() if __name__ == "__main__": heartbeat = 0.0 events = Queue.Queue() equity = settings.EQUITY # Load the historic CSV tick data files pairs = ["GBPUSD"] csv_dir = settings.CSV_DATA_DIR if csv_dir is None: print "No historic data directory provided - backtest terminating." sys.exit() # Create the historic tick data streaming class ticker = HistoricCSVPriceHandler(pairs, events, csv_dir) # Create the strategy/signal generator, passing the # instrument and the events queue strategy = MovingAverageCrossStrategy(pairs, events, 500, 2000) # Create the portfolio object to track trades portfolio = Portfolio(ticker, events, equity=equity) # Create the simulated execution handler execution = SimulatedExecution() # Carry out the backtest loop backtest(events, ticker, strategy, portfolio, execution, heartbeat)
portfolio.output_results() if __name__ == "__main__": heartbeat = 0.0 events = queue.Queue() equity = settings.EQUITY # Load the historic CSV tick data filesw pairs = ["GBPUSD"] csv_dir = settings.CSV_DATA_DIR if csv_dir is None: print("No historic data directory provided - backtest terminating.") sys.exit() # Create the historic tick data streaming class ticker = HistoricCSVPriceHandler(pairs, events, csv_dir) # Create the strategy/signal generator, passing the # instrument and the events queue strategy = MovingAverageCrossStrategy(pairs, events, 500, 2000) # Create the portfolio object to track trades portfolio = Portfolio(ticker, events, equity=equity, backtest=True) # Create the simulated execution handler execution = SimulatedExecution() # Carry out the backtest loop backtest(events, ticker, strategy, portfolio, execution, heartbeat)
# Trade GBP/USD instrument = "GBP_USD" # Create the OANDA market price streaming class # making sure to provide authentication commands prices = StreamingForexPrices(STREAM_DOMAIN, ACCESS_TOKEN, ACCOUNT_ID, instrument, events) # Create the strategy/signal generator, passing the # instrument and the events queue strategy = TestStrategy(instrument, events) # Create the portfolio object that will be used to # compare the OANDA positions with the local, to # ensure backtesting integrity. portfolio = Portfolio(prices, events, equity=100000.0) # Create the execution handler making sure to # provide authentication commands execution = Execution(API_DOMAIN, ACCESS_TOKEN, ACCOUNT_ID) # Create two separate threads: One for the trading loop # and another for the market price streaming class trade_thread = threading.Thread(target=trade, args=(events, strategy, portfolio, execution)) price_thread = threading.Thread(target=prices.stream_to_queue, args=[]) # Start both threads trade_thread.start() price_thread.start()