Time Analysis - 1
Time Analysis - 1
1 Data Cleaning
[2]: datasets = ['AAPL']
[*********************100%%**********************] 1 of 1 completed
[5]: stock_data
1
2023-09-18 176.479996 179.380005 176.169998 177.970001 177.970001
2023-09-19 177.520004 179.630005 177.130005 179.070007 179.070007
2023-09-20 179.259995 179.699997 175.399994 175.490005 175.490005
2023-09-21 174.550003 176.300003 173.860001 173.929993 173.929993
2023-09-22 174.669998 177.078995 174.054993 174.789993 174.789993
Volume
Date
2019-01-02 148158800
2019-01-03 365248800
2019-01-04 234428400
2019-01-07 219111200
2019-01-08 164101200
… …
2023-09-18 67257600
2023-09-19 51826900
2023-09-20 58436200
2023-09-21 63047900
2023-09-22 56682928
stock_data = stock_data.drop_duplicates()
[13]: stock_data
Volume
Date
2019-01-02 148158800
2019-01-03 365248800
2
2019-01-04 234428400
2019-01-07 219111200
2019-01-08 164101200
… …
2023-09-18 67257600
2023-09-19 51826900
2023-09-20 58436200
2023-09-21 63047900
2023-09-22 55110610
[15]: stock_data
Volume
Date
2019-01-02 148158800
2019-01-03 365248800
2019-01-04 234428400
2019-01-07 219111200
2019-01-08 164101200
… …
2023-09-18 67257600
2023-09-19 51826900
2023-09-20 58436200
2023-09-21 63047900
2023-09-22 55110610
3
[16]: #calculate Daily Returns
stock_data['Daily Return'] = stock_data['Close'].pct_change() * 100
[18]: stock_data
[21]: print(stock_data.head())
4
Date
2019-01-03 35.994999 36.430000 35.500000 35.547501 34.163818 365248800
2019-01-04 36.132500 37.137501 35.950001 37.064999 35.622253 234428400
2019-01-07 37.174999 37.207500 36.474998 36.982498 35.542973 219111200
2019-01-08 37.389999 37.955002 37.130001 37.687500 36.220531 164101200
2019-01-09 37.822498 38.632500 37.407501 38.327499 36.835617 180396400
5
[24]: fig ,ax = plt.subplots(figsize=(12, 4))
stock_data['Daily Return'].plot(ax=ax);
plt.subplot(411)
plt.plot(stock_prices, label='Original Stock Prices')
plt.legend()
plt.subplot(412)
plt.plot(result.trend, label='Trend Component')
plt.legend()
6
plt.subplot(413)
plt.plot(result.seasonal, label='Seasonal Component')
plt.legend()
plt.subplot(414)
plt.plot(result.resid, label='Residual component')
plt.legend()
plt.show()
plt.tight_layout()
3 Volatility Garch
[23]: !pip install arch
Collecting arch
Downloading
arch-6.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (916 kB)
�������������������������������������� 916.4/916.4 kB
25.1 MB/s eta 0:00:00
Requirement already satisfied: numpy>=1.19 in
/usr/local/lib/python3.10/dist-packages (from arch) (1.23.5)
Requirement already satisfied: scipy>=1.5 in /usr/local/lib/python3.10/dist-
packages (from arch) (1.11.2)
Requirement already satisfied: pandas>=1.1 in /usr/local/lib/python3.10/dist-
7
packages (from arch) (1.5.3)
Requirement already satisfied: statsmodels>=0.12 in
/usr/local/lib/python3.10/dist-packages (from arch) (0.14.0)
Requirement already satisfied: python-dateutil>=2.8.1 in
/usr/local/lib/python3.10/dist-packages (from pandas>=1.1->arch) (2.8.2)
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-
packages (from pandas>=1.1->arch) (2023.3.post1)
Requirement already satisfied: patsy>=0.5.2 in /usr/local/lib/python3.10/dist-
packages (from statsmodels>=0.12->arch) (0.5.3)
Requirement already satisfied: packaging>=21.3 in
/usr/local/lib/python3.10/dist-packages (from statsmodels>=0.12->arch) (23.1)
Requirement already satisfied: six in /usr/local/lib/python3.10/dist-packages
(from patsy>=0.5.2->statsmodels>=0.12->arch) (1.16.0)
Installing collected packages: arch
Successfully installed arch-6.1.0
8
#Plot Conditional Volatility
plt.subplot(2, 1, 2)
plt.plot(conditional_volatility, label='Conditional Volatility (GARCH)',␣
↪color='green')
plt.tight_layout()
plt.show()
4 Statistical Descriptions
[28]: mean_return = stock_data['Daily Return'].mean()
median_return = stock_data['Daily Return'].median()
std_deviation = stock_data['Daily Return'].std()
skewness = stock_data['Daily Return'].skew()
kurtosis = stock_data['Daily Return'].kurtosis()
[29]: mean_return
[29]: 0.14673047261990926
[30]: plt.subplot(2, 1, 2)
plt.axhline(mean_return, color='green', linestyle='--', label=f'Mean Return␣
↪({mean_return:.4f})')
9
plt.tight_layout()
plt.show()
5 Correlations / cointegrations
[31]: correlation_matrix = stock_data.corr()
[32]: correlation_matrix
10
Cumulative Return -0.428742 -0.015809 -0.013254 1.000000
[37]: cointegration_test
[37]: (-8.10242004427434,
1.6696221220460294e-11,
array([-4.01048603, -3.39854434, -3.08756793]))
plt.title('Price Series')
plt.xlabel('time')
plt.ylabel('Price')
plt.legend()
plt.grid(True)
plt.show()
11
6 Econometrics Model
[63]: import statsmodels.api as sm
[*********************100%%**********************] 1 of 1 completed
[66]: market_returns
Volume
Date
2019-01-02 3733160000
2019-01-03 3858830000
2019-01-04 4234140000
2019-01-07 4133120000
2019-01-08 4120060000
… …
2023-09-15 6932230000
2023-09-18 3161230000
2023-09-19 3614880000
2023-09-20 3308450000
2023-09-21 3662340000
12
[68]: X = sm.add_constant(market_data)
/usr/local/lib/python3.10/dist-packages/statsmodels/tsa/base/tsa_model.py:473:
ValueWarning: A date index has been provided, but it has no associated frequency
information and so will be ignored when e.g. forecasting.
self._init_dates(dates, freq)
/usr/local/lib/python3.10/dist-packages/statsmodels/tsa/base/tsa_model.py:473:
ValueWarning: A date index has been provided, but it has no associated frequency
information and so will be ignored when e.g. forecasting.
self._init_dates(dates, freq)
13
/usr/local/lib/python3.10/dist-packages/statsmodels/tsa/base/tsa_model.py:473:
ValueWarning: A date index has been provided, but it has no associated frequency
information and so will be ignored when e.g. forecasting.
self._init_dates(dates, freq)
[81]: plt.figure(figsize=(12,6))
plt.plot(prices, label='Original Price', color='blue')
[82]: lags = 5
14
[101]: forecast = model.forecast(steps=5)
plt.plot(range(len(prices), len(prices) + 5), forecast, label='Forecasts',␣
↪color='orange')
plt.xlabel('Time')
plt.ylabel('Stock Price')
plt.title('Model ARIMA')
plt.xticks(rotation = 25)
plt.legend()
plt.show()
/usr/local/lib/python3.10/dist-packages/statsmodels/tsa/base/tsa_model.py:836:
ValueWarning: No supported index is available. Prediction results will be given
with an integer index beginning at `start`.
return get_prediction_index(
/usr/local/lib/python3.10/dist-packages/statsmodels/tsa/base/tsa_model.py:836:
FutureWarning: No supported index is available. In the next version, calling
this method in a model without a supported index will result in an exception.
return get_prediction_index(
15
7 Strategies Based on Simple Moving Averages
[11]: data = pd.DataFrame(stock_data)
[14]: data
16
2023-09-22 174.669998 177.078995 174.054993 174.789993 174.789993
Volume
Date
2019-01-02 148158800
2019-01-03 365248800
2019-01-04 234428400
2019-01-07 219111200
2019-01-08 164101200
… …
2023-09-18 67257600
2023-09-19 51826900
2023-09-20 58436200
2023-09-21 63047900
2023-09-22 56682928
[16]: stock_data.tail()
17
[20]: stock_data['Position'] = np.where(stock_data['SMA1']> stock_data['SMA2'], 1, -1)
[21]: stock_data.dropna(inplace=True)
18
[25]: stock_data['Return'] = np.log(stock_data['Adj Close'] / stock_data['Adj Close'].
↪shift(1))
19
[33]: stock_data[['Strategy', 'Return']].mean() * 252
20
[38]: stock_data['cummax'] = stock_data['cumret'].cummax()
[41]: drawdown.max()
[41]: 1.1597999478192935
8 Predictions Stock
[47]: X= stock_data['Close']
[49]: y = X + np.random.standard_normal(len(X))
[51]: reg
21
plt.plot(X, np.polyval(reg, X), 'r', lw=2.5, label='Linear Regression')
plt.legend(loc=0)
[53]: lags = 5
[54]: cols = []
for lag in range(1, lags + 1):
col =f'lag_{lag}'
stock_data[col] = stock_data['Adj Close'].shift(lag)
cols.append(col)
stock_data.dropna(inplace=True)
[56]: reg
22
[59]: stock_data[['Predictions', 'Adj Close']].loc['2023-1-1':].plot(figsize=(10, 6));
23