<jupyter_start><jupyter_text>WBA CVS pair  Entry Threshold:	2.00 | Exit Threshold:	0.50		 Max Duration:	45 | MA Period:	60 | MA Type:	SMA	| StdDev Period:	30 | Sharpe Ratio:	1.824<jupyter_code>import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
import math
import statsmodels
from pandas_datareader import data
import datetime
import quandl
start= datetime.datetime(2017, 1, 1)  # The start of the year for example
end= datetime.datetime(2020, 7, 30)
ticker_1 = "CVS"
ticker_2 = "WBA"
df_tickr1 = data.DataReader(name= ticker_1, data_source= "yahoo", start= start, end= end)
df_tickr2 = data.DataReader(name= ticker_2, data_source= "yahoo", start= start, end= end)
df_tickr1.tail()
df_tickr2.tail()
df_tickr1['Adj Close'].plot(label='{}'.format(ticker_1),figsize=(12,8))
df_tickr2['Adj Close'].plot(label='{}'.format(ticker_2))
plt.legend();
spread_ratio = df_tickr1['Adj Close']/df_tickr2['Adj Close']
spread_ratio.plot(label='Spread ratio',figsize=(12,8))
plt.axhline(spread_ratio.mean(),c='r')
plt.legend();
spread = df_tickr1['Adj Close'] - df_tickr2['Adj Close']
spread.plot(label='Spread',figsize=(12,8))
plt.axhline(spread.mean(),c='r')
plt.legend();
def zscore(stocks):
    return (stocks - stocks.mean()) / np.std(stocks)
zscore(spread).plot(figsize=(14,8))
plt.axhline(zscore(spread).mean(), color='black')
plt.axhline(2.0, c='r', ls='--')
plt.axhline(-2.0, c='g', ls='--')
plt.legend(['Spread z-score {} VS {}'.format(ticker_1, ticker_2), 'Mean', '+2.5 Sd', '-2.5 Sd']);
#1 day moving average of the price spread
spread_mavg1 = spread.rolling(5).mean()

# 30 day moving average of the price spread
spread_mavg30 = spread.rolling(30).mean()

# Take a rolling 30 day standard deviation
std_30 = spread.rolling(30).std()

# Compute the z score for each day
zscore_30_1 = (spread_mavg1 - spread_mavg30)/std_30



zscore_30_1.plot(figsize=(12,8),label='Rolling 30 day Z score')
plt.axhline(0, color='black')
plt.axhline(2.0, color='red', linestyle='--')
plt.axhline(-2.0, color='red',linestyle='--')
plt.legend(['Rolling 30 day z-score', 'Mean', '+2 Sd', '-2 Sd']);
#1 day moving average of the price spread
spreadratio_mavg1 = spread_ratio.rolling(1).mean()

# 30 day moving average of the price spread
spreadratio_mavg30 = spread_ratio.rolling(30).mean()

# Take a rolling 30 day standard deviation
std_30ratio = spread_ratio.rolling(30).std()

# Compute the z score for each day
zscore_30_1_ratio = (spreadratio_mavg1 - spreadratio_mavg30)/std_30ratio



zscore_30_1_ratio.plot(figsize=(12,8),label='Rolling 30 day Z score for spread ratio')
plt.axhline(0, color='black')
plt.axhline(2.50, color='red', linestyle='--')
plt.axhline(-2.50, color='red',linestyle='--')
plt.legend(['Rolling 30 day z-score spread ratio', 'Mean', '+2 Sd', '-2 Sd']);
from statsmodels.tsa.stattools import coint
y0 = df_tickr1['Adj Close']
y1 = df_tickr2['Adj Close']
t_stat_summary = statsmodels.tsa.stattools.coint(y0, y1, trend='c', method='aeg', maxlag=None, autolag='aic', return_results=True) 
print('----------------------------------------')
print('T-stat for the pair {} VS {}:'.format(ticker_1,ticker_2), t_stat_summary[0])
print('Alpha value for the T-stat:  {}'.format(t_stat_summary[1]))
print('--------------------------------------')
print('T-stat 99%:  {}'.format(t_stat_summary[2][0]))
print('T-stat 95%:  {}'.format(t_stat_summary[2][1]))
print('T-stat 90%:  {}'.format(t_stat_summary[2][2]))
from statsmodels.tsa.stattools import adfuller
def adf_check(time_series):
    """
    Pass in a time series, returns ADF report
    """
    result = adfuller(time_series)
    print('\n-----------Augmented Dickey-Fuller Test: ----------\n')
    labels = ['ADF Test Statistic','p-value','#Lags Used','Number of Observations Used']

    for value,label in zip(result,labels):
        print(label+' : '+str(value) )
    
    if result[1] <= 0.05:
        print("\nstrong evidence against the null hypothesis, reject the null hypothesis. Data has no unit root and is mean-reverting\n")
    else:
        print("\nWeak evidence against null hypothesis, time series has a unit root, indicating it is non-mean-reverting\n ")
    
    print("Dickey Fuller Confidence Intervals:  ", adfuller(spread_ratio)[4])

adf_check(spread_ratio)
np.corrcoef(df_tickr1['Adj Close'],df_tickr2['Adj Close'])
np.cov(df_tickr1['Adj Close'],df_tickr2['Adj Close'])<jupyter_output><empty_output><jupyter_text>Differencing method of spread; GARCH volatility method of spread and final use log returns minus average log returns of spread over GARCH - to be done next<jupyter_code>zscore_30_1_ratio[-20:]
spread_ratio[-20:]<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17754401030485187, 'fraction_numerical': 0.040145985401459854, 'mean_word_length': 4.950191570881226, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 9, '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': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '295355', 'license': 'MIT', 'n_tokens_mistral': 1806, 'n_tokens_neox': 1661, 'n_words': 410, 'path': 'Quant trading test models - #active WBA vs CVS Pairs trade.ipynb', 'repo_name': 'gsamarakoon/Quant-trading', 'size': '4658'}