一、Strategy:
hold S&P 500 ETF when volatility is low, when vol is high be in cash.
二、知识点
1.从雅虎获取历史行情,并转化成df。
2.plot展示(原来的代码没有显示Figure,后来加了plt.show()才显示。
三、代码:
import pandas as pd import matplotlib.pyplot as plt def load_equities_web(symbol, date_from): import pandas_datareader.data as web raw_data = web.DataReader(symbol, 'yahoo', pd.to_datetime(date_from), pd.datetime.now()) data = raw_data.stack(dropna=False)['Adj Close'].to_frame().reset_index().rename(columns = {'Symbols':'symbol', 'Date':'date', 'Adj Close':'value'}).sort_values(by = ['symbol', 'date']) return pd.pivot_table(data, columns = 'symbol', index = 'date', values ='value') prices = load_equities_web(['SPY', '^GSPC', '^VIX'], date_from = '2000-01-01') def backtest_strategy(prices, symbol_trade, symbol_volatility, volatility_threshold, capital, symbol_benchmark): df_init = (prices[symbol_trade]*0).to_frame().assign(cash = 0) df_update = (prices[symbol_trade]*0).to_frame().assign(cash = 0) df_end = (prices[symbol_trade]*0).to_frame().assign(cash = 0) df_init.iloc[0, df_init.columns.get_loc('cash')] = capital df_end.iloc[0, df_end.columns.get_loc('cash')] = capital calendar = pd.Series(prices.index).iloc[1:] for date in calendar: prev_date = df_init.index[df_init.index<date][-1] df_init.loc[date, :] = df_end.loc[prev_date, :] port_value = df_init.loc[date, symbol_trade] * prices.loc[date, symbol_trade] + df_init.loc[date, 'cash'] if prices.loc[date, symbol_volatility] > volatility_threshold: # volatility is high -> be fully in cash df_end.loc[date, symbol_trade] = 0 df_end.loc[date, 'cash'] = port_value else: # volatility is low -> be in market position df_end.loc[date, symbol_trade] = port_value/prices.loc[date, symbol_trade] df_end.loc[date, 'cash'] = 0 df_update.loc[date] = df_end.loc[date] - df_init.loc[date] portval = (df_end*prices.assign(cash = 1)[[symbol_trade, 'cash']]).sum(axis = 1).to_frame().rename(columns = {0:'strategy'}) portval['benchmark'] = prices[symbol_benchmark] portval = portval/portval.iloc[0].values return portval res = backtest_strategy(prices = prices, symbol_trade = 'SPY', symbol_volatility = '^VIX', volatility_threshold = 20, capital = 10000, symbol_benchmark = '^GSPC') print(res) res.plot() plt.show()
四、成果展示