<jupyter_start><jupyter_text>Backtesting an Active Strategy<jupyter_code>import pandas_datareader as pdr
import datetime as dt
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib notebook
tickers = ['SPY', 'TLT']

start = dt.datetime(2007, 1, 1)
end = dt.datetime(2021, 1, 1)

data = pdr.get_data_yahoo(tickers, start, end)

data = data['Adj Close']
ma = data['SPY'].rolling(200).mean()

signal_line = data['SPY'] - ma
signal_line = signal_line.apply(np.sign)
log_return = np.log(data/data.shift())
rtn = signal_line.clip(lower=0).shift(1)*log_return['SPY']
rtn = rtn - (signal_line.clip(upper=0).shift())*log_return['TLT']
rtn.loc['2008':].cumsum().apply(np.exp)
log_return['SPY'].loc['2008':].cumsum().apply(np.exp)
fig, ax = plt.subplots()

rtn.loc['2008':].cumsum().apply(np.exp).plot(ax=ax, label='Backtest')
log_return['SPY'].loc['2008':].cumsum().apply(np.exp).plot(ax=ax)
ax.legend()<jupyter_output><empty_output><jupyter_text>Project- Backtesting different periods and visualize results  Step 1- Make a function which calucates the CAGR, maximum drawdown, and volatility<jupyter_code>def calculate(log_return, start, end):
    years = int(end) - int(start) + 1
    
    data = log_return.loc[start:end]
    
    cagr = np.exp(data.sum())**(1/years) - 1
    
    norm = data.cumsum().apply(np.exp)
    
    rolling_max = norm.rolling(252).max()
    daily_drawdown = norm/rolling_max - 1
    drawdown = daily_drawdown.cummin().iloc[-1]

    volatility = data.std()*(252**.5)
    
    return cagr, drawdown, volatility<jupyter_output><empty_output><jupyter_text>Step 2- Use our function on SPY from 2008 to end 2017- And on our strategy in the same period<jupyter_code>calculate(log_return['SPY'], '2008', '2017')
calculate(rtn, '2008', '2017')<jupyter_output><empty_output><jupyter_text>Step 3- Create a visual reprentation of the result<jupyter_code>def visualize(backtest, spy, start, end):
    def x_titles(spy_val, bt_val):
        spy_str = str(round(spy_val*100, 1))
        bt_str = str(round(bt_val*100, 1))
        return ['SPY\n' + spy_str + '%', 'Backtest\n' + bt_str + '%']
        
    spy_cagr, spy_drawdown, spy_vol = calculate(spy, start, end)
    bt_cagr, bt_drawdown, bt_vol = calculate(backtest, start, end)

    fig, ax = plt.subplots(2, 2)
    
    spy.loc[start:end].cumsum().apply(np.exp).plot(ax=ax[0, 0])
    backtest.loc[start:end].cumsum().apply(np.exp).plot(ax=ax[0, 0], label='Backtest', c='c')
    ax[0, 0].legend()
    
    x = x_titles(spy_cagr, bt_cagr)
    ax[0, 1].bar(x, [spy_cagr, bt_cagr], color=['b', 'c'])
    ax[0, 1].set_title("CAGR")
    
    x = x_titles(spy_drawdown, bt_drawdown)
    ax[1, 0].bar(x, [spy_drawdown, bt_drawdown], color=['b', 'c'])
    ax[1, 0].set_title("Drawdown")

    x = x_titles(spy_vol, bt_vol)
    ax[1, 1].bar(x, [spy_vol, bt_vol], color=['b', 'c'])
    ax[1, 1].set_title("Volatility")

    plt.tight_layout()
visualize(rtn, log_return['SPY'], '2008', '2017')
visualize(rtn, log_return['SPY'], '2011', '2020')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17585301837270342, 'fraction_numerical': 0.038385826771653545, 'mean_word_length': 4.688432835820896, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '647823', 'license': 'MIT', 'n_tokens_mistral': 1311, 'n_tokens_neox': 1208, 'n_words': 228, 'path': 'Python For Financial Analysis/08 - Backtesting an Active Strategy.ipynb', 'repo_name': 'shreejitverma/Data-Scientist', 'size': '3048'}