logo

1. Introduction

In this project I decided to explore the monthly price of gold in GBP per troy ounce, with data from Jan 1978 to Feb 2026.

(Data obtained from: https://www.gold.org/goldhub/data/gold-prices)

Gold is one of the most widely tracked commodities globally and it is usually used as a store of value and a hedge against inflation.

My goal behind this project is to analyse the trend in the gold price series and produce a forecast using the Prophet forecasting system.

2. Loading the Data

First we load the libraries which are needed and then read the gold price data from the Excel file we have from the website: https://www.gold.org/goldhub/data/gold-prices.

We extract the date column and the GBP price column, and from those we remove any rows with missing values.

Due to there being a disclaimer sheet and multiple header rows, I used ‘sheet = “Monthly_Avg”’ and ‘skip = 3’ to read the data directly.

library(readxl)
library(prophet)

gold_raw <- read_excel("data/gold.xlsx", sheet = "Monthly_Avg", skip = 3)

gold_gbp <- data.frame(ds = as.Date(gold_raw[[1]]), y = as.numeric(gold_raw[["GBP"]]))

gold_gbp <- gold_gbp[!is.na(gold_gbp$ds) & !is.na(gold_gbp$y), ]

head(gold_gbp)
##           ds        y
## 1 1978-01-31 104.6260
## 2 1978-02-28 113.3210
## 3 1978-03-31 122.5497
## 4 1978-04-28 118.7907
## 5 1978-05-31 115.4330
## 6 1978-06-30 125.1719
summary(gold_gbp$y)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   104.6   219.0   264.0   580.8   879.6  3697.5
range(gold_gbp$ds)
## [1] "1978-01-31" "2026-02-27"

The summary statistics here give us a quick overview of the scale of the series before diving deeper into the analysis and the range function used help us get an overview of the date range of the data we are working with, so in this case it helps us see that the series runs monthly from 1978 to 2026.

3. Exploratory Analysis

Before beginning the forecast we start by checking the trend of the raw time series over the period of the data.

plot(gold_gbp$ds, gold_gbp$y,
     type = "l",
     main = "Monthly Gold Price in GBP per troy ounce",
     xlab = "Year",
     ylab = "Price in GBP",
     col = "darkgoldenrod")

The plot as seen here shows a strong upward trend over the period of the data, particularly a dramatic rise from 2005 onwards.

We also see peaks at around 1980 and 2011 meaning that the series is shaped also by periods of economic uncertainty and changing market conditions rather than just being a constant rise, which is naturally expected for such a relied upon commodity.

3.1 Measuring the trend

We fit a simple linear regression to measure the average rate of price increase over time.

gold_trend <- lm(y ~ as.numeric(ds), data = gold_gbp)
summary(gold_trend)
## 
## Call:
## lm(formula = y ~ as.numeric(ds), data = gold_gbp)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -458.27 -251.43  -41.36  200.90 2349.66 
## 
## Coefficients:
##                  Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    -443.99558   36.68994  -12.10   <2e-16 ***
## as.numeric(ds)    0.08736    0.00287   30.44   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 350.4 on 576 degrees of freedom
## Multiple R-squared:  0.6166, Adjusted R-squared:  0.616 
## F-statistic: 926.4 on 1 and 576 DF,  p-value: < 2.2e-16

The regression fitted here helps us confirm that the overall direction of the series overtime is in a positive direction, indicating that gold prices on average have increased for the time period we obtained the data for.

⚠️ Extra The slope coefficient is in GBP per day since ‘ds’ is stored as a date in days.

4. Forecasting with Prophet

We fit a prophet model to the data and forecast it 2 years(24 months) ahead. Using Meta’s Prophet model helps us in this case, as Prophet is a forecasting model primarily used for economic and financial series where changes in growth pattern are seen over time. This reflects what we see with our gold price series where we have a long term upward trend and changing patterns making this a useful tool for our analysis.

gold_model <- prophet(gold_gbp)

future_dates <- make_future_dataframe(gold_model, periods = 24, freq = "month")
gold_forecast <- predict(gold_model, future_dates)

4.1 The Forecast Plot

plot(gold_model, gold_forecast,
     xlab = "Year",
     ylab = "Gold Price in GBP")

The black dots in the forecast are the observed monthly prices and the blue line is prophet’s fitted model, and the shaded region is the uncertainty interval around the forecast.

4.2 Components Plot

Prophet decomposes the series into separate components.

prophet_plot_components(gold_model, gold_forecast)

The trend component here confirms the strong long-run increase in gold prices and the seasonal component shows any recurring patterns that prophet has identified across the period that we have.

tail(gold_forecast[, c("ds", "yhat","yhat_lower", "yhat_upper")], 12)
##             ds     yhat yhat_lower yhat_upper
## 591 2027-03-27 2293.956   2112.090   2478.961
## 592 2027-04-27 2341.953   2139.462   2541.345
## 593 2027-05-27 2428.751   2239.082   2610.213
## 594 2027-06-27 2370.408   2174.151   2563.353
## 595 2027-07-27 2472.394   2287.051   2660.274
## 596 2027-08-27 2502.171   2323.810   2709.451
## 597 2027-09-27 2389.815   2190.157   2577.802
## 598 2027-10-27 2386.675   2186.634   2579.012
## 599 2027-11-27 2596.826   2402.521   2797.180
## 600 2027-12-27 2310.809   2102.702   2510.884
## 601 2028-01-27 2591.732   2405.317   2789.195
## 602 2028-02-27 2564.203   2374.028   2755.335

Our table above shows the final months of the forecast going till February 2028.

5. Conclusion

In this project I use Meta’s Prophet to analyse and forecast monthly gold prices in GBP based on the data I obtained from https://www.gold.org/goldhub/data/gold-prices. The data I gathered from the website included gold prices from 1978 to 2026 and has shown a clear long-run upward trend in the prices, with some periods of significant rise especially after 2005.

Prophet managed to produce a 2 year forecast that extended into 2028 and also separated the series into components to aid our analysis and forecasting.