Skip to content

Commit

Permalink
Fixed Buy & Hold and 60/40 Monthly Rebalance examples to work with ne…
Browse files Browse the repository at this point in the history
…w API.
  • Loading branch information
mhallsmoore committed Mar 10, 2020
1 parent 78a90c5 commit 117640e
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 32 deletions.
46 changes: 36 additions & 10 deletions examples/buy_and_hold.py
@@ -1,24 +1,50 @@
import os

import pandas as pd
import pytz

from qstrader.alpha_model.fixed_signals import FixedSignalsAlphaModel
from qstrader.asset.equity import Equity
from qstrader.asset.universe.static import StaticUniverse
from qstrader.data.backtest_data_handler import BacktestDataHandler
from qstrader.data.daily_bar_csv import CSVDailyBarDataSource
from qstrader.statistics.tearsheet import TearsheetStatistics
from qstrader.trading.backtest import BacktestTradingSession


if __name__ == "__main__":
assets = ['EQ:GLD']
signal_weights = {'EQ:GLD': 1.0}
alpha_model = FixedSignalsAlphaModel(signal_weights)
start_dt = pd.Timestamp('2004-11-19 14:30:00', tz=pytz.UTC)
end_dt = pd.Timestamp('2019-12-31 23:59:00', tz=pytz.UTC)

# Construct the symbol and asset necessary for the backtest
strategy_symbols = ['GLD']
strategy_assets = ['EQ:GLD']
strategy_universe = StaticUniverse(strategy_assets)

start_dt = pd.Timestamp('2004-11-19 00:00:00', tz=pytz.UTC)
end_dt = pd.Timestamp('2019-10-16 23:59:00', tz=pytz.UTC)
# 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])

backtest = BacktestTradingSession(
# Construct an Alpha Model that simply provides a fixed
# signal for the single GLD ETF at 100% allocation
# with a backtest that does not rebalance
strategy_alpha_model = FixedSignalsAlphaModel({'EQ:GLD': 1.0})
strategy_backtest = BacktestTradingSession(
start_dt,
end_dt,
assets,
alpha_model,
strategy_universe,
strategy_alpha_model,
rebalance='buy_and_hold',
cash_buffer_percentage=0.05
cash_buffer_percentage=0.01,
data_handler=data_handler
)
strategy_backtest.run()

# Performance Output
tearsheet = TearsheetStatistics(
strategy_equity=strategy_backtest.get_equity_curve(),
title='Buy & Hold GLD ETF'
)
backtest.run()
tearsheet.plot_results()
60 changes: 38 additions & 22 deletions examples/sixty_forty.py
@@ -1,54 +1,70 @@
import os

import pandas as pd
import pytz

from qstrader.alpha_model.fixed_signals import FixedSignalsAlphaModel
from qstrader.asset.equity import Equity
from qstrader.asset.universe.static import StaticUniverse
from qstrader.data.backtest_data_handler import BacktestDataHandler
from qstrader.data.daily_bar_csv import CSVDailyBarDataSource
from qstrader.statistics.tearsheet import TearsheetStatistics
from qstrader.trading.backtest import BacktestTradingSession


if __name__ == "__main__":
start_dt = pd.Timestamp('2004-01-01 00:00:00', tz=pytz.UTC)
end_dt = pd.Timestamp('2018-12-31 23:59:00', tz=pytz.UTC)

# Strategic Asset Allocation - Fixed Weight 60/40 SPY/AGG
strategy_assets = ['EQ:SPY', 'EQ:AGG']
strategy_signal_weights = {'EQ:SPY': 0.6, 'EQ:AGG': 0.4}
strategy_title = 'Strategic Asset Allocation - 60/40 US Equities/Bonds (SPY/AGG)'
strategy_alpha_model = FixedSignalsAlphaModel(strategy_signal_weights)
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_assets,
strategy_universe,
strategy_alpha_model,
rebalance='end_of_month',
account_name='Strategic Asset Allocation Account',
portfolio_id='SAA001',
portfolio_name=strategy_title,
cash_buffer_percentage=0.05
cash_buffer_percentage=0.01,
data_handler=data_handler
)
strategy_backtest.run()

# Benchmark - Buy & Hold SPY
# Construct benchmark assets (buy & hold SPY)
benchmark_assets = ['EQ:SPY']
benchmark_signal_weights = {'EQ:SPY': 1.0}
benchmark_alpha_model = FixedSignalsAlphaModel(benchmark_signal_weights)
benchmark_universe = StaticUniverse(benchmark_assets)

# Construct a benchmark Alpha Model that provides
# 100% static allocation to the SPY ETF, with no rebalance
benchmark_alpha_model = FixedSignalsAlphaModel({'EQ:SPY': 1.0})
benchmark_backtest = BacktestTradingSession(
start_dt,
end_dt,
benchmark_assets,
benchmark_universe,
benchmark_alpha_model,
account_name='Benchmark Account',
portfolio_id='SPY001',
portfolio_name='Benchmark - Buy & Hold S&P500 (SPY)',
rebalance='buy_and_hold',
cash_buffer_percentage=0.05
cash_buffer_percentage=0.01,
data_handler=data_handler
)
benchmark_backtest.run()

# Performance Output
tearsheet = TearsheetStatistics(
strategy_equity=strategy_backtest.get_equity_curve(),
benchmark_equity=benchmark_backtest.get_equity_curve(),
title=strategy_title
title='60/40 US Equities/Bonds'
)
tearsheet.plot_results()

0 comments on commit 117640e

Please sign in to comment.