def setUp(self): """ Set up the Position object that will store the PnL. """ self.position = Position("BOT", "XOM", 100, PriceParser.parse(74.78), PriceParser.parse(1.00), PriceParser.parse(74.78), PriceParser.parse(74.80))
def setUp(self): """ Set up the Position object that will store the PnL. """ self.position = Position( "BOT", "XOM", 100, PriceParser.parse(74.78), PriceParser.parse(1.00), PriceParser.parse(74.78), PriceParser.parse(74.80) )
def __init__(self): self.tickers = { "AAA": { "adj_close": PriceParser.parse(50.00) }, "BBB": { "adj_close": PriceParser.parse(100.00) }, "CCC": { "adj_close": PriceParser.parse(1.00) }, }
def test_open_short_position(self): self.assertEqual(PriceParser.display(self.position.cost_basis), -7768.00) self.assertEqual(PriceParser.display(self.position.market_value), -7769.00) self.assertEqual(PriceParser.display(self.position.unrealised_pnl), -1.00) self.assertEqual(PriceParser.display(self.position.realised_pnl), -1.0) self.position.update_market_value( PriceParser.parse(77.72), PriceParser.parse(77.72) ) self.assertEqual(PriceParser.display(self.position.cost_basis), -7768.00) self.assertEqual(PriceParser.display(self.position.market_value), -7772.00) self.assertEqual(PriceParser.display(self.position.unrealised_pnl), -4.00) self.assertEqual(PriceParser.display(self.position.realised_pnl), -4.0)
def test_calculate_round_trip(self): """ After the subsequent purchase, carry out two more buys/longs and then close the position out with two additional sells/shorts. The following prices have been tested against those calculated via Interactive Brokers' Trader Workstation (TWS). """ self.position.transact_shares( "BOT", 100, PriceParser.parse(74.63), PriceParser.parse(1.00) ) self.position.transact_shares( "BOT", 250, PriceParser.parse(74.620), PriceParser.parse(1.25) ) self.position.transact_shares( "SLD", 200, PriceParser.parse(74.58), PriceParser.parse(1.00) ) self.position.transact_shares( "SLD", 250, PriceParser.parse(75.26), PriceParser.parse(1.25) ) self.position.update_market_value( PriceParser.parse(77.75), PriceParser.parse(77.77) ) self.assertEqual(self.position.action, "BOT") self.assertEqual(self.position.ticker, "XOM") self.assertEqual(self.position.quantity, 0) self.assertEqual(self.position.buys, 450) self.assertEqual(self.position.sells, 450) self.assertEqual(self.position.net, 0) self.assertEqual( PriceParser.display(self.position.avg_bot, 5), 74.65778 ) self.assertEqual( PriceParser.display(self.position.avg_sld, 5), 74.95778 ) self.assertEqual(PriceParser.display(self.position.total_bot), 33596.00) self.assertEqual(PriceParser.display(self.position.total_sld), 33731.00) self.assertEqual(PriceParser.display(self.position.net_total), 135.00) self.assertEqual(PriceParser.display(self.position.total_commission), 5.50) self.assertEqual(PriceParser.display(self.position.net_incl_comm), 129.50) self.assertEqual( PriceParser.display(self.position.avg_price, 3), 74.665 ) self.assertEqual(PriceParser.display(self.position.cost_basis), 0.00) self.assertEqual(PriceParser.display(self.position.market_value), 0.00) self.assertEqual(PriceParser.display(self.position.unrealised_pnl), 0.00) self.assertEqual(PriceParser.display(self.position.realised_pnl), 129.50)
def test_calculate_round_trip(self): """ After the subsequent sale, carry out two more sells/shorts and then close the position out with two additional buys/longs. The following prices have been tested against those calculated via Interactive Brokers' Trader Workstation (TWS). """ self.position.transact_shares( "SLD", 100, PriceParser.parse(77.68), PriceParser.parse(1.00) ) self.position.transact_shares( "SLD", 50, PriceParser.parse(77.70), PriceParser.parse(1.00) ) self.position.transact_shares( "BOT", 100, PriceParser.parse(77.77), PriceParser.parse(1.00) ) self.position.transact_shares( "BOT", 150, PriceParser.parse(77.73), PriceParser.parse(1.00) ) self.position.update_market_value( PriceParser.parse(77.72), PriceParser.parse(77.72) ) self.assertEqual(self.position.action, "SLD") self.assertEqual(self.position.ticker, "PG") self.assertEqual(self.position.quantity, 0) self.assertEqual(self.position.buys, 250) self.assertEqual(self.position.sells, 250) self.assertEqual(self.position.net, 0) self.assertEqual( PriceParser.display(self.position.avg_bot, 3), 77.746 ) self.assertEqual( PriceParser.display(self.position.avg_sld, 3), 77.688 ) self.assertEqual(PriceParser.display(self.position.total_bot), 19436.50) self.assertEqual(PriceParser.display(self.position.total_sld), 19422.00) self.assertEqual(PriceParser.display(self.position.net_total), -14.50) self.assertEqual(PriceParser.display(self.position.total_commission), 5.00) self.assertEqual(PriceParser.display(self.position.net_incl_comm), -19.50) self.assertEqual( PriceParser.display(self.position.avg_price, 5), 77.67600 ) self.assertEqual(PriceParser.display(self.position.cost_basis), 0.00) self.assertEqual(PriceParser.display(self.position.market_value), 0.00) self.assertEqual(PriceParser.display(self.position.unrealised_pnl), 0.00) self.assertEqual(PriceParser.display(self.position.realised_pnl), -19.50)
def _create_event(self, index, period, ticker, row): """ Obtain all elements of the bar from a row of dataframe and return a BarEvent """ open_price = PriceParser.parse(row["Open"]) low_price = PriceParser.parse(row["Low"]) high_price = PriceParser.parse(row["High"]) close_price = PriceParser.parse(row["Close"]) adj_close_price = PriceParser.parse(row["Close"]) volume = int(row["Volume"]) bev = BarEvent(ticker, index, period, open_price, high_price, low_price, close_price, volume, adj_close_price) return bev
def test_calculate_round_trip(self): """ After the subsequent purchase, carry out two more buys/longs and then close the position out with two additional sells/shorts. The following prices have been tested against those calculated via Interactive Brokers' Trader Workstation (TWS). """ self.position.transact_shares("BOT", 100, PriceParser.parse(74.63), PriceParser.parse(1.00)) self.position.transact_shares("BOT", 250, PriceParser.parse(74.620), PriceParser.parse(1.25)) self.position.transact_shares("SLD", 200, PriceParser.parse(74.58), PriceParser.parse(1.00)) self.position.transact_shares("SLD", 250, PriceParser.parse(75.26), PriceParser.parse(1.25)) self.position.update_market_value(PriceParser.parse(77.75), PriceParser.parse(77.77)) self.assertEqual(self.position.action, "BOT") self.assertEqual(self.position.ticker, "XOM") self.assertEqual(self.position.quantity, 0) self.assertEqual(self.position.buys, 450) self.assertEqual(self.position.sells, 450) self.assertEqual(self.position.net, 0) self.assertEqual(PriceParser.display(self.position.avg_bot, 5), 74.65778) self.assertEqual(PriceParser.display(self.position.avg_sld, 5), 74.95778) self.assertEqual(PriceParser.display(self.position.total_bot), 33596.00) self.assertEqual(PriceParser.display(self.position.total_sld), 33731.00) self.assertEqual(PriceParser.display(self.position.net_total), 135.00) self.assertEqual(PriceParser.display(self.position.total_commission), 5.50) self.assertEqual(PriceParser.display(self.position.net_incl_comm), 129.50) self.assertEqual(PriceParser.display(self.position.avg_price, 3), 74.665) self.assertEqual(PriceParser.display(self.position.cost_basis), 0.00) self.assertEqual(PriceParser.display(self.position.market_value), 0.00) self.assertEqual(PriceParser.display(self.position.unrealised_pnl), 0.00) self.assertEqual(PriceParser.display(self.position.realised_pnl), 129.50)
def test_price_from_long(self): parsed = PriceParser.parse(self.long) self.assertEqual(parsed, 200) if PY2: self.assertIsInstance(parsed, long) # noqa else: self.assertIsInstance(parsed, int)
def run_monthly_rebalance(config, testing, filename, benchmark, ticker_weights, title_str, start_date, end_date, equity): config = settings.from_file(config, testing) tickers = [t for t in ticker_weights.keys()] # Set up variables needed for backtest events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_equity = PriceParser.parse(equity) # Use Yahoo Daily Price Handler price_handler = YahooDailyCsvBarPriceHandler(csv_dir, events_queue, tickers, start_date=start_date, end_date=end_date) # Use the monthly liquidate and rebalance strategy strategy = MonthlyLiquidateRebalanceStrategy(tickers, events_queue) strategy = Strategies(strategy, DisplayStrategy()) # Use the liquidate and rebalance position sizer # with prespecified ticker weights position_sizer = LiquidateRebalancePositionSizer(ticker_weights) # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler(initial_equity, events_queue, price_handler, position_sizer, risk_manager) # Use the ExampleCompliance component compliance = ExampleCompliance(config)
def subscribe_ticker(self, ticker): """ Subscribes the price handler to a new ticker symbol. """ if ticker not in self.tickers: try: self._open_ticker_price_csv(ticker) dft = self.tickers_data[ticker] row0 = dft.iloc[0] close = PriceParser.parse(row0["Close"]) # adj_close = PriceParser.parse(row0["Adj Close"]) ticker_prices = { "close": close, # "adj_close": adj_close, "timestamp": dft.index[0] } self.tickers[ticker] = ticker_prices except OSError: print( "Could not subscribe ticker %s " "as no data CSV found for pricing." % ticker ) else: print( "Could not subscribe ticker %s " "as is already subscribed." % ticker )
def size_order(self, portfolio, initial_order): ticker = initial_order.ticker if initial_order.action == "EXIT": from pudb import set_trace; set_trace() invested_action = portfolio.positions[ticker].action if invested_action == "BOT": initial_order.action = "SLD" else: initial_order.action = "BOT" initial_order.quantity = abs(portfolio.positions[ticker].quantity) return initial_order else: cur_price = portfolio.price_handler.get_last_close(ticker) ''' The reason for having 'min(size_1, size_2)' is that: In the case that the cash available, after deducting 5% for volatility, is not enough for placing the order with 'size_1', we can then only place whatever amount we can afford after spending all (95%) we have. ''' size_1 = int(portfolio.cur_cash * self.max_risk // PriceParser.parse(self.max_volatility)) size_2 = int(portfolio.cur_cash * (1 - self.max_risk) // cur_price) initial_order.quantity = min(size_1, size_2) initial_order.quantity = self.initial_quantity return initial_order
def test_calculate_round_trip(self): """ After the subsequent sale, carry out two more sells/shorts and then close the position out with two additional buys/longs. The following prices have been tested against those calculated via Interactive Brokers' Trader Workstation (TWS). """ self.position.transact_shares("SLD", 100, PriceParser.parse(77.68), PriceParser.parse(1.00)) self.position.transact_shares("SLD", 50, PriceParser.parse(77.70), PriceParser.parse(1.00)) self.position.transact_shares("BOT", 100, PriceParser.parse(77.77), PriceParser.parse(1.00)) self.position.transact_shares("BOT", 150, PriceParser.parse(77.73), PriceParser.parse(1.00)) self.position.update_market_value(PriceParser.parse(77.72), PriceParser.parse(77.72)) self.assertEqual(self.position.action, "SLD") self.assertEqual(self.position.ticker, "PG") self.assertEqual(self.position.quantity, 0) self.assertEqual(self.position.buys, 250) self.assertEqual(self.position.sells, 250) self.assertEqual(self.position.net, 0) self.assertEqual(PriceParser.display(self.position.avg_bot, 3), 77.746) self.assertEqual(PriceParser.display(self.position.avg_sld, 3), 77.688) self.assertEqual(PriceParser.display(self.position.total_bot), 19436.50) self.assertEqual(PriceParser.display(self.position.total_sld), 19422.00) self.assertEqual(PriceParser.display(self.position.net_total), -14.50) self.assertEqual(PriceParser.display(self.position.total_commission), 5.00) self.assertEqual(PriceParser.display(self.position.net_incl_comm), -19.50) self.assertEqual(PriceParser.display(self.position.avg_price, 5), 77.67600) self.assertEqual(PriceParser.display(self.position.cost_basis), 0.00) self.assertEqual(PriceParser.display(self.position.market_value), 0.00) self.assertEqual(PriceParser.display(self.position.unrealised_pnl), 0.00) self.assertEqual(PriceParser.display(self.position.realised_pnl), -19.50)
def run(config, testing, tickers, filename): # Benchmark ticker benchmark = 'SP500TR' # Set up variables needed for backtest title = [ 'Moving Average Crossover Example', __file__, ','.join(tickers) + ': 100x400' ] events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_equity = PriceParser.parse(500000.00) # Use Yahoo Daily Price Handler price_handler = YahooDailyCsvBarPriceHandler( csv_dir, events_queue, tickers ) # Use the MAC Strategy strategy = MovingAverageCrossStrategy(tickers, events_queue) # Use an example Position Sizer, position_sizer = FixedPositionSizer() # Use an example Risk Manager, risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler( initial_equity, events_queue, price_handler, position_sizer, risk_manager ) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler( events_queue, price_handler, compliance ) # Use the default Statistics statistics = TearsheetStatistics( config, portfolio_handler, title, benchmark ) # Set up the backtest backtest = Backtest( price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity ) results = backtest.simulate_trading(testing=testing) statistics.save(filename) return results
def run(config, testing, tickers, filename): # Set up variables needed for backtest events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_equity = PriceParser.parse(100000.00) # Use Yahoo Daily Price Handler start_date = datetime.datetime(2009, 8, 3) end_date = datetime.datetime(2019, 8, 1) price_handler = YahooDailyCsvBarPriceHandler(csv_dir, events_queue, tickers, start_date=start_date, end_date=end_date) # Use the KalmanPairsTrading Strategy strategy = KalmanPairsTradingStrategy(tickers, events_queue) strategy = Strategies(strategy) # Use the Naive Position Sizer (suggested quantities are followed) position_sizer = NaivePositionSizer() # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler(initial_equity, events_queue, price_handler, position_sizer, risk_manager) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler(events_queue, price_handler, compliance) # Use the Tearsheet Statistics title = ["Kalman Filter Pairs Trade on TLT/IEI"] statistics = TearsheetStatistics(config, portfolio_handler, title) # Set up the backtest backtest = TradingSession(config, strategy, tickers, initial_equity, start_date, end_date, events_queue, price_handler=price_handler, portfolio_handler=portfolio_handler, execution_handler=execution_handler, position_sizer=position_sizer, risk_manager=risk_manager, statistics=statistics) results = backtest.start_trading(testing=testing) statistics.save(filename) return results
def run(config, testing, tickers, filename): # Set up variables needed for backtest title = ["Intraday AREX Machine Learning Prediction Strategy"] events_queue = queue.Queue() csv_dir = "/path/to/your/csv/data/" initial_equity = 500000.0 # Use DTN IQFeed Intraday Bar Price Handler start_date = datetime.datetime(2013, 1, 1) end_date = datetime.datetime(2014, 3, 11) price_handler = IQFeedIntradayCsvBarPriceHandler(csv_dir, events_queue, tickers, start_date=start_date) # Use the ML Intraday Prediction Strategy model_pickle_file = '/path/to/your/ml_model_lda.pkl' strategy = IntradayMachineLearningPredictionStrategy(tickers, events_queue, model_pickle_file, lags=5) # Use the Naive Position Sizer where # suggested quantities are followed position_sizer = NaivePositionSizer() # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler(PriceParser.parse(initial_equity), events_queue, price_handler, position_sizer, risk_manager) # Use the Tearsheet Statistics statistics = TearsheetStatistics( config, portfolio_handler, title=title, periods=int(252 * 6.5 * 60) # Minutely periods ) # Set up the backtest backtest = TradingSession(config, strategy, tickers, initial_equity, start_date, end_date, events_queue, title=title, portfolio_handler=portfolio_handler, position_sizer=position_sizer, price_handler=price_handler, statistics=statistics) results = backtest.start_trading(testing=testing) return results
def run(cache_name, cache_backend, expire_after, data_source, start, end, config, testing, tickers, filename, n, n_window): # Set up variables needed for backtest events_queue = queue.Queue() initial_equity = PriceParser.parse(500000.00) session = init_session(cache_name, cache_backend, expire_after) period = 86400 # Seconds in a day if len(tickers) == 1: data = web.DataReader(tickers[0], data_source, start, end, session=session) else: data = web.DataReader(tickers, data_source, start, end, session=session) # Use Generic Bar Handler with Pandas Bar Iterator price_event_iterator = PandasBarEventIterator(data, period, tickers[0]) price_handler = GenericPriceHandler(events_queue, price_event_iterator) # Use the Display Strategy strategy1 = DisplayStrategy(n=n, n_window=n_window) strategy2 = BuyAndHoldStrategy(tickers, events_queue) strategy = Strategies(strategy1, strategy2) # Use an example Position Sizer position_sizer = FixedPositionSizer() # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler( initial_equity, events_queue, price_handler, position_sizer, risk_manager ) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler( events_queue, price_handler, compliance ) # Use the default Statistics statistics = SimpleStatistics(config, portfolio_handler) # Set up the backtest backtest = Backtest( price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity ) results = backtest.simulate_trading(testing=testing) statistics.save(filename) return results
def setUp(self): """ Set up the Portfolio object that will store the collection of Position objects, supplying it with $500,000.00 USD in initial cash. """ ph = PriceHandlerMock() cash = PriceParser.parse(500000.00) self.portfolio = Portfolio(ph, cash)
def run(config, testing, tickers, filename): # Set up variables needed for backtest events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_equity = PriceParser.parse(500000.00) start_date = datetime.datetime(2006, 11, 1) end_date = datetime.datetime(2016, 10, 12) # Use Yahoo Daily Price Handler price_handler = YahooDailyCsvBarPriceHandler(csv_dir, events_queue, tickers, start_date=start_date, end_date=end_date) # Use the monthly liquidate and rebalance strategy strategy = MonthlyLiquidateRebalanceStrategy(tickers, events_queue) strategy = Strategies(strategy, DisplayStrategy()) # Use the liquidate and rebalance position sizer # with prespecified ticker weights ticker_weights = { "SPY": 0.6, "AGG": 0.4, } position_sizer = LiquidateRebalancePositionSizer(ticker_weights) # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler(initial_equity, events_queue, price_handler, position_sizer, risk_manager) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler(events_queue, price_handler, compliance) # Use the default Statistics title = ["US Equities/Bonds 60/40 ETF Strategy"] benchmark = "SPY" statistics = TearsheetStatistics(config, portfolio_handler, title, benchmark) # Set up the backtest backtest = Backtest(price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity) results = backtest.simulate_trading(testing=testing) statistics.save(filename) return results
def test_will_liquidate_positions(self): """ Ensure positions will be liquidated completely when asked. Include a long & a short. """ self.portfolio._add_position("BOT", "AAA", 100, PriceParser.parse(60.00), 0.0) self.portfolio._add_position("BOT", "BBB", -100, PriceParser.parse(60.00), 0.0) exit_a = SuggestedOrder("AAA", "EXIT", 0) exit_b = SuggestedOrder("BBB", "EXIT", 0) sized_a = self.position_sizer.size_order(self.portfolio, exit_a) sized_b = self.position_sizer.size_order(self.portfolio, exit_b) self.assertEqual(sized_a.action, "SLD") self.assertEqual(sized_b.action, "BOT") self.assertEqual(sized_a.quantity, 100) self.assertEqual(sized_a.quantity, 100)
def test_open_short_position(self): self.assertEqual(PriceParser.display(self.position.cost_basis), -7768.00) self.assertEqual(PriceParser.display(self.position.market_value), -7769.00) self.assertEqual(PriceParser.display(self.position.unrealised_pnl), -1.00) self.assertEqual(PriceParser.display(self.position.realised_pnl), -1.0) self.position.update_market_value(PriceParser.parse(77.72), PriceParser.parse(77.72)) self.assertEqual(PriceParser.display(self.position.cost_basis), -7768.00) self.assertEqual(PriceParser.display(self.position.market_value), -7772.00) self.assertEqual(PriceParser.display(self.position.unrealised_pnl), -4.00) self.assertEqual(PriceParser.display(self.position.realised_pnl), -4.0)
def run(config, testing, tickers, filename): # Set up variables needed for backtest events_queue = queue.Queue() csv_dir = "/path/to/your/csv/data/" initial_equity = PriceParser.parse(500000.00) # Use DTN IQFeed Intraday Bar Price Handler start_date = datetime.datetime(2013, 1, 1) price_handler = IQFeedIntradayCsvBarPriceHandler(csv_dir, events_queue, tickers, start_date=start_date) # Use the ML Intraday Prediction Strategy model_pickle_file = '/path/to/your/ml_model_lda.pkl' strategy = IntradayMachineLearningPredictionStrategy(tickers, events_queue, model_pickle_file, lags=5) strategy = Strategies(strategy, DisplayStrategy()) # Use the Naive Position Sizer (suggested quantities are followed) position_sizer = NaivePositionSizer() # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler(initial_equity, events_queue, price_handler, position_sizer, risk_manager) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler(events_queue, price_handler, compliance) # Use the Tearsheet Statistics statistics = TearsheetStatistics( config, portfolio_handler, title=["Intraday AREX Machine Learning Prediction Strategy"], periods=int(252 * 6.5 * 60) # Minutely periods ) # Set up the backtest backtest = Backtest(price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity) results = backtest.simulate_trading(testing=testing) statistics.save(filename) return results
def run(config, testing, tickers, filename): # Set up variables needed for backtest events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_equity = PriceParser.parse(500000.00) # Use Yahoo Daily Price Handler start_date = datetime.datetime(2013, 7, 1) end_date = datetime.datetime(2019, 6, 1) price_handler = YahooDailyCsvBarPriceHandler(csv_dir, events_queue, tickers, start_date=start_date, end_date=end_date) # Use the Cointegration Bollinger Bands trading strategy weights = np.array([1.0, -1.213]) lookback = 15 entry_z = 1.5 exit_z = 0.5 base_quantity = 10000 strategy = CointegrationBollingerBandsStrategy(tickers[1:], events_queue, lookback, weights, entry_z, exit_z, base_quantity) strategy = Strategies(strategy) # Use the Naive Position Sizer # where suggested quantities are followed position_sizer = NaivePositionSizer() # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler(initial_equity, events_queue, price_handler, position_sizer, risk_manager) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler(events_queue, price_handler, compliance) # Use the Tearsheet Statistics title = ["Aluminum Smelting Strategy - ARNC/UNG"] statistics = TearsheetStatistics(config, portfolio_handler, title, benchmark=tickers[0]) # Set up the backtest backtest = TradingSession(config, strategy, tickers[1:], initial_equity, start_date, end_date, events_queue, price_handler=price_handler, portfolio_handler=portfolio_handler, execution_handler=execution_handler, position_sizer=position_sizer, risk_manager=risk_manager, statistics=statistics, benchmark=tickers[0]) results = backtest.start_trading(testing=testing) statistics.save(filename) return results
def subscribe_ticker(self, ticker): """ Subscribes the price handler to a new ticker symbol. """ if ticker not in self.tickers: ticker_id = next(self.tickers_loop_id) ticker = next(self.tickers_loop) data = self.get_data_from_IB(ticker_id) close = PriceParser.parse(data[1]) adj_close = PriceParser.parse(data[2]) timestamp = data[0] ticker_prices = { "close": close, "adj_close": adj_close, "timestamp": timestamp } self.tickers[ticker] = ticker_prices else: print("Could not subscribe ticker %s " "as is already subscribed." % ticker)
def test_realised_unrealised_calcs(self): self.assertEqual( PriceParser.display(self.position.unrealised_pnl), -1.00 ) self.assertEqual( PriceParser.display(self.position.realised_pnl), 0.00 ) self.position.update_market_value( PriceParser.parse(75.77), PriceParser.parse(75.79) ) self.assertEqual( PriceParser.display(self.position.unrealised_pnl), 99.00 ) self.position.transact_shares( "SLD", 100, PriceParser.parse(75.78), PriceParser.parse(1.00) ) self.assertEqual( PriceParser.display(self.position.unrealised_pnl), 99.00 ) # still high self.assertEqual( PriceParser.display(self.position.realised_pnl), 98.00 ) self.position.update_market_value( PriceParser.parse(75.77), PriceParser.parse(75.79) ) self.assertEqual( PriceParser.display(self.position.unrealised_pnl), 0.00 )
def run_monthly_rebalance(config, testing, filename, benchmark, ticker_weights, title_str, start_date, end_date, equity): config = settings.from_file(config, testing) tickers = [t for t in ticker_weights.keys()] # Set up variables needed for backtest events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_equity = PriceParser.parse(equity) # Use Yahoo Daily Price Handler price_handler = YahooDailyCsvBarPriceHandler(csv_dir, events_queue, tickers, start_date=start_date, end_date=end_date) # Use the monthly liquidate and rebalance strategy strategy = MonthlyLiquidateRebalanceStrategy(tickers, events_queue) #strategy = Strategies(strategy, DisplayStrategy()) # Use the liquidate and rebalance position sizer # with prespecified ticker weights position_sizer = LiquidateRebalancePositionSizer(ticker_weights) # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler(initial_equity, events_queue, price_handler, position_sizer, risk_manager) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler(events_queue, price_handler, compliance) # Use the default Statistics title = [title_str] statistics = TearsheetStatistics(config, portfolio_handler, title, benchmark) # Set up the backtest backtest = Backtest(price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity) results = backtest.simulate_trading(testing=testing) statistics.save(filename) return results
def run(config, testing, tickers, filename, start_date, end_date): # Set up variables needed for backtest events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_equity = PriceParser.parse(500000.00) # Use Yahoo Daily Price Handler price_handler = SqliteDBBarPriceHandler( csv_dir, events_queue, tickers, start_date, end_date ) # Use the Buy and Hold Strategy strategy = CustomStrategy(tickers, events_queue) strategy = Strategies(strategy, DisplayStrategy()) # Use an example Position Sizer position_sizer = CustomPositionSizer() # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler( initial_equity, events_queue, price_handler, position_sizer, risk_manager ) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler( events_queue, price_handler, compliance ) # Use the default Statistics statistics = TearsheetStatistics( config, portfolio_handler, title="" ) # Set up the backtest backtest = Backtest( price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity ) results = backtest.simulate_trading(testing=testing) statistics.save(filename) return results
def run(config, testing, tickers, filename, n, n_window): # Set up variables needed for backtest events_queue = queue.Queue() ig_service = IGService(config.IG.USERNAME, config.IG.PASSWORD, config.IG.API_KEY, config.IG.ACCOUNT.TYPE) ig_stream_service = IGStreamService(ig_service) ig_session = ig_stream_service.create_session() accountId = ig_session[u'accounts'][0][u'accountId'] ig_stream_service.connect(accountId) initial_equity = PriceParser.parse(500000.00) # Use IG Tick Price Handler price_handler = IGTickPriceHandler(events_queue, ig_stream_service, tickers) # Use the Display Strategy strategy = DisplayStrategy(n=n, n_window=n_window) # Use an example Position Sizer position_sizer = FixedPositionSizer() # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler(initial_equity, events_queue, price_handler, position_sizer, risk_manager) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler(events_queue, price_handler, compliance) # Use the default Statistics statistics = SimpleStatistics(config, portfolio_handler) # Set up the backtest backtest = Backtest(price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity) results = backtest.simulate_trading(testing=testing) statistics.save(filename) return results
def run(config, testing, tickers, filename): # Benchmark ticker benchmark = 'SP500TR' # Set up variables needed for backtest title = [ 'Moving Average Crossover Example', __file__, ','.join(tickers) + ': 100x400' ] events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_equity = PriceParser.parse(500000.00) # Use Yahoo Daily Price Handler price_handler = YahooDailyCsvBarPriceHandler(csv_dir, events_queue, tickers) # Use the MAC Strategy strategy = MovingAverageCrossStrategy(tickers, events_queue) # Use an example Position Sizer, position_sizer = FixedPositionSizer() # Use an example Risk Manager, risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler(initial_equity, events_queue, price_handler, position_sizer, risk_manager) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler(events_queue, price_handler, compliance) # Use the default Statistics statistics = TearsheetStatistics(config, portfolio_handler, title, benchmark) # Set up the backtest backtest = Backtest(price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity) results = backtest.simulate_trading(testing=testing) statistics.save(filename) return results
def run(config, testing, tickers, filename): # Set up variables needed for backtest events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_invst = 1000000.00 initial_equity = PriceParser.parse(initial_invst) # Use Yahoo Daily Price Handler price_handler = YahooDailyCsvBarPriceHandler( csv_dir, events_queue, tickers, ) # Use the KalmanPairsTrading Strategy strategy = KalmanPairsTradingStrategy(tickers, events_queue, initial_invst) strategy = Strategies(strategy, DisplayStrategy()) # Use the Naive Position Sizer (suggested quantities are followed) position_sizer = NaivePositionSizer() # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler(initial_equity, events_queue, price_handler, position_sizer, risk_manager) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler(events_queue, price_handler, compliance) # Use the default Statistics statistics = TearsheetStatistics(config, portfolio_handler, title="") # Set up the backtest backtest = Backtest(price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity) results = backtest.simulate_trading(testing=testing) hist = results['cum_returns'] print('==:++==') print(hist.to_csv('6pair.csv', header=['date,total asset'])) statistics.save('output') return results
def run(config, testing, tickers, filename): # Set up variables needed for backtest events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_equity = PriceParser.parse(500000.00) # Use Yahoo Daily Price Handler price_handler = YahooDailyCsvBarPriceHandler( csv_dir, events_queue, tickers ) # Use the Buy and Hold Strategy strategy = BuyAndHoldStrategy(tickers, events_queue) strategy = Strategies(strategy, DisplayStrategy()) # Use an example Position Sizer position_sizer = FixedPositionSizer() # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler( initial_equity, events_queue, price_handler, position_sizer, risk_manager ) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler( events_queue, price_handler, compliance ) # Use the default Statistics statistics = SimpleStatistics(config, portfolio_handler) # Set up the backtest backtest = Backtest( price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity ) results = backtest.simulate_trading(testing=testing) statistics.save(filename) return results
def run(config, testing, tickers, filename, n, n_window): # Set up variables needed for backtest events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_equity = PriceParser.parse(500000.00) # Use Yahoo Daily Price Handler price_handler = YahooDailyCsvBarPriceHandler(csv_dir, events_queue, tickers) # Use the Display Strategy strategy = DisplayStrategy(n=n, n_window=n_window) # Use an example Position Sizer position_sizer = FixedPositionSizer() # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler(initial_equity, events_queue, price_handler, position_sizer, risk_manager) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler(events_queue, price_handler, compliance) # Use the default Statistics statistics = SimpleStatistics(config, portfolio_handler) # Set up the backtest backtest = Backtest(price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity) results = backtest.simulate_trading(testing=testing) statistics.save(filename) return results
def test_realised_unrealised_calcs(self): self.assertEqual(PriceParser.display(self.position.unrealised_pnl), -1.00) self.assertEqual(PriceParser.display(self.position.realised_pnl), 0.00) self.position.update_market_value(PriceParser.parse(75.77), PriceParser.parse(75.79)) self.assertEqual(PriceParser.display(self.position.unrealised_pnl), 99.00) self.position.transact_shares("SLD", 100, PriceParser.parse(75.78), PriceParser.parse(1.00)) self.assertEqual(PriceParser.display(self.position.unrealised_pnl), 99.00) # still high self.assertEqual(PriceParser.display(self.position.realised_pnl), 98.00) self.position.update_market_value(PriceParser.parse(75.77), PriceParser.parse(75.79)) self.assertEqual(PriceParser.display(self.position.unrealised_pnl), 0.00)
def test_display(self): parsed = PriceParser.parse(self.float) displayed = PriceParser.display(parsed) self.assertEqual(displayed, 10.12)
def run(config, testing, tickers, filename, n, n_window): # Set up variables needed for backtest events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_equity = PriceParser.parse(500000.00) d_tickers = OrderedDict() for ticker in tickers: ticker_path = os.path.join(csv_dir, "%s.csv" % ticker) df = pd.io.parsers.read_csv( ticker_path, header=0, parse_dates=True, dayfirst=True, index_col=1, names=("Ticker", "Time", "Bid", "Ask") ) del df["Ticker"] d_tickers[ticker] = df if len(tickers) == 1: ticker = tickers[0] data = d_tickers[ticker] else: data = pd.Panel.from_dict(d_tickers) data = data.transpose(2, 1, 0) print(data) print("Null:") print(data.isnull().sum()) # Use Generic Tick Handler with Pandas Tick Iterator price_event_iterator = PandasTickEventIterator(data, tickers[0]) price_handler = GenericPriceHandler(events_queue, price_event_iterator) # Use the Display Strategy and ExampleStrategy strategy1 = DisplayStrategy(n=n, n_window=n_window) strategy2 = ExampleStrategy(tickers, events_queue) strategy = Strategies(strategy1, strategy2) # strategy = ExampleStrategy(tickers, events_queue) # Use an example Position Sizer position_sizer = FixedPositionSizer() # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler( initial_equity, events_queue, price_handler, position_sizer, risk_manager ) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler( events_queue, price_handler, compliance ) # Use the default Statistics statistics = SimpleStatistics(config, portfolio_handler) # Set up the backtest backtest = Backtest( price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity ) results = backtest.simulate_trading(testing=testing) statistics.save(filename) return results
def setUp(self): self.position = Position("SLD", "PG", 100, PriceParser.parse(77.69), PriceParser.parse(1.00), PriceParser.parse(77.68), PriceParser.parse(77.70))
def setUp(self): self.position = Position( "BOT", "XOM", 100, PriceParser.parse(74.78), PriceParser.parse(1.00), PriceParser.parse(74.77), PriceParser.parse(74.79) )
def run(config, testing, tickers, filename): # Set up variables needed for backtest events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_equity = PriceParser.parse(500000.00) start_date = datetime.datetime(2006, 11, 1) end_date = datetime.datetime(2016, 10, 12) # Use Yahoo Daily Price Handler price_handler = YahooDailyCsvBarPriceHandler( csv_dir, events_queue, tickers, start_date=start_date, end_date=end_date ) # Use the monthly liquidate and rebalance strategy strategy = MonthlyLiquidateRebalanceStrategy(tickers, events_queue) strategy = Strategies(strategy, DisplayStrategy()) # Use the liquidate and rebalance position sizer # with prespecified ticker weights ticker_weights = { "SPY": 0.6, "AGG": 0.4, } position_sizer = LiquidateRebalancePositionSizer(ticker_weights) # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler( initial_equity, events_queue, price_handler, position_sizer, risk_manager ) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler( events_queue, price_handler, compliance ) # Use the default Statistics title = ["US Equities/Bonds 60/40 ETF Strategy"] benchmark = "SPY" statistics = TearsheetStatistics( config, portfolio_handler, title, benchmark ) # Set up the backtest backtest = Backtest( price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity ) results = backtest.simulate_trading(testing=testing) statistics.save(filename) return results
def get_best_bid_ask(self, ticker): prices = { "GOOG": (PriceParser.parse(705.46), PriceParser.parse(705.46)), "AMZN": (PriceParser.parse(564.14), PriceParser.parse(565.14)), } return prices[ticker]
def test_calculating_statistics(self): """ Purchase/sell multiple lots of AMZN, GOOG at various prices/commissions to ensure the arithmetic in calculating equity, drawdowns and sharpe ratio is correct. """ # Create Statistics object price_handler = PriceHandlerMock() self.portfolio = Portfolio(price_handler, PriceParser.parse(500000.00)) portfolio_handler = PortfolioHandlerMock(self.portfolio) statistics = SimpleStatistics(self.config, portfolio_handler) # Check initialization was correct self.assertEqual(PriceParser.display(statistics.equity[0]), 500000.00) self.assertEqual(PriceParser.display(statistics.drawdowns[0]), 00) self.assertEqual(statistics.equity_returns[0], 0.0) # Perform transaction and test statistics at this tick self.portfolio.transact_position( "BOT", "AMZN", 100, PriceParser.parse(566.56), PriceParser.parse(1.00) ) t = "2000-01-01 00:00:00" statistics.update(t, portfolio_handler) self.assertEqual(PriceParser.display(statistics.equity[1]), 499807.00) self.assertEqual(PriceParser.display(statistics.drawdowns[1]), 193.00) self.assertEqual(statistics.equity_returns[1], -0.0386) # Perform transaction and test statistics at this tick self.portfolio.transact_position( "BOT", "AMZN", 200, PriceParser.parse(566.395), PriceParser.parse(1.00) ) t = "2000-01-02 00:00:00" statistics.update(t, portfolio_handler) self.assertEqual(PriceParser.display(statistics.equity[2]), 499455.00) self.assertEqual(PriceParser.display(statistics.drawdowns[2]), 545.00) self.assertEqual(statistics.equity_returns[2], -0.0705) # Perform transaction and test statistics at this tick self.portfolio.transact_position( "BOT", "GOOG", 200, PriceParser.parse(707.50), PriceParser.parse(1.00) ) t = "2000-01-03 00:00:00" statistics.update(t, portfolio_handler) self.assertEqual(PriceParser.display(statistics.equity[3]), 499046.00) self.assertEqual(PriceParser.display(statistics.drawdowns[3]), 954.00) self.assertEqual(statistics.equity_returns[3], -0.0820) # Perform transaction and test statistics at this tick self.portfolio.transact_position( "SLD", "AMZN", 100, PriceParser.parse(565.83), PriceParser.parse(1.00) ) t = "2000-01-04 00:00:00" statistics.update(t, portfolio_handler) self.assertEqual(PriceParser.display(statistics.equity[4]), 499164.00) self.assertEqual(PriceParser.display(statistics.drawdowns[4]), 836.00) self.assertEqual(statistics.equity_returns[4], 0.0236) # Perform transaction and test statistics at this tick self.portfolio.transact_position( "BOT", "GOOG", 200, PriceParser.parse(705.545), PriceParser.parse(1.00) ) t = "2000-01-05 00:00:00" statistics.update(t, portfolio_handler) self.assertEqual(PriceParser.display(statistics.equity[5]), 499146.00) self.assertEqual(PriceParser.display(statistics.drawdowns[5]), 854.00) self.assertEqual(statistics.equity_returns[5], -0.0036) # Perform transaction and test statistics at this tick self.portfolio.transact_position( "SLD", "AMZN", 200, PriceParser.parse(565.59), PriceParser.parse(1.00) ) t = "2000-01-06 00:00:00" statistics.update(t, portfolio_handler) self.assertEqual(PriceParser.display(statistics.equity[6]), 499335.00) self.assertEqual(PriceParser.display(statistics.drawdowns[6]), 665.00) self.assertEqual(statistics.equity_returns[6], 0.0379) # Perform transaction and test statistics at this tick self.portfolio.transact_position( "SLD", "GOOG", 100, PriceParser.parse(707.92), PriceParser.parse(1.00) ) t = "2000-01-07 00:00:00" statistics.update(t, portfolio_handler) self.assertEqual(PriceParser.display(statistics.equity[7]), 499580.00) self.assertEqual(PriceParser.display(statistics.drawdowns[7]), 420.00) self.assertEqual(statistics.equity_returns[7], 0.0490) # Perform transaction and test statistics at this tick self.portfolio.transact_position( "SLD", "GOOG", 100, PriceParser.parse(707.90), PriceParser.parse(0.00) ) t = "2000-01-08 00:00:00" statistics.update(t, portfolio_handler) self.assertEqual(PriceParser.display(statistics.equity[8]), 499824.00) self.assertEqual(PriceParser.display(statistics.drawdowns[8]), 176.00) self.assertEqual(statistics.equity_returns[8], 0.0488) # Perform transaction and test statistics at this tick self.portfolio.transact_position( "SLD", "GOOG", 100, PriceParser.parse(707.92), PriceParser.parse(0.50) ) t = "2000-01-09 00:00:00" statistics.update(t, portfolio_handler) self.assertEqual(PriceParser.display(statistics.equity[9]), 500069.50) self.assertEqual(PriceParser.display(statistics.drawdowns[9]), 00.00) self.assertEqual(statistics.equity_returns[9], 0.0491) # Perform transaction and test statistics at this tick self.portfolio.transact_position( "SLD", "GOOG", 100, PriceParser.parse(707.78), PriceParser.parse(1.00) ) t = "2000-01-10 00:00:00" statistics.update(t, portfolio_handler) self.assertEqual(PriceParser.display(statistics.equity[10]), 500300.50) self.assertEqual(PriceParser.display(statistics.drawdowns[10]), 00.00) self.assertEqual(statistics.equity_returns[10], 0.0462) # Test that results are calculated correctly. results = statistics.get_results() self.assertEqual(results["max_drawdown"], 954.00) self.assertEqual(results["max_drawdown_pct"], 0.1908) self.assertAlmostEqual(float(results["sharpe"]), 1.7575)
def run(config, testing, tickers, filename): # Set up variables needed for backtest pickle_path = "/path/to/your/model/hmm_model_spy.pkl" events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_equity = PriceParser.parse(500000.00) # Use Yahoo Daily Price Handler start_date = datetime.datetime(2005, 1, 1) end_date = datetime.datetime(2014, 12, 31) price_handler = YahooDailyCsvBarPriceHandler(csv_dir, events_queue, tickers, start_date=start_date, end_date=end_date, calc_adj_returns=True) # Use the Moving Average Crossover trading strategy base_quantity = 10000 strategy = MovingAverageCrossStrategy(tickers, events_queue, base_quantity, short_window=10, long_window=30) strategy = Strategies(strategy, DisplayStrategy()) # Use the Naive Position Sizer # where suggested quantities are followed position_sizer = NaivePositionSizer() # Use regime detection HMM risk manager hmm_model = pickle.load(open(pickle_path, "rb")) risk_manager = RegimeHMMRiskManager(hmm_model) # Use an example Risk Manager #risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler(initial_equity, events_queue, price_handler, position_sizer, risk_manager) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler(events_queue, price_handler, compliance) # Use the Tearsheet Statistics title = ["Trend Following Regime Detection with HMM"] statistics = TearsheetStatistics(config, portfolio_handler, title, benchmark="SPY") # Set up the backtest backtest = Backtest(price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity) results = backtest.simulate_trading(testing=testing) statistics.save(filename) return results
def test_calculate_round_trip(self): """ Purchase/sell multiple lots of AMZN and GOOG at various prices/commissions to check the arithmetic and cost handling. """ # Buy 300 of AMZN over two transactions self.portfolio.transact_position( "BOT", "AMZN", 100, PriceParser.parse(566.56), PriceParser.parse(1.00) ) self.portfolio.transact_position( "BOT", "AMZN", 200, PriceParser.parse(566.395), PriceParser.parse(1.00) ) # Buy 200 GOOG over one transaction self.portfolio.transact_position( "BOT", "GOOG", 200, PriceParser.parse(707.50), PriceParser.parse(1.00) ) # Add to the AMZN position by 100 shares self.portfolio.transact_position( "SLD", "AMZN", 100, PriceParser.parse(565.83), PriceParser.parse(1.00) ) # Add to the GOOG position by 200 shares self.portfolio.transact_position( "BOT", "GOOG", 200, PriceParser.parse(705.545), PriceParser.parse(1.00) ) # Sell 200 of the AMZN shares self.portfolio.transact_position( "SLD", "AMZN", 200, PriceParser.parse(565.59), PriceParser.parse(1.00) ) # Multiple transactions bundled into one (in IB) # Sell 300 GOOG from the portfolio self.portfolio.transact_position( "SLD", "GOOG", 100, PriceParser.parse(704.92), PriceParser.parse(1.00) ) self.portfolio.transact_position( "SLD", "GOOG", 100, PriceParser.parse(704.90), PriceParser.parse(0.00) ) self.portfolio.transact_position( "SLD", "GOOG", 100, PriceParser.parse(704.92), PriceParser.parse(0.50) ) # Finally, sell the remaining GOOG 100 shares self.portfolio.transact_position( "SLD", "GOOG", 100, PriceParser.parse(704.78), PriceParser.parse(1.00) ) # The figures below are derived from Interactive Brokers # demo account using the above trades with prices provided # by their demo feed. self.assertEqual(len(self.portfolio.positions), 0) self.assertEqual(len(self.portfolio.closed_positions), 2) self.assertEqual(PriceParser.display(self.portfolio.cur_cash), 499100.50) self.assertEqual(PriceParser.display(self.portfolio.equity), 499100.50) self.assertEqual(PriceParser.display(self.portfolio.unrealised_pnl), 0.00) self.assertEqual(PriceParser.display(self.portfolio.realised_pnl), -899.50)
def setUp(self): self.position = Position("BOT", "XOM", 100, PriceParser.parse(74.78), PriceParser.parse(1.00), PriceParser.parse(74.77), PriceParser.parse(74.79))
def test_price_from_float(self): parsed = PriceParser.parse(self.float) self.assertEqual(parsed, 101234567) self.assertIsInstance(parsed, int)
def run(config, testing, tickers, filename): # Set up variables needed for backtest events_queue = queue.Queue() csv_dir = config.CSV_DATA_DIR initial_equity = PriceParser.parse(500000.00) # Use Yahoo Daily Price Handler start_date = datetime.datetime(2012, 10, 15) end_date = datetime.datetime(2016, 2, 2) price_handler = YahooDailyCsvBarPriceHandler( csv_dir, events_queue, tickers, start_date=start_date, end_date=end_date ) # Use the Sentdex Sentiment trading strategy sentiment_handler = SentdexSentimentHandler( config.CSV_DATA_DIR, "sentdex_sample.csv", events_queue, tickers=tickers, start_date=start_date, end_date=end_date ) base_quantity = 2000 sent_buy = 6 sent_sell = -1 strategy = SentdexSentimentStrategy( tickers, events_queue, sent_buy, sent_sell, base_quantity ) strategy = Strategies(strategy, DisplayStrategy()) # Use the Naive Position Sizer # where suggested quantities are followed position_sizer = NaivePositionSizer() # Use an example Risk Manager risk_manager = ExampleRiskManager() # Use the default Portfolio Handler portfolio_handler = PortfolioHandler( initial_equity, events_queue, price_handler, position_sizer, risk_manager ) # Use the ExampleCompliance component compliance = ExampleCompliance(config) # Use a simulated IB Execution Handler execution_handler = IBSimulatedExecutionHandler( events_queue, price_handler, compliance ) # Use the Tearsheet Statistics title = ["Sentiment Sentdex Strategy"] statistics = TearsheetStatistics( config, portfolio_handler, title, benchmark="SPY" ) # Set up the backtest backtest = Backtest( price_handler, strategy, portfolio_handler, execution_handler, position_sizer, risk_manager, statistics, initial_equity, sentiment_handler=sentiment_handler ) results = backtest.simulate_trading(testing=testing) statistics.save(filename) return results
def setUp(self): self.position = Position( "SLD", "PG", 100, PriceParser.parse(77.69), PriceParser.parse(1.00), PriceParser.parse(77.68), PriceParser.parse(77.70) )
def test_rounded_float(self): parsed = PriceParser.parse(self.rounded_float) # Expect 100,000,000 self.assertEqual(parsed, 100000000) self.assertIsInstance(parsed, int)
def test_price_from_int(self): parsed = PriceParser.parse(self.int) self.assertEqual(parsed, 200) self.assertIsInstance(parsed, int)