<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Exercises
Step1:  Exercise 1
Step2:  b. Checking for Normality
As an extra all-purpose check, and one that is often done on series, check whether the above series is normally distributed using the Jarque-Bera test.
Step3:  c. Constructing Examples I
Create/provide a series that is stationary and different from any covered so far in the exercise or the lecture.
Step4:  d. Constructing Examples II
Create/provide a series that is non-stationary and different from any covered so far in the exercise or the lecture.
Step5:  Exercise 2
Step6:  Exercise 3
<ASSISTANT_TASK:>
Python Code:
# Useful Functions
def check_for_stationarity(X, cutoff=0.01):
    # H_0 in adfuller is unit root exists (non-stationary)
    # We must observe significant p-value to convince ourselves that the series is stationary
    pvalue = adfuller(X)[1]
    if pvalue < cutoff:
        print 'p-value = ' + str(pvalue) + ' The series is likely stationary.'
        return True
    else:
        print 'p-value = ' + str(pvalue) + ' The series is likely non-stationary.'
        return False
    
def generate_datapoint(params):
    mu = params[0]
    sigma = params[1]
    return np.random.normal(mu, sigma)
# Useful Libraries
import numpy as np
import pandas as pd
import statsmodels
import statsmodels.api as sm
from statsmodels.tsa.stattools import coint, adfuller
import matplotlib.pyplot as plt
Explanation: Exercises: Integration, Cointegration, and Stationarity - Answer Key
by Delaney Granizo-Mackenzie and Maxwell Margenot
Lecture Link :
https://www.quantopian.com/lectures/integration-cointegration-and-stationarity
IMPORTANT NOTE:
This lecture corresponds to the Integration, Cointegration, and Stationarity lecture, which is part of the Quantopian lecture series. This homework expects you to rely heavily on the code presented in the corresponding lecture. Please copy and paste regularly from that lecture when starting to work on the problems, as trying to do them from scratch will likely be too difficult.
Part of the Quantopian Lecture Series:
www.quantopian.com/lectures
github.com/quantopian/research_public
Helper Functions
End of explanation
QQQ = get_pricing("QQQ", start_date='2014-1-1', end_date='2015-1-1', fields='price')
QQQ.name = QQQ.name.symbol
check_for_stationarity(QQQ)
Explanation: Exercise 1: Stationarity Testing
a. Checking For Stationarity
Check whether the following series is stationary using the tests from the lecture.
End of explanation
from statsmodels.stats.stattools import jarque_bera
jarque_bera(QQQ)
Explanation: b. Checking for Normality
As an extra all-purpose check, and one that is often done on series, check whether the above series is normally distributed using the Jarque-Bera test.
End of explanation
X = np.random.normal(0, 1, 100)
check_for_stationarity(X)
Explanation: c. Constructing Examples I
Create/provide a series that is stationary and different from any covered so far in the exercise or the lecture.
End of explanation
# Set the number of datapoints
T = 100
B = pd.Series(index=range(T))
B.name = 'B'
for t in range(T):
    # Now the parameters are dependent on time
    # Specifically, the mean of the series changes over time
    params = (np.power(t, 2), 1)
    B[t] = generate_datapoint(params)
plt.plot(B);
check_for_stationarity(B)
Explanation: d. Constructing Examples II
Create/provide a series that is non-stationary and different from any covered so far in the exercise or the lecture.
End of explanation
QQQ = get_pricing("QQQ", start_date='2014-1-1', end_date='2015-1-1', fields='price')
QQQ.name = QQQ.name.symbol
# Write code to estimate the order of integration of QQQ.
# Feel free to sample from the code provided in the lecture.
QQQ = QQQ.diff()[1:]
QQQ.name = QQQ.name + ' Additive Returns'
check_for_stationarity(QQQ)
plt.plot(QQQ.index, QQQ.values)
plt.ylabel('Additive Returns')
plt.legend([QQQ.name]);
Explanation: Exercise 2: Estimate Order of Integration
Use the techniques laid out in the lecture notebook to estimate the order of integration for the following timeseries.
End of explanation
T = 500
X1 = pd.Series(index=range(T))
X1.name = 'X1'
for t in range(T):
    # Now the parameters are dependent on time
    # Specifically, the mean of the series changes over time
    params = (t * 0.1, 1)
    X1[t] = generate_datapoint(params)
X2 = np.power(X1, 2) + X1
X3 = np.power(X1, 3) + X1
X4 = np.sin(X1) + X1
# We now have 4 time series, X1, X2, X3, X4
# Determine a linear combination of the 4 that is stationary over the 
# time period shown using the techniques in the lecture.
X1 = sm.add_constant(X1)
results = sm.OLS(X4, X1).fit()
# Get rid of the constant column
X1 = X1['X1']
results.params
plt.plot(X4-0.99 * X1);
check_for_stationarity(X4 - 0.99*X1)
Explanation: Exercise 3: Find a Stationary Linear (Cointegrated) Combination
Use the techniques laid out in the lecture notebook to find a linear combination of the following timeseries that is stationary.
End of explanation
<END_TASK>