Context:
You are the head of trading at a large Canadian integrated oil and gas firm. Your job is to manage spot and futures positions in oil and gas to ensure a balanced inventory, sell the companies raw and refined products, and manage the companies oil price risk. The oil your company produces is benchmarked to West Texas Intermediate (WTI), a North American centric oil benchmark, with some adjustments for quality and location differences.
The firms CEO and board would like to further understand whether events in oil markets outside of North America pose a risk to their firm. They would also like to know whether the trading desk could boost its profit by trading non-WTI contracts.
You have been asked to prepare a brief report outlining the relationship between the price of WTI, and the price of Brent (the primary Global oil price benchmark).
Assignment:
Within the above context, write a report suitable for sharing with the CEO and board on the relationship between daily WTI and Brent Crude Oil prices from 1995-01-01 to 2020-12-31.
Brent Oil Spot Price: Crude Oil Prices: Brent - Europe
WTI Oil Spot Price: Crude Oil Prices: West Texas Intermediate (WTI) - Cushing, Oklahoma
A full descriptive table of your time series variables.
This includes # of observations, # of missing values, mean, median,
standard deviation, skewness, and kurtosis. Discuss and compare any
notable statistical features of your variables.
# Retrieve WTI Crude Oil Prices
wti_data <- tq_get("DCOILWTICO", get = "economic.data", from = start_date, to = end_date)
# Retrieve Brent Crude Oil Prices
brent_data <- tq_get("DCOILBRENTEU", get = "economic.data", from = start_date, to = end_date)oil_data <- left_join(wti_data, brent_data, by = "date", suffix = c("_WTI", "_Brent"))
oil_data <- na.omit(oil_data)calculate_statistics <- function(data, variable_name) {
data %>%
summarise(
Variable = variable_name,
Observations = n(),
Missing_Values = sum(is.na(.data[[variable_name]])),
Mean = mean(.data[[variable_name]], na.rm = TRUE),
Median = median(.data[[variable_name]], na.rm = TRUE),
Standard_Deviation = sd(.data[[variable_name]], na.rm = TRUE),
Skewness = skewness(.data[[variable_name]], na.rm = TRUE),
Kurtosis = kurtosis(.data[[variable_name]], na.rm = TRUE)
)
}wti_stats <- calculate_statistics(oil_data, "price_WTI")
brent_stats <- calculate_statistics(oil_data, "price_Brent")
# results in a single table
descriptive_table <- bind_rows(wti_stats, brent_stats)
descriptive_table %>%
kable(
format = "html",
caption = "Descriptive Statistics of Oil Prices",
digits = 4
) %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE,
position = "center"
) %>%
row_spec(1)%>%
row_spec(0, bold = TRUE, background = "#D3D3D3") %>%
column_spec(3, color = "red", bold = TRUE)| Variable | Observations | Missing_Values | Mean | Median | Standard_Deviation | Skewness | Kurtosis |
|---|---|---|---|---|---|---|---|
| price_WTI | 6476 | 0 | 52.8387 | 49.15 | 28.7348 | 0.5169 | 2.3184 |
| price_Brent | 6476 | 0 | 54.7998 | 50.61 | 32.3824 | 0.5547 | 2.2147 |
Analysis:
Observations and Missing Values:
Both WTI and Brent datasets contain 6,476 observations with no missing values.
Mean and Median: The mean and median prices for both WTI and Brent are close, indicating a relatively symmetric distribution of prices over the period analyzed.
Standard Deviation: Brent prices exhibit a slightly higher standard deviation compared to WTI, suggesting marginally greater volatility in Brent prices during the study period.
Skewness: Both distributions have positive skewness values (WTI: 0.52, Brent: 0.55), indicating a slight rightward skew. This suggests that there were more instances of higher-than-average prices, though the skewness is relatively mild.
Kurtosis: Both the WTI and Brent distributions exhibit less pronounced tails than a normal distribution (kurtosis = 3), indicating they are less prone to extreme price fluctuations.
Since these kurtosis values are close to 3 but less than that, their distributions are somewhat similar to a normal distribution but with slightly flatter peaks and less heavy tails.
For financial data like oil prices, these kurtosis values suggest that extreme price changes (spikes or drops) are less frequent compared to distributions with higher kurtosis.
In summary, both WTI and Brent crude oil prices exhibit similar statistical characteristics, with slight differences in volatility and skewness. These similarities reflect the interconnected nature of global oil markets, where factors influencing one benchmark often affect the other in a comparable manner.
# Calculate correlation
correlation <- cor(oil_data$price_WTI, oil_data$price_Brent)
print(paste("Correlation between WTI and Brent prices:", round(correlation, 2)))## [1] "Correlation between WTI and Brent prices: 0.99"
A correlation coefficient of 0.99 between WTI and Brent crude oil prices indicates an exceptionally strong positive linear relationship. This means that as the price of one benchmark increases or decreases, the price of the other tends to move in the same direction to a nearly identical degree.
Global Market Integration: The high correlation suggests that WTI and Brent prices are influenced by similar global supply and demand factors, including geopolitical events, economic conditions, and production decisions by major oil-producing countries.
Risk Management: For firms whose operations are tied to WTI pricing, such as those in North America, this strong correlation implies that global events affecting Brent prices are likely to impact WTI prices similarly. Therefore, monitoring international market developments is crucial for effective risk management.
Trading Strategies: The near-identical movement of WTI and Brent prices indicates limited arbitrage opportunities between these two benchmarks. However, during rare periods of divergence—often due to regional supply disruptions or logistical constraints—traders might find opportunities to capitalize on the price differential.
In summary, the 0.99 correlation coefficient underscores the interconnectedness of WTI and Brent crude oil markets, highlighting the importance of a global perspective in oil trading and risk management strategies.
Generate one time series plot containing both WTI and Brent Oil
prices over time.
Compare the patterns in both price series.
# Transform the data
oil_data_long <- oil_data %>%
pivot_longer(cols = starts_with("price"), names_to = "Type", values_to = "Price") %>%
mutate(Type = recode(Type, price_WTI = "WTI", price_Brent = "Brent"))
# Create the ggplot object
p <- ggplot(oil_data_long, aes(x = date, y = Price, color = Type)) +
geom_line() +
scale_color_manual(values = c("WTI" = "#ffde57", "Brent" = "#4584b6")) +
labs(title = "WTI and Brent Crude Oil Prices (1995-2020)",
x = "",
y = "USD per Barrel",
color = "Crude Oil Type") +
theme_minimal()
# Make it interactive
interactive_plot <- ggplotly(p)
htmltools::div(interactive_plot, style = "display: flex; justify-content: center;")Both types of oil show a general increase in prices from the late 1990s to around 2008, peaking at over 100 USD per barrel.
After the 2008 peak, there is a sharp decline, followed by fluctuations with a major dip around 2014-2016 and another significant decline in 2020.
Volatility: The data exhibits periods of high volatility, particularly between 2000 and 2020, indicating economic and market events that impacted oil prices.
Convert prices to log prices, use log prices for the remaining analysis
# log transformation
oil_data <- oil_data %>%
mutate(log_price_WTI = log(price_WTI),
log_price_Brent = log(price_Brent))
# statistics for log-transformed prices
log_wti_stats <- calculate_statistics(oil_data, "log_price_WTI")
log_brent_stats <- calculate_statistics(oil_data, "log_price_Brent")
# results in a single table
log_descriptive_table <- bind_rows(log_wti_stats, log_brent_stats)
log_descriptive_table %>%
kable(
format = "html",
caption = "Log Descriptive Statistics of Oil Prices",
digits = 4
) %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE,
position = "center"
) %>%
row_spec(1, background = "#D3D3D3")%>%
row_spec(0, bold = TRUE) %>%
column_spec(3, color = "red", bold = TRUE)| Variable | Observations | Missing_Values | Mean | Median | Standard_Deviation | Skewness | Kurtosis |
|---|---|---|---|---|---|---|---|
| log_price_WTI | 6476 | 1 | 3.8022 | 3.8951 | 0.5993 | -0.2807 | 2.0055 |
| log_price_Brent | 6476 | 0 | 3.8047 | 3.9241 | 0.6616 | -0.2845 | 1.9934 |
# Reshape data to long format for plotting
oil_data_long <- oil_data %>%
select(date, log_price_WTI, log_price_Brent) %>%
pivot_longer(cols = starts_with("log_price"), names_to = "Type", values_to = "Log_Price") %>%
mutate(Type = recode(Type, log_price_WTI = "WTI", log_price_Brent = "Brent"))
# Create the ggplot object
p_oil_data_long <- ggplot(oil_data_long, aes(x = date, y = Log_Price, color = Type)) +
geom_line() +
scale_color_manual(values = c("WTI" = "#ffde57", "Brent" = "#4584b6")) +
labs(title = "Log-Transformed WTI and Brent Crude Oil Prices (1995-2020)",
x = "",
y = "Log Price (Natural Log of USD per Barrel)",
color = "Crude Oil Type") +
theme_minimal()
# Make it interactive
interactive_plot_long <- ggplotly(p_oil_data_long)
htmltools::div(interactive_plot_long, style = "display: flex; justify-content: center;")
Explore and discuss whether the Brent and WTI Oil log price series are
non-stationary
- Use ACF’s and Unit-Root tests
- Note: For the unit root test use an appropriate lag order.
library(forecast)
# Plot ACF for log-transformed WTI prices
plot_acf_wti <- ggAcf(oil_data$log_price_WTI, main = "ACF of Log-Transformed WTI Prices")
# Plot ACF for log-transformed Brent prices
plot_acf_brent <- ggAcf(oil_data$log_price_Brent, main = "ACF of Log-Transformed Brent Prices")
grid.arrange(plot_acf_wti, plot_acf_brent, ncol = 2)# oil_data_clean <- na.omit(oil_data[, c("log_price_WTI", "log_price_Brent")])
# adf_wti <- adf.test(oil_data_clean$log_price_WTI, alternative = "stationary")
# adf_brent <- adf.test(oil_data_clean$log_price_Brent, alternative = "stationary")
# while both functions serve the purpose of conducting the ADF test, adf.test() is suitable for quick checks with minimal configuration, whereas ur.df() is more appropriate for detailed and customizable time series analysis.
library(urca)
oil_data_clean <- oil_data[!is.na(oil_data$log_price_WTI), ]
adf_wti <- ur.df(oil_data_clean$log_price_WTI, type = "drift", selectlags = "AIC")
summary(adf_wti)##
## ###############################################
## # Augmented Dickey-Fuller Test Unit Root Test #
## ###############################################
##
## Test regression drift
##
##
## Call:
## lm(formula = z.diff ~ z.lag.1 + 1 + z.diff.lag)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.72700 -0.01258 0.00073 0.01331 0.37438
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.0050146 0.0022923 2.188 0.0287 *
## z.lag.1 -0.0012748 0.0005955 -2.141 0.0323 *
## z.diff.lag -0.0683441 0.0124007 -5.511 3.7e-08 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.02871 on 6470 degrees of freedom
## Multiple R-squared: 0.005448, Adjusted R-squared: 0.005141
## F-statistic: 17.72 on 2 and 6470 DF, p-value: 2.111e-08
##
##
## Value of test-statistic is: -2.1407 2.4011
##
## Critical values for test statistics:
## 1pct 5pct 10pct
## tau2 -3.43 -2.86 -2.57
## phi1 6.43 4.59 3.78
adf_brent <- ur.df(oil_data_clean$log_price_Brent, type = "drift", selectlags = "AIC")
summary(adf_brent)##
## ###############################################
## # Augmented Dickey-Fuller Test Unit Root Test #
## ###############################################
##
## Test regression drift
##
##
## Call:
## lm(formula = z.diff ~ z.lag.1 + 1 + z.diff.lag)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.77159 -0.01201 0.00071 0.01268 0.38111
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.0039097 0.0019370 2.018 0.04359 *
## z.lag.1 -0.0009783 0.0005015 -1.951 0.05115 .
## z.diff.lag -0.0377505 0.0124211 -3.039 0.00238 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.02669 on 6470 degrees of freedom
## Multiple R-squared: 0.00204, Adjusted R-squared: 0.001732
## F-statistic: 6.614 on 2 and 6470 DF, p-value: 0.00135
##
##
## Value of test-statistic is: -1.9506 2.0617
##
## Critical values for test statistics:
## 1pct 5pct 10pct
## tau2 -3.43 -2.86 -2.57
## phi1 6.43 4.59 3.78
Selecting the Appropriate Lag Order:
The selectlags = “AIC” parameter in the ur.df function automatically selects the optimal lag length based on the Akaike Information Criterion (AIC). This approach ensures that the model accounts for the necessary lagged terms without overfitting.
Interpreting ADF Test Results:
Null Hypothesis (H₀): The series has a unit root (non-stationary).
Alternative Hypothesis (H₁): The series does not have a unit root (stationary).
If the test statistic is less than the critical value at a chosen significance level (e.g., 5%), we reject the null hypothesis, indicating that the series is stationary. Conversely, if we fail to reject the null hypothesis, it suggests that the series is non-stationary.
Conclusion:Based on the ACF analysis and the results of the ADF tests, we can determine the stationarity of the log-transformed WTI and Brent crude oil price series. If both analyses indicate non-stationarity, it may be necessary to difference the series or apply other transformations to achieve stationarity before proceeding with further time series modeling.
Estimate and present results for a VAR(12) model
• Any data that is non-stationary should be properly differenced to make
it stationary first.
• Make sure you interpret and discuss the results
Differencing transforms the data to stationary by removing trends and seasonality.
oil_data_diff <- oil_data %>%
mutate(
diff_log_price_WTI = c(NA, diff(log_price_WTI)),
diff_log_price_Brent = c(NA, diff(log_price_Brent))
)
oil_data_diff <- oil_data_diff %>%
filter(!is.na(diff_log_price_WTI) & !is.na(diff_log_price_Brent))
Selecting the Optimal Lag Length.
Before fitting the VAR model, determine the appropriate lag length using
information criteria.
lag_selection <- VARselect(oil_data_diff[, c("diff_log_price_WTI", "diff_log_price_Brent")], lag.max = 12, type = "const")
print(lag_selection$selection)## AIC(n) HQ(n) SC(n) FPE(n)
## 12 12 11 12
Estimating the VAR(12) Model and Fit the VAR model with 12 lags.
var_model <- vars::VAR(oil_data_diff[, c("diff_log_price_WTI", "diff_log_price_Brent")], p = 12, type = "const")
summary(var_model)##
## VAR Estimation Results:
## =========================
## Endogenous variables: diff_log_price_WTI, diff_log_price_Brent
## Deterministic variables: const
## Sample size: 6461
## Log Likelihood: 30871.968
## Roots of the characteristic polynomial:
## 0.8564 0.8564 0.8088 0.8088 0.8067 0.8067 0.804 0.8031 0.8031 0.7861 0.7845 0.7845 0.7773 0.7773 0.7745 0.7745 0.7563 0.7563 0.7385 0.7385 0.7022 0.7022 0.4711 0.01086
## Call:
## vars::VAR(y = oil_data_diff[, c("diff_log_price_WTI", "diff_log_price_Brent")],
## p = 12, type = "const")
##
##
## Estimation results for equation diff_log_price_WTI:
## ===================================================
## diff_log_price_WTI = diff_log_price_WTI.l1 + diff_log_price_Brent.l1 + diff_log_price_WTI.l2 + diff_log_price_Brent.l2 + diff_log_price_WTI.l3 + diff_log_price_Brent.l3 + diff_log_price_WTI.l4 + diff_log_price_Brent.l4 + diff_log_price_WTI.l5 + diff_log_price_Brent.l5 + diff_log_price_WTI.l6 + diff_log_price_Brent.l6 + diff_log_price_WTI.l7 + diff_log_price_Brent.l7 + diff_log_price_WTI.l8 + diff_log_price_Brent.l8 + diff_log_price_WTI.l9 + diff_log_price_Brent.l9 + diff_log_price_WTI.l10 + diff_log_price_Brent.l10 + diff_log_price_WTI.l11 + diff_log_price_Brent.l11 + diff_log_price_WTI.l12 + diff_log_price_Brent.l12 + const
##
## Estimate Std. Error t value Pr(>|t|)
## diff_log_price_WTI.l1 -0.0696039 0.0159990 -4.351 1.38e-05 ***
## diff_log_price_Brent.l1 0.0479910 0.0181842 2.639 0.008331 **
## diff_log_price_WTI.l2 -0.0213173 0.0173402 -1.229 0.218983
## diff_log_price_Brent.l2 0.0079016 0.0186873 0.423 0.672432
## diff_log_price_WTI.l3 -0.0380322 0.0176009 -2.161 0.030747 *
## diff_log_price_Brent.l3 -0.0423533 0.0188513 -2.247 0.024692 *
## diff_log_price_WTI.l4 -0.0336636 0.0178072 -1.890 0.058744 .
## diff_log_price_Brent.l4 0.1135723 0.0188721 6.018 1.86e-09 ***
## diff_log_price_WTI.l5 -0.1082490 0.0177547 -6.097 1.14e-09 ***
## diff_log_price_Brent.l5 0.0710306 0.0188940 3.759 0.000172 ***
## diff_log_price_WTI.l6 -0.0645523 0.0177658 -3.634 0.000282 ***
## diff_log_price_Brent.l6 0.1081937 0.0189321 5.715 1.15e-08 ***
## diff_log_price_WTI.l7 -0.1243300 0.0177658 -6.998 2.85e-12 ***
## diff_log_price_Brent.l7 0.1511623 0.0189879 7.961 2.00e-15 ***
## diff_log_price_WTI.l8 -0.1175519 0.0177642 -6.617 3.95e-11 ***
## diff_log_price_Brent.l8 0.1387049 0.0190481 7.282 3.69e-13 ***
## diff_log_price_WTI.l9 -0.0859728 0.0178312 -4.821 1.46e-06 ***
## diff_log_price_Brent.l9 0.1116589 0.0191129 5.842 5.41e-09 ***
## diff_log_price_WTI.l10 -0.0974224 0.0176917 -5.507 3.80e-08 ***
## diff_log_price_Brent.l10 0.1448273 0.0188355 7.689 1.70e-14 ***
## diff_log_price_WTI.l11 -0.0639646 0.0175294 -3.649 0.000265 ***
## diff_log_price_Brent.l11 0.0288206 0.0185712 1.552 0.120735
## diff_log_price_WTI.l12 0.0176199 0.0166596 1.058 0.290260
## diff_log_price_Brent.l12 -0.0185015 0.0170952 -1.082 0.279177
## const 0.0002171 0.0003348 0.648 0.516776
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## Residual standard error: 0.02689 on 6436 degrees of freedom
## Multiple R-Squared: 0.03846, Adjusted R-squared: 0.03487
## F-statistic: 10.73 on 24 and 6436 DF, p-value: < 2.2e-16
##
##
## Estimation results for equation diff_log_price_Brent:
## =====================================================
## diff_log_price_Brent = diff_log_price_WTI.l1 + diff_log_price_Brent.l1 + diff_log_price_WTI.l2 + diff_log_price_Brent.l2 + diff_log_price_WTI.l3 + diff_log_price_Brent.l3 + diff_log_price_WTI.l4 + diff_log_price_Brent.l4 + diff_log_price_WTI.l5 + diff_log_price_Brent.l5 + diff_log_price_WTI.l6 + diff_log_price_Brent.l6 + diff_log_price_WTI.l7 + diff_log_price_Brent.l7 + diff_log_price_WTI.l8 + diff_log_price_Brent.l8 + diff_log_price_WTI.l9 + diff_log_price_Brent.l9 + diff_log_price_WTI.l10 + diff_log_price_Brent.l10 + diff_log_price_WTI.l11 + diff_log_price_Brent.l11 + diff_log_price_WTI.l12 + diff_log_price_Brent.l12 + const
##
## Estimate Std. Error t value Pr(>|t|)
## diff_log_price_WTI.l1 0.3357039 0.0140483 23.896 < 2e-16 ***
## diff_log_price_Brent.l1 -0.2179587 0.0159671 -13.651 < 2e-16 ***
## diff_log_price_WTI.l2 0.1843062 0.0152260 12.105 < 2e-16 ***
## diff_log_price_Brent.l2 -0.1504378 0.0164089 -9.168 < 2e-16 ***
## diff_log_price_WTI.l3 0.1490859 0.0154549 9.647 < 2e-16 ***
## diff_log_price_Brent.l3 -0.1058632 0.0165528 -6.395 1.71e-10 ***
## diff_log_price_WTI.l4 0.0683215 0.0156361 4.369 1.27e-05 ***
## diff_log_price_Brent.l4 0.0027927 0.0165711 0.169 0.866173
## diff_log_price_WTI.l5 0.0155043 0.0155900 0.995 0.320015
## diff_log_price_Brent.l5 -0.0206614 0.0165903 -1.245 0.213034
## diff_log_price_WTI.l6 -0.0063707 0.0155997 -0.408 0.683003
## diff_log_price_Brent.l6 0.0079742 0.0166238 0.480 0.631469
## diff_log_price_WTI.l7 -0.0189433 0.0155997 -1.214 0.224664
## diff_log_price_Brent.l7 0.0297046 0.0166728 1.782 0.074858 .
## diff_log_price_WTI.l8 0.0221450 0.0155983 1.420 0.155742
## diff_log_price_Brent.l8 -0.0120966 0.0167257 -0.723 0.469561
## diff_log_price_WTI.l9 0.0137028 0.0156571 0.875 0.381509
## diff_log_price_Brent.l9 0.0301389 0.0167826 1.796 0.072566 .
## diff_log_price_WTI.l10 0.0130795 0.0155346 0.842 0.399844
## diff_log_price_Brent.l10 0.0481129 0.0165390 2.909 0.003638 **
## diff_log_price_WTI.l11 0.0264961 0.0153921 1.721 0.085225 .
## diff_log_price_Brent.l11 -0.0544356 0.0163069 -3.338 0.000848 ***
## diff_log_price_WTI.l12 0.0682210 0.0146284 4.664 3.17e-06 ***
## diff_log_price_Brent.l12 -0.0703672 0.0150109 -4.688 2.82e-06 ***
## const 0.0002118 0.0002940 0.721 0.471205
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
##
## Residual standard error: 0.02361 on 6436 degrees of freedom
## Multiple R-Squared: 0.1071, Adjusted R-squared: 0.1038
## F-statistic: 32.17 on 24 and 6436 DF, p-value: < 2.2e-16
##
##
##
## Covariance matrix of residuals:
## diff_log_price_WTI diff_log_price_Brent
## diff_log_price_WTI 0.0007231 0.0003983
## diff_log_price_Brent 0.0003983 0.0005575
##
## Correlation matrix of residuals:
## diff_log_price_WTI diff_log_price_Brent
## diff_log_price_WTI 1.0000 0.6274
## diff_log_price_Brent 0.6274 1.0000
Are the log prices of WTI and Brent cointegrated?
• Conduct a formal test of cointegration and interpret the result
oil_data <- na.omit(oil_data)
# log transformation
oil_data <- oil_data %>%
mutate(log_price_WTI = log(price_WTI),
log_price_Brent = log(price_Brent))
# ADF test on log-transformed WTI prices
adf_wti <- ur.df(oil_data$log_price_WTI, type = "drift", selectlags = "AIC")
summary(adf_wti)##
## ###############################################
## # Augmented Dickey-Fuller Test Unit Root Test #
## ###############################################
##
## Test regression drift
##
##
## Call:
## lm(formula = z.diff ~ z.lag.1 + 1 + z.diff.lag)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.72700 -0.01258 0.00073 0.01331 0.37438
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.0050146 0.0022923 2.188 0.0287 *
## z.lag.1 -0.0012748 0.0005955 -2.141 0.0323 *
## z.diff.lag -0.0683441 0.0124007 -5.511 3.7e-08 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.02871 on 6470 degrees of freedom
## Multiple R-squared: 0.005448, Adjusted R-squared: 0.005141
## F-statistic: 17.72 on 2 and 6470 DF, p-value: 2.111e-08
##
##
## Value of test-statistic is: -2.1407 2.4011
##
## Critical values for test statistics:
## 1pct 5pct 10pct
## tau2 -3.43 -2.86 -2.57
## phi1 6.43 4.59 3.78
# ADF test on log-transformed Brent prices
adf_brent <- ur.df(oil_data$log_price_Brent, type = "drift", selectlags = "AIC")
summary(adf_brent)##
## ###############################################
## # Augmented Dickey-Fuller Test Unit Root Test #
## ###############################################
##
## Test regression drift
##
##
## Call:
## lm(formula = z.diff ~ z.lag.1 + 1 + z.diff.lag)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.77159 -0.01201 0.00071 0.01268 0.38111
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.0039097 0.0019370 2.018 0.04359 *
## z.lag.1 -0.0009783 0.0005015 -1.951 0.05115 .
## z.diff.lag -0.0377505 0.0124211 -3.039 0.00238 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.02669 on 6470 degrees of freedom
## Multiple R-squared: 0.00204, Adjusted R-squared: 0.001732
## F-statistic: 6.614 on 2 and 6470 DF, p-value: 0.00135
##
##
## Value of test-statistic is: -1.9506 2.0617
##
## Critical values for test statistics:
## 1pct 5pct 10pct
## tau2 -3.43 -2.86 -2.57
## phi1 6.43 4.59 3.78
# Step 1: OLS regression of log_price_WTI on log_price_Brent
ols_model <- lm(log_price_WTI ~ log_price_Brent, data = oil_data)
summary(ols_model)##
## Call:
## lm(formula = log_price_WTI ~ log_price_Brent, data = oil_data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.43538 -0.03753 0.00041 0.04508 0.28191
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.374259 0.004555 82.17 <2e-16 ***
## log_price_Brent 0.900938 0.001179 763.89 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.06278 on 6473 degrees of freedom
## Multiple R-squared: 0.989, Adjusted R-squared: 0.989
## F-statistic: 5.835e+05 on 1 and 6473 DF, p-value: < 2.2e-16
# Extract residuals
residuals_ols <- resid(ols_model)
# Step 2: ADF test on residuals
adf_residuals <- ur.df(residuals_ols, type = "none", selectlags = "AIC")
summary(adf_residuals)##
## ###############################################
## # Augmented Dickey-Fuller Test Unit Root Test #
## ###############################################
##
## Test regression none
##
##
## Call:
## lm(formula = z.diff ~ z.lag.1 - 1 + z.diff.lag)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.27251 -0.00985 0.00025 0.01016 0.59689
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## z.lag.1 -0.051269 0.004443 -11.54 <2e-16 ***
## z.diff.lag -0.244597 0.012054 -20.29 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.02206 on 6471 degrees of freedom
## Multiple R-squared: 0.09172, Adjusted R-squared: 0.09144
## F-statistic: 326.7 on 2 and 6471 DF, p-value: < 2.2e-16
##
##
## Value of test-statistic is: -11.5398
##
## Critical values for test statistics:
## 1pct 5pct 10pct
## tau1 -2.58 -1.95 -1.62
The analysis investigates the long-term relationship between the log-transformed prices of West Texas Intermediate (WTI) and Brent crude oil from January 1, 1995, to December 31, 2020.
1. Ordinary Least Squares (OLS) Regression:
An OLS regression was performed with log_price_WTI as the
dependent variable and log_price_Brent as the independent
variable.
Regression Equation: log_price_WTI = 0.374259 + 0.900938 * log_price_Brent
Key Statistics:
Interpretation:
The high R-squared value (0.989) indicates that approximately 98.9% of the variance in WTI log prices is explained by Brent log prices. The slope coefficient of 0.900938 suggests a strong positive relationship between the two price series.
2. Augmented Dickey-Fuller (ADF) Test on Residuals:
To assess cointegration, an ADF test was conducted on the residuals of the OLS regression.
Interpretation:
The test statistic (-11.5398) is significantly lower than the 1% critical value (-2.58), leading to the rejection of the null hypothesis of a unit root in the residuals. This indicates that the residuals are stationary, confirming that the log-transformed prices of WTI and Brent crude oil are cointegrated.
Conclusion:
The log-transformed prices of WTI and Brent crude oil exhibit a strong long-term equilibrium relationship, as evidenced by the high R-squared value in the OLS regression and the stationarity of the residuals. This cointegration implies that, despite short-term deviations, the two price series move together over time, maintaining a stable long-term relationship.
Estimate and present results for an appropriate VECM(12) model on log
prices.
• Is there a long-run relationship between WTI and Brent?
• Interpret the speed of adjustment coefficients
library(tsDyn)
# Combine the log price series into a matrix
log_prices <- cbind(oil_data$log_price_WTI, oil_data$log_price_Brent)
colnames(log_prices) <- c("log_price_WTI", "log_price_Brent")
# Determine the number of cointegrating relationships
johansen_test <- ca.jo(log_prices, type = "trace", ecdet = "const", K = 13)
summary(johansen_test)##
## ######################
## # Johansen-Procedure #
## ######################
##
## Test type: trace statistic , without linear trend and constant in cointegration
##
## Eigenvalues (lambda):
## [1] 5.273317e-03 6.629280e-04 -2.922447e-21
##
## Values of teststatistic and critical values of test:
##
## test 10pct 5pct 1pct
## r <= 1 | 4.29 7.52 9.24 12.97
## r = 0 | 38.45 17.85 19.96 24.60
##
## Eigenvectors, normalised to first column:
## (These are the cointegration relations)
##
## log_price_WTI.l13 log_price_Brent.l13 constant
## log_price_WTI.l13 1.0000000 1.000000 1.000000
## log_price_Brent.l13 -0.9052149 0.811976 -3.213703
## constant -0.3568884 -7.156026 1.867247
##
## Weights W:
## (This is the loading matrix)
##
## log_price_WTI.l13 log_price_Brent.l13 constant
## log_price_WTI.d -0.01316557 -0.0005735230 2.919392e-20
## log_price_Brent.d 0.01391791 -0.0004974956 2.032787e-19
# Extract the cointegrating vector
cointegration_vector <- cajorls(johansen_test, r = 1)$beta
print(cointegration_vector)## ect1
## log_price_WTI.l13 1.0000000
## log_price_Brent.l13 -0.9052149
## constant -0.3568884
# Fit the VECM with 12 lags
vecm_model <- VECM(log_prices, lag = 12, r = 1, include = "const", estim = "ML")
summary(vecm_model)## #############
## ###Model VECM
## #############
## Full sample size: 6475 End sample size: 6462
## Number of variables: 2 Number of estimated slope parameters 52
## AIC -97519.13 BIC -97160.12 SSR 9.099038
## Cointegrating vector (estimated by ML):
## log_price_WTI log_price_Brent
## r1 1 -0.9051604
##
##
## ECT Intercept
## Equation log_price_WTI -0.0132(0.0060)* 0.0049(0.0022)*
## Equation log_price_Brent 0.0139(0.0054)** -0.0048(0.0019)*
## log_price_WTI -1 log_price_Brent -1
## Equation log_price_WTI -0.0415(0.0172)* -0.0475(0.0190)*
## Equation log_price_Brent 0.3331(0.0155)*** -0.3024(0.0170)***
## log_price_WTI -2 log_price_Brent -2
## Equation log_price_WTI -0.0025(0.0184) -0.0092(0.0196)
## Equation log_price_Brent 0.1775(0.0165)*** -0.1335(0.0176)***
## log_price_WTI -3 log_price_Brent -3
## Equation log_price_WTI -0.0290(0.0187) -0.0328(0.0197).
## Equation log_price_Brent 0.1253(0.0167)*** -0.0867(0.0177)***
## log_price_WTI -4 log_price_Brent -4
## Equation log_price_WTI 0.0289(0.0188) 0.0852(0.0197)***
## Equation log_price_Brent 0.1126(0.0169)*** -0.0484(0.0177)**
## log_price_WTI -5 log_price_Brent -5
## Equation log_price_WTI -0.1309(0.0188)*** 0.1492(0.0197)***
## Equation log_price_Brent -0.0274(0.0168) 0.0552(0.0177)**
## log_price_WTI -6 log_price_Brent -6
## Equation log_price_WTI -0.0659(0.0187)*** 0.0245(0.0197)
## Equation log_price_Brent -0.0133(0.0168) -0.0689(0.0177)***
## log_price_WTI -7 log_price_Brent -7
## Equation log_price_WTI -0.1266(0.0187)*** 0.1254(0.0198)***
## Equation log_price_Brent -0.0149(0.0168) 0.0401(0.0177)*
## log_price_WTI -8 log_price_Brent -8
## Equation log_price_WTI -0.1137(0.0186)*** 0.1432(0.0198)***
## Equation log_price_Brent 0.0127(0.0167) 0.0300(0.0177).
## log_price_WTI -9 log_price_Brent -9
## Equation log_price_WTI -0.0851(0.0187)*** 0.0797(0.0197)***
## Equation log_price_Brent -0.0118(0.0168) 0.0099(0.0177)
## log_price_WTI -10 log_price_Brent -10
## Equation log_price_WTI -0.1043(0.0185)*** 0.0617(0.0194)**
## Equation log_price_Brent -0.0184(0.0166) -0.0149(0.0174)
## log_price_WTI -11 log_price_Brent -11
## Equation log_price_WTI -0.0849(0.0182)*** 0.1171(0.0190)***
## Equation log_price_Brent -0.0072(0.0163) 0.0600(0.0170)***
## log_price_WTI -12 log_price_Brent -12
## Equation log_price_WTI -0.1860(0.0173)*** 0.1794(0.0175)***
## Equation log_price_Brent -0.1534(0.0155)*** 0.1438(0.0157)***
Conclusion:
The analysis indicates a significant long-term relationship between West Texas Intermediate (WTI) and Brent crude oil prices. The high correlation and cointegration between these benchmarks suggest that global oil market events, including those outside North America, influence WTI prices over the long run.
Implications for the Firm:
Given the interconnectedness of WTI and Brent prices, the firm can consider the following strategies to manage risk and enhance profitability:
Hedging with Brent Contracts:
Risk Mitigation: Utilize Brent futures or options to hedge against price volatility, especially when global events are expected to impact oil markets.
Diversification: Incorporate Brent-based instruments to diversify the firm’s hedging portfolio, reducing reliance solely on WTI-based contracts.
Spread Trading:
Exploiting Price Differentials: Engage in spread trading by taking positions on the price difference between WTI and Brent. This strategy can capitalize on temporary deviations from the long-term equilibrium relationship.
Arbitrage Opportunities: Monitor and act on arbitrage opportunities arising from discrepancies between WTI and Brent prices, adjusting positions as the spread converges.
Global Market Monitoring:
Informed Decision-Making: Stay vigilant to international events, such as geopolitical tensions or OPEC decisions, that may affect Brent prices and, consequently, WTI prices.
Proactive Positioning: Adjust trading strategies proactively in anticipation of global market shifts, leveraging insights into the Brent-WTI relationship.
By acknowledging the global factors influencing WTI prices and implementing these strategies, the firm can better manage its oil price risk and identify opportunities for profit in the interconnected oil markets.
Md Mahmudul
Hasan
MQIM 3760573
Faculty of Management
University of New Brunswick
mahmudul.hasan@unb.ca