0% found this document useful (0 votes)
24 views13 pages

PPP Models - GARCH & NARNN - Ipynb - Colaboratory

Uploaded by

sethantanah
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
24 views13 pages

PPP Models - GARCH & NARNN - Ipynb - Colaboratory

Uploaded by

sethantanah
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

1/3/24, 6:10 PM PPP Models - GARCH & NARNN.

ipynb - Colaboratory

keyboard_arrow_down Petroleum Price Prediction Models

The following models would be developed:

GARCH with NARNN and vice versa

ARIMA with NARNN vice versa

SARIMA with NARNN vice versa

Exponential Smoothing with NARNN and vice versa.

NB: The residuals from the base model would be used to train the other model

The existing models serve as a Benchmark ( GARCH, ARIMA and SARIMA, Exponential
Smoothing)

1 # Load Libraries
2 import numpy as np # Mathematical Computations
3 import pandas as pd # Data Manipulation
4 import matplotlib.pyplot as plt # Data Visualization
5 import seaborn as sns # Advance Data Visualizations
6 import plotly.express as px # Advance and Interactive Data Visualizations

keyboard_arrow_down Load Dataset and Preprocessing

1 # Pick the data from local machine


2 from google.colab import files
3 file_path = files.upload()

Choose Files petroleum_products.xlsx


petroleum_products.xlsx(application/vnd.openxmlformats-officedocument.spreadsheetml.sheet) -
10200 bytes, last modified: 12/21/2023 - 100% done
Saving petroleum_products.xlsx to petroleum_products.xlsx

1 # Load the dataset into a useable dataframe format


2 df = pd.read_excel('petroleum_products.xlsx', index_col='Date')
3 df.head()

GASOLINE DIESEL LPG

Date

2019-01-01 4.89 4.90 4.99

2019-02-01 4.90 4.91 4.94

2019-03-01 5.15 5.16 5.01

2019-04-01 5.19 5.19 5.39

2019-05-01 5.20 5.21 4.97

https://colab.research.google.com/drive/12zwsFRYplo5DU6lIq6vfaYs75v6Sez4M#scrollTo=xFe4ZkpeBp26&uniqifier=3&printMode=true 1/13
1/3/24, 6:10 PM PPP Models - GARCH & NARNN.ipynb - Colaboratory
1 # Rename columns for convinience
2 df = df.rename(columns = {'GASOLINE': 'Gasoline', 'DIESEL': 'Diesel'})
3 df.columns

Index(['Gasoline', 'Diesel', 'LPG'], dtype='object')

keyboard_arrow_down Data Selection

1 # Select a Product and Model Type to Analyze


product: Gasoline
2 product = "Gasoline" # @param ["Gasoline", "Die
3 print(f"Selected Product: {product}")

Selected Product: Gasoline

keyboard_arrow_down GARCH - NARNN Model

keyboard_arrow_down Estimate The Mean Equation

1 ! pip install pmdarima


2 import pmdarima as pm
3 import statsmodels.api as sm
4 import matplotlib.pyplot as plt
5 from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

Collecting pmdarima
Downloading pmdarima-2.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manyl
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.1/2.1 MB 9.5 MB/s eta 0:00:00
Requirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.10/dist-packages (f
Requirement already satisfied: Cython!=0.29.18,!=0.29.31,>=0.29 in /usr/local/lib/python3
Requirement already satisfied: numpy>=1.21.2 in /usr/local/lib/python3.10/dist-packages (
Requirement already satisfied: pandas>=0.19 in /usr/local/lib/python3.10/dist-packages (f
Requirement already satisfied: scikit-learn>=0.22 in /usr/local/lib/python3.10/dist-packa
Requirement already satisfied: scipy>=1.3.2 in /usr/local/lib/python3.10/dist-packages (f
Requirement already satisfied: statsmodels>=0.13.2 in /usr/local/lib/python3.10/dist-pack
Requirement already satisfied: urllib3 in /usr/local/lib/python3.10/dist-packages (from p
Requirement already satisfied: setuptools!=50.0.0,>=38.6.0 in /usr/local/lib/python3.10/d
Requirement already satisfied: packaging>=17.1 in /usr/local/lib/python3.10/dist-packages
Requirement already satisfied: python-dateutil>=2.8.1 in /usr/local/lib/python3.10/dist-p
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (f
Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.10/dist-pac
Requirement already satisfied: patsy>=0.5.4 in /usr/local/lib/python3.10/dist-packages (f
Requirement already satisfied: six in /usr/local/lib/python3.10/dist-packages (from patsy
Installing collected packages: pmdarima
Successfully installed pmdarima-2.0.4

https://colab.research.google.com/drive/12zwsFRYplo5DU6lIq6vfaYs75v6Sez4M#scrollTo=xFe4ZkpeBp26&uniqifier=3&printMode=true 2/13
1/3/24, 6:10 PM PPP Models - GARCH & NARNN.ipynb - Colaboratory
1 from statsmodels.tsa.stattools import adfuller
2 # Perform the ADF test
3 def perform_adf_test(ds):
4 result = adfuller(ds)
5 # Extract and print test statistics
6 adf_statistic = result[0]
7 p_value = result[1]
8 critical_values = result[4]
9
10 print(f'ADF Statistic: {adf_statistic}')
11 print(f'p-value: {p_value}')
12 print(f'Critical Values: {critical_values}')
13
14 # Check the p-value against the significance level (e.g., 0.05)
15 if p_value <= 0.05:
16 print("Reject the null hypothesis. The time series is likely stationary.")
17 else:
18 print("Fail to reject the null hypothesis. The time series may not be stationary.")
19
20 perform_adf_test(df[product])

ADF Statistic: -0.4714985407350731


p-value: 0.8974593895763701
Critical Values: {'1%': -3.5506699942762414, '5%': -2.913766394626147, '10%': -2.59462404
Fail to reject the null hypothesis. The time series may not be stationary.

1 # Diffrence the data


2 differenced_ds = df[product].diff(1).dropna()
3 perform_adf_test(differenced_ds)

ADF Statistic: -6.54915636272955


p-value: 8.941192716390255e-09
Critical Values: {'1%': -3.5506699942762414, '5%': -2.913766394626147, '10%': -2.59462404
Reject the null hypothesis. The time series is likely stationary.

1 def find_arima_lags(data, max_ar=5, max_ma=5, figsize=(12, 3)):


2 # Plot ACF and PACF
3 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=figsize)
4
5 plot_acf(data, ax=ax1)
6 plot_pacf(data, ax=ax2)
7
8 ax1.set_title('Autocorrelation Function (ACF)')
9 ax2.set_title('Partial Autocorrelation Function (PACF)')
10
11 plt.show()
12
13 find_arima_lags(differenced_ds)

https://colab.research.google.com/drive/12zwsFRYplo5DU6lIq6vfaYs75v6Sez4M#scrollTo=xFe4ZkpeBp26&uniqifier=3&printMode=true 3/13
1/3/24, 6:10 PM PPP Models - GARCH & NARNN.ipynb - Colaboratory

1 # Perform Stepwise fit to identify the best order


2 stepwise_fit = pm.auto_arima(df[product], trace=True)
3 print(stepwise_fit.summary())

Performing stepwise search to minimize aic


ARIMA(2,1,2)(0,0,0)[0] intercept : AIC=154.005, Time=0.34 sec
ARIMA(0,1,0)(0,0,0)[0] intercept : AIC=153.281, Time=0.06 sec
ARIMA(1,1,0)(0,0,0)[0] intercept : AIC=154.166, Time=0.05 sec
ARIMA(0,1,1)(0,0,0)[0] intercept : AIC=152.760, Time=0.08 sec
ARIMA(0,1,0)(0,0,0)[0] : AIC=152.667, Time=0.03 sec
ARIMA(1,1,1)(0,0,0)[0] intercept : AIC=151.680, Time=0.33 sec
ARIMA(2,1,1)(0,0,0)[0] intercept : AIC=152.396, Time=0.45 sec
ARIMA(1,1,2)(0,0,0)[0] intercept : AIC=152.019, Time=0.27 sec
ARIMA(0,1,2)(0,0,0)[0] intercept : AIC=150.020, Time=0.46 sec
ARIMA(0,1,3)(0,0,0)[0] intercept : AIC=152.019, Time=0.56 sec
ARIMA(1,1,3)(0,0,0)[0] intercept : AIC=154.020, Time=0.55 sec
ARIMA(0,1,2)(0,0,0)[0] : AIC=149.611, Time=0.22 sec
ARIMA(0,1,1)(0,0,0)[0] : AIC=151.556, Time=0.11 sec
ARIMA(1,1,2)(0,0,0)[0] : AIC=151.592, Time=0.38 sec
ARIMA(0,1,3)(0,0,0)[0] : AIC=151.588, Time=0.25 sec
ARIMA(1,1,1)(0,0,0)[0] : AIC=150.689, Time=0.31 sec
ARIMA(1,1,3)(0,0,0)[0] : AIC=152.953, Time=0.80 sec

Best model: ARIMA(0,1,2)(0,0,0)[0]


Total fit time: 5.355 seconds
SARIMAX Results
==============================================================================
Dep. Variable: y No. Observations: 60
Model: SARIMAX(0, 1, 2) Log Likelihood -71.805
Date: Wed, 03 Jan 2024 AIC 149.611
Time: 17:31:45 BIC 155.844
Sample: 01-01-2019 HQIC 152.044
- 12-01-2023
Covariance Type: opg
==============================================================================
coef std err z P>|z| [0.025 0.975]
------------------------------------------------------------------------------
ma.L1 0.2512 0.068 3.721 0.000 0.119 0.384
ma.L2 -0.2579 0.151 -1.705 0.088 -0.554 0.039
sigma2 0.6648 0.042 15.793 0.000 0.582 0.747
===================================================================================
Ljung-Box (L1) (Q): 0.05 Jarque-Bera (JB): 1182.36
Prob(Q): 0.82 Prob(JB): 0.00
Heteroskedasticity (H): 23.10 Skew: 3.51
Prob(H) (two-sided): 0.00 Kurtosis: 23.77
===================================================================================

https://colab.research.google.com/drive/12zwsFRYplo5DU6lIq6vfaYs75v6Sez4M#scrollTo=xFe4ZkpeBp26&uniqifier=3&printMode=true 4/13
1/3/24, 6:10 PM PPP Models - GARCH & NARNN.ipynb - Colaboratory
Warnings:
[1] Covariance matrix calculated using the outer product of gradients (complex-step).

1 from statsmodels.tsa.arima.model import ARIMA


2 # # Fit ARIMA(2,2) model
3 order = (0, 1, 2) # (p, d, q) order
4 arima_model = ARIMA(df[product], order=order)
5 arima_results = arima_model.fit()
6
7 # Display model summary
8 print(arima_results.summary())

SARIMAX Results
==============================================================================
Dep. Variable: Gasoline No. Observations: 60
Model: ARIMA(0, 1, 2) Log Likelihood -71.805
Date: Wed, 03 Jan 2024 AIC 149.611
Time: 17:32:54 BIC 155.844
Sample: 01-01-2019 HQIC 152.044
- 12-01-2023
Covariance Type: opg
==============================================================================
coef std err z P>|z| [0.025 0.975]
------------------------------------------------------------------------------
ma.L1 0.2512 0.068 3.721 0.000 0.119 0.384
ma.L2 -0.2579 0.151 -1.705 0.088 -0.554 0.039
sigma2 0.6648 0.042 15.793 0.000 0.582 0.747
===================================================================================
Ljung-Box (L1) (Q): 0.05 Jarque-Bera (JB): 1182.36
Prob(Q): 0.82 Prob(JB): 0.00
Heteroskedasticity (H): 23.10 Skew: 3.51
Prob(H) (two-sided): 0.00 Kurtosis: 23.77
===================================================================================

Warnings:
[1] Covariance matrix calculated using the outer product of gradients (complex-step).
/usr/local/lib/python3.10/dist-packages/statsmodels/tsa/base/tsa_model.py:473: ValueWarni
self._init_dates(dates, freq)
/usr/local/lib/python3.10/dist-packages/statsmodels/tsa/base/tsa_model.py:473: ValueWarni
self._init_dates(dates, freq)
/usr/local/lib/python3.10/dist-packages/statsmodels/tsa/base/tsa_model.py:473: ValueWarni
self._init_dates(dates, freq)

1 arima_resid = pd.DataFrame(arima_results.resid)
2 arima_resid.plot(kind = "kde", figsize=(20,6))

https://colab.research.google.com/drive/12zwsFRYplo5DU6lIq6vfaYs75v6Sez4M#scrollTo=xFe4ZkpeBp26&uniqifier=3&printMode=true 5/13
1/3/24, 6:10 PM PPP Models - GARCH & NARNN.ipynb - Colaboratory

<Axes: ylabel='Density'>

keyboard_arrow_down ARCH TEST

Since the data has an AR component, we would fit the ARCH Model on the residuals of the ARIMA
model.

1 ! pip install arch


2 import arch

Requirement already satisfied: arch in /usr/local/lib/python3.10/dist-packages (6.2.0)


Requirement already satisfied: numpy>=1.19 in /usr/local/lib/python3.10/dist-packages (fr
Requirement already satisfied: scipy>=1.5 in /usr/local/lib/python3.10/dist-packages (fro
Requirement already satisfied: pandas>=1.1 in /usr/local/lib/python3.10/dist-packages (fr
Requirement already satisfied: statsmodels>=0.12 in /usr/local/lib/python3.10/dist-packag
Requirement already satisfied: python-dateutil>=2.8.1 in /usr/local/lib/python3.10/dist-p
Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (f
Requirement already satisfied: patsy>=0.5.4 in /usr/local/lib/python3.10/dist-packages (f
Requirement already satisfied: packaging>=21.3 in /usr/local/lib/python3.10/dist-packages
Requirement already satisfied: six in /usr/local/lib/python3.10/dist-packages (from patsy

1 # Obtain squared residuals


2 # squared_residuals = arima_results.resid**2
3 ds = arima_resid #df[product]
4 lags = 30 # ARCH TEST IS POSITIVE AT LAG 30
5
6 # Fit an ARCH model to the squared residuals
7 arch_model = arch.arch_model(ds, mean='Zero', vol='ARCH', p=3, lags=lags)
8 arch_result = arch_model.fit()
9
10 print(arch_result.summary())
11
12 # Perform ARCH LM test
13 lm_test = arch_result.arch_lm_test(lags=lags) # Adjust the number of lags as needed
14 print("ARCH LM Test p-value:", lm_test)
15

Iteration: 1, Func. Count: 6, Neg. LLF: 130.25413733733095


Iteration: 2, Func. Count: 16, Neg. LLF: 2024.039104072993
Iteration: 3, Func. Count: 22, Neg. LLF: 1953.3446359373388
Iteration: 4, Func. Count: 28, Neg. LLF: 1830.1700243650791
Iteration: 5, Func. Count: 34, Neg. LLF: 1772.5178015616962
Iteration: 6, Func. Count: 40, Neg. LLF: 1772.5177631819702

https://colab.research.google.com/drive/12zwsFRYplo5DU6lIq6vfaYs75v6Sez4M#scrollTo=xFe4ZkpeBp26&uniqifier=3&printMode=true 6/13
1/3/24, 6:10 PM PPP Models - GARCH & NARNN.ipynb - Colaboratory
Iteration: 7, Func. Count: 46, Neg. LLF: 1772.517900132466
Iteration: 8, Func. Count: 52, Neg. LLF: 57.32423354514197
Iteration: 9, Func. Count: 57, Neg. LLF: 57.46116408610714
Iteration: 10, Func. Count: 63, Neg. LLF: 57.28839336266442
Iteration: 11, Func. Count: 68, Neg. LLF: 1772.5140329794292
Iteration: 12, Func. Count: 75, Neg. LLF: 57.288380645096915
Optimization terminated successfully (Exit mode 0)
Current function value: 57.28837974861303
Iterations: 13
Function evaluations: 75
Gradient evaluations: 12
Zero Mean - ARCH Model Results
==============================================================================
Dep. Variable: 0 R-squared: 0.000
Mean Model: Zero Mean Adj. R-squared: 0.017
Vol Model: ARCH Log-Likelihood: -57.2884
Distribution: Normal AIC: 122.577
Method: Maximum Likelihood BIC: 130.954
No. Observations: 60
Date: Wed, Jan 03 2024 Df Residuals: 60
Time: 17:59:52 Df Model: 0
Volatility Model
=============================================================================
coef std err t P>|t| 95.0% Conf. Int.
-----------------------------------------------------------------------------
omega 0.1130 4.473e-02 2.527 1.149e-02 [2.538e-02, 0.201]
alpha[1] 1.0000 0.396 2.522 1.166e-02 [ 0.223, 1.777]
alpha[2] 6.5873e-14 2.325e-02 2.833e-12 1.000 [-4.557e-02,4.557e-02]
alpha[3] 1.0795e-13 8.136e-03 1.327e-11 1.000 [-1.595e-02,1.595e-02]
=============================================================================

Covariance estimator: robust


ARCH LM Test p-value: ARCH-LM Test
H0: Residuals are homoskedastic.
ARCH-LM Test
H1: Residuals are conditionally heteroskedastic.
Statistic: 49.3932
P-value: 0.0105
Distributed: chi2(29)

1 # Create a GARCH model


2 # Extract Residuals From ARCH Model
3 arch_residuals = arch_result.resid
4 garch_model = arch.arch_model(arch_residuals, mean='Constant', lags=1, vol='GARCH', p=1, q=1, power=2.0,
5
6 # Fit the model
7 garch_result = garch_model.fit()
8
9 # Display model summary
10 print(garch_result.summary())

Iteration: 1, Func. Count: 6, Neg. LLF: 248.13952546070539


Iteration: 2, Func. Count: 13, Neg. LLF: 140.93626886556575
Iteration: 3, Func. Count: 19, Neg. LLF: 122.20202445832632
Iteration: 4, Func. Count: 25, Neg. LLF: 123.06109763174514
Iteration: 5, Func. Count: 31, Neg. LLF: 3552.87176654639
Iteration: 6, Func. Count: 37, Neg. LLF: 8905.56417193098
Iteration: 7, Func. Count: 43, Neg. LLF: 602.6142582806667
Iteration: 8, Func. Count: 49, Neg. LLF: 6475.377231855412
Iteration: 9, Func. Count: 55, Neg. LLF: 5080.56075662095
Iteration: 10, Func. Count: 61, Neg. LLF: 58.103062449764415
Iteration: 11, Func. Count: 66, Neg. LLF: 385262.8141300336

https://colab.research.google.com/drive/12zwsFRYplo5DU6lIq6vfaYs75v6Sez4M#scrollTo=xFe4ZkpeBp26&uniqifier=3&printMode=true 7/13
1/3/24, 6:10 PM PPP Models - GARCH & NARNN.ipynb - Colaboratory
Iteration: 12, Func. Count: 72, Neg. LLF: 56.860447795643275
Iteration: 13, Func. Count: 77, Neg. LLF: 56.81596564847961
Iteration: 14, Func. Count: 82, Neg. LLF: 56.8117858529232
Iteration: 15, Func. Count: 87, Neg. LLF: 56.8116901249659
Iteration: 16, Func. Count: 92, Neg. LLF: 59.88033886994014
Iteration: 17, Func. Count: 100, Neg. LLF: 56.91129629217719
Optimization terminated successfully (Exit mode 0)
Current function value: 56.81168551834978
Iterations: 18
Function evaluations: 103
Gradient evaluations: 17
Constant Mean - GARCH Model Results
==============================================================================
Dep. Variable: resid R-squared: 0.000
Mean Model: Constant Mean Adj. R-squared: 0.000
Vol Model: GARCH Log-Likelihood: -56.8117
Distribution: Normal AIC: 121.623
Method: Maximum Likelihood BIC: 130.001
No. Observations: 60
Date: Wed, Jan 03 2024 Df Residuals: 59
Time: 18:04:45 Df Model: 1
Mean Model
===========================================================================
coef std err t P>|t| 95.0% Conf. Int.
---------------------------------------------------------------------------
mu 0.0678 4.784e-02 1.417 0.156 [-2.597e-02, 0.162]
Volatility Model
=============================================================================
coef std err t P>|t| 95.0% Conf. Int.
-----------------------------------------------------------------------------
omega 0.1003 3.882e-02 2.584 9.771e-03 [2.422e-02, 0.176]
alpha[1] 1.0000 0.366 2.730 6.327e-03 [ 0.282, 1.718]
beta[1] 1.5508e-13 8.794e-03 1.763e-11 1.000 [-1.724e-02,1.724e-02]
=============================================================================

Covariance estimator: robust

keyboard_arrow_down Evaluate GARCH Model

https://colab.research.google.com/drive/12zwsFRYplo5DU6lIq6vfaYs75v6Sez4M#scrollTo=xFe4ZkpeBp26&uniqifier=3&printMode=true 8/13
1/3/24, 6:10 PM PPP Models - GARCH & NARNN.ipynb - Colaboratory
1 # prompt: Write codes to evaluate the GARCH Model
2
3 # Evaluate the GARCH Model
4 # Calculate Residuals
5 residuals = garch_result.resid
6
7 # Calculate the Root Mean Squared Error (RMSE)
8 rmse = np.sqrt(np.mean(residuals**2))
9 print(f"RMSE: {rmse}")
10
11 # Calculate the Mean Absolute Error (MAE)
12 mae = np.mean(np.abs(residuals))
13 print(f"MAE: {mae}")
14
15 # Calculate the Mean Absolute Percentage Error (MAPE)
16 mape = np.mean(np.abs(residuals / arch_residuals)) * 100
17 print(f"MAPE: {mape}%")
18
19 # Plot the Residuals
20 plt.figure(figsize=(12, 6))
21 plt.plot(residuals, label='Residuals', alpha=0.6)
22 plt.title(f'Residuals of GARCH Model for {product}')
23 plt.xlabel('Year')
24 plt.ylabel('Residuals')
25 plt.legend()
26 plt.show()
27

RMSE: 1.0142621472049587
MAE: 0.4755606334037595
MAPE: 145.18138560695348%

https://colab.research.google.com/drive/12zwsFRYplo5DU6lIq6vfaYs75v6Sez4M#scrollTo=xFe4ZkpeBp26&uniqifier=3&printMode=true 9/13
1/3/24, 6:10 PM PPP Models - GARCH & NARNN.ipynb - Colaboratory
1 import statsmodels.api as sm
2 from statsmodels.stats.diagnostic import acorr_ljungbox
3
4 # Residual Analysis
5 squared_residuals = residuals**2
6
7 # Calculate standardized squared residuals
8 standardized_squared_residuals = (residuals ** 2) / (garch_result.conditional_volatility ** 2)
9
10
11 # Diagnostic Tests
12 # Autocorrelation in squared residuals (Ljung-Box test)
13 print(acorr_ljungbox(standardized_squared_residuals, lags=10, boxpierce=True))

lb_stat lb_pvalue bp_stat bp_pvalue


1 0.018688 0.891263 0.017784 0.893911
2 0.137440 0.933588 0.128875 0.937595
3 0.391232 0.942048 0.362199 0.947936
4 0.518298 0.971695 0.476969 0.975704
5 0.547749 0.990270 0.503095 0.992010
6 0.575410 0.996796 0.527186 0.997492
7 0.916299 0.996068 0.818591 0.997250
8 0.998753 0.998256 0.887746 0.998863
9 1.453216 0.997479 1.261578 0.998559
10 1.453267 0.999074 1.261620 0.999506

1 # Generate GARCH predictions


2 garch_forecast = garch_result.forecast(reindex=False, start=12) # Replace with the desired start date
3
4 # Extract actual variances from the dataset
5 actual_variances = garch_result.conditional_volatility
6
7
8 # Extract the predicted conditional volatility
9 predicted_volatility = garch_forecast.variance['h.1']
10
11 # Plot the original returns and predicted volatility
12 plt.figure(figsize=(12, 6))
13 # plt.plot(actual_variances, label=f'Original {product}', alpha=0.6)
14 plt.plot(predicted_volatility.index, predicted_volatility, label='Predicted Volatility', linestyle='--',
15 plt.title('GARCH Model Volatility Forecast (In sample)')
16 plt.xlabel('Time')
17 plt.ylabel('Volatility')
18 plt.legend()
19 plt.show()
20

https://colab.research.google.com/drive/12zwsFRYplo5DU6lIq6vfaYs75v6Sez4M#scrollTo=xFe4ZkpeBp26&uniqifier=3&printMode=true 10/13
1/3/24, 6:10 PM PPP Models - GARCH & NARNN.ipynb - Colaboratory

Extract GARCH Residuals

1 # Extract residuals
2 garch_residuals = garch_result.resid
3 # Plot residuals
4 plt.figure(figsize=(10, 4))
5 plt.plot(garch_residuals, label='GARCH Residuals')
6 plt.title('Residuals of GARCH Model')
7 plt.xlabel('Time')
8 plt.ylabel('Residuals')
9 plt.legend()
10 plt.show()

https://colab.research.google.com/drive/12zwsFRYplo5DU6lIq6vfaYs75v6Sez4M#scrollTo=xFe4ZkpeBp26&uniqifier=3&printMode=true 11/13
1/3/24, 6:10 PM PPP Models - GARCH & NARNN.ipynb - Colaboratory

NARNN MODEL
keyboard_arrow_down

1 from tensorflow import keras


2 from keras.models import Sequential
3 from keras.layers import LSTM, Dense
4 from keras.optimizers import Adam
5 from sklearn.preprocessing import MinMaxScaler

1 # Extract residuals from the GARCH model


2 residuals = garch_result.resid
3
4 # Scale the residuals between 0 and 1
5 # scaler = MinMaxScaler(feature_range=(0, 1))
6 residuals_scaled = residuals.values.reshape(-1, 1) #scaler.fit_transform()
7
8 # Create a NARNN model
9 model = Sequential()
10 model.add(LSTM(units=100, activation='relu', return_sequences=True, input_shape=(residuals_scaled.shape[1
11 model.add(LSTM(units=100, activation='relu'))
12 model.add(Dense(units=1))
13
14 # Compile the model
15 model.compile(optimizer=Adam(learning_rate=0.001), loss='mean_squared_error')
16
17 # Train the model
18 model.fit(residuals_scaled, residuals_scaled, epochs=100, batch_size=32)

Epoch 1/100
2/2 [==============================] - 10s 42ms/step - loss: 1.0298
Epoch 2/100
2/2 [==============================] - 0s 24ms/step - loss: 1.0240
Epoch 3/100
2/2 [==============================] - 0s 26ms/step - loss: 1.0166
Epoch 4/100
2/2 [==============================] - 0s 20ms/step - loss: 1.0096
Epoch 5/100
2/2 [==============================] - 0s 16ms/step - loss: 1.0060
Epoch 6/100
2/2 [==============================] - 0s 25ms/step - loss: 0.9984
Epoch 7/100
2/2 [==============================] - 0s 27ms/step - loss: 0.9935
Epoch 8/100
2/2 [==============================] - 0s 16ms/step - loss: 0.9872
Epoch 9/100
2/2 [==============================] - 0s 17ms/step - loss: 0.9807
Epoch 10/100
2/2 [==============================] - 0s 23ms/step - loss: 0.9744
Epoch 11/100
2/2 [==============================] - 0s 19ms/step - loss: 0.9664
Epoch 12/100
2/2 [==============================] - 0s 29ms/step - loss: 0.9567
Epoch 13/100
2/2 [==============================] - 0s 19ms/step - loss: 0.9490
Epoch 14/100
2/2 [==============================] - 0s 21ms/step - loss: 0.9355
Epoch 15/100
2/2 [==============================] - 0s 20ms/step - loss: 0.9262
Epoch 16/100
2/2 [==============================] - 0s 23ms/step - loss: 0.9164
Epoch 17/100

https://colab.research.google.com/drive/12zwsFRYplo5DU6lIq6vfaYs75v6Sez4M#scrollTo=xFe4ZkpeBp26&uniqifier=3&printMode=true 12/13
1/3/24, 6:10 PM PPP Models - GARCH & NARNN.ipynb - Colaboratory
2/2 [==============================] - 0s 20ms/step - loss: 0.8984
Epoch 18/100
2/2 [==============================] - 0s 11ms/step - loss: 0.8840
Epoch 19/100
2/2 [==============================] - 0s 10ms/step - loss: 0.8729
Epoch 20/100
2/2 [==============================] - 0s 10ms/step - loss: 0.8499
Epoch 21/100
2/2 [==============================] - 0s 12ms/step - loss: 0.8302
Epoch 22/100
2/2 [==============================] - 0s 12ms/step - loss: 0.8135
Epoch 23/100
2/2 [==============================] - 0s 10ms/step - loss: 0.7892
Epoch 24/100
2/2 [==============================] - 0s 11ms/step - loss: 0.7639
Epoch 25/100
2/2 [==============================] - 0s 10ms/step - loss: 0.7336
Epoch 26/100
2/2 [==============================] - 0s 10ms/step - loss: 0.7076
Epoch 27/100
2/2 [==============================] - 0s 18ms/step - loss: 0.6580
Epoch 28/100
2/2 [==============================] - 0s 11ms/step - loss: 0.6259
Epoch 29/100
2/2 [==============================] - 0s 10ms/step - loss: 0.5784

1 # Evaluate the model


2 model.evaluate(residuals_scaled, residuals_scaled)

2/2 [==============================] - 0s 8ms/step - loss: 0.0016


0.001564527628943324

1 # Make predictions
2 predictions = model.predict(residuals_scaled)
3
4 # Rescale the predictions back to the original range
5 #predictions = scaler.inverse_transform(predictions)
6
7 df2 = df

https://colab.research.google.com/drive/12zwsFRYplo5DU6lIq6vfaYs75v6Sez4M#scrollTo=xFe4ZkpeBp26&uniqifier=3&printMode=true 13/13

You might also like