def _create_data_handler(self, data_handler): """ Creates a DataHandler instance to load the asset pricing data used within the backtest. TODO: Currently defaults to CSV data sources of daily bar data in the YahooFinance format. Parameters ---------- `BacktestDataHandler` or None The (potential) backtesting data handler instance. Returns ------- `BacktestDataHandler` The backtesting data handler instance. """ if data_handler is not None: return data_handler try: os.environ['QSTRADER_CSV_DATA_DIR'] except KeyError: if settings.PRINT_EVENTS: print( "The QSTRADER_CSV_DATA_DIR environment variable has not been set. " "This means that QSTrader will fall back to finding data within the " "current directory where the backtest has been executed. However " "it is strongly recommended that a QSTRADER_CSV_DATA_DIR environment " "variable is set for future backtests." ) csv_dir = '.' else: csv_dir = os.environ.get('QSTRADER_CSV_DATA_DIR') # TODO: Only equities are supported by QSTrader for now. data_source = CSVDailyBarDataSource(csv_dir, Equity) data_handler = BacktestDataHandler( self.universe, data_sources=[data_source] ) return data_handler
from qstrader.trading.backtest import BacktestTradingSession if __name__ == "__main__": start_dt = pd.Timestamp('2003-09-30 14:30:00', tz=pytz.UTC) end_dt = pd.Timestamp('2019-12-31 23:59:00', tz=pytz.UTC) # Construct the symbols and assets necessary for the backtest strategy_symbols = ['SPY', 'AGG'] strategy_assets = ['EQ:%s' % symbol for symbol in strategy_symbols] strategy_universe = StaticUniverse(strategy_assets) # To avoid loading all CSV files in the directory, set the # data source to load only those provided symbols csv_dir = os.environ.get('QSTRADER_CSV_DATA_DIR') data_source = CSVDailyBarDataSource(csv_dir, Equity, csv_symbols=strategy_symbols) data_handler = BacktestDataHandler(strategy_universe, data_sources=[data_source]) # Construct an Alpha Model that simply provides # static allocations to a universe of assets # In this case 60% SPY ETF, 40% AGG ETF, # rebalanced at the end of each month strategy_alpha_model = FixedSignalsAlphaModel({'EQ:SPY': 0.6, 'EQ:AGG': 0.4}) strategy_backtest = BacktestTradingSession( start_dt, end_dt, strategy_universe, strategy_alpha_model, rebalance='end_of_month', cash_buffer_percentage=0.01, data_handler=data_handler
def cli(start_date, end_date, allocations, strat_title, strat_id, tearsheet): csv_dir = os.environ.get('QSTRADER_CSV_DATA_DIR', '.') start_dt = pd.Timestamp('%s 00:00:00' % start_date, tz=pytz.UTC) if end_date is None: # Use yesterday's date yesterday = (datetime.now() - timedelta(1)).strftime('%Y-%m-%d') end_dt = pd.Timestamp('%s 23:59:00' % yesterday, tz=pytz.UTC) else: end_dt = pd.Timestamp('%s 23:59:00' % end_date, tz=pytz.UTC) alloc_dict = obtain_allocations(allocations) # Assets and Data Handling strategy_assets = list(alloc_dict.keys()) strategy_symbols = [ symbol.replace('EQ:', '') for symbol in strategy_assets ] strategy_universe = StaticUniverse(strategy_assets) strategy_data_source = CSVDailyBarDataSource(csv_dir, Equity, csv_symbols=strategy_symbols) strategy_data_handler = BacktestDataHandler( strategy_universe, data_sources=[strategy_data_source]) strategy_assets = alloc_dict.keys() strategy_alpha_model = FixedSignalsAlphaModel(alloc_dict) strategy_backtest = BacktestTradingSession( start_dt, end_dt, strategy_universe, strategy_alpha_model, rebalance='end_of_month', account_name=strat_title, portfolio_id='STATIC001', portfolio_name=strat_title, long_only=True, cash_buffer_percentage=0.01, data_handler=strategy_data_handler) strategy_backtest.run() # Benchmark: 60/40 US Equities/Bonds benchmark_symbols = ['SPY', 'AGG'] benchmark_assets = ['EQ:SPY', 'EQ:AGG'] benchmark_universe = StaticUniverse(benchmark_assets) benchmark_data_source = CSVDailyBarDataSource( csv_dir, Equity, csv_symbols=benchmark_symbols) benchmark_data_handler = BacktestDataHandler( benchmark_universe, data_sources=[benchmark_data_source]) benchmark_signal_weights = {'EQ:SPY': 0.6, 'EQ:AGG': 0.4} benchmark_title = '60/40 US Equities/Bonds' benchmark_alpha_model = FixedSignalsAlphaModel(benchmark_signal_weights) benchmark_backtest = BacktestTradingSession( start_dt, end_dt, benchmark_universe, benchmark_alpha_model, rebalance='end_of_month', account_name='60/40 US Equities/Bonds', portfolio_id='6040EQBD', portfolio_name=benchmark_title, long_only=True, cash_buffer_percentage=0.01, data_handler=benchmark_data_handler) benchmark_backtest.run() output_filename = ('%s_monthly.json' % strat_id).replace('-', '_') stats = JSONStatistics( equity_curve=strategy_backtest.get_equity_curve(), target_allocations=strategy_backtest.get_target_allocations(), strategy_id=strat_id, strategy_name=strat_title, benchmark_curve=benchmark_backtest.get_equity_curve(), benchmark_id='6040-us-equitiesbonds', benchmark_name=benchmark_title, output_filename=output_filename) stats.to_file() if tearsheet: tearsheet = TearsheetStatistics( strategy_equity=strategy_backtest.get_equity_curve(), benchmark_equity=benchmark_backtest.get_equity_curve(), title=strat_title) tearsheet.plot_results()