Forecasting Exchange Rates
Data Science

Forecasting Exchange Rates

Time Series data is vastly used across various domains for forecasting. Forecasting the future can be beneficial for the analysts and management in making better calculated decisions to maximise returns and minimise risks.

In this article,we will be demonstrating how we can forecast exchange rates. If you are new to finance and want to understand what exchange rates are then please go through: How do exchange rates work?

It provides a basic overview of market data. Exchange rates are dependent on a range of factors such as supply and demand, government policies, country’s growth rates etc.

Forecasting Exchange Rates

Recently, a number of technological advancements have been introduced that can forecast future time points quickly, efficiently and accurately. To get a detailed understanding on how Time Series Analysis and forecasting is done, please go through this article: Time Series Forecasting

After completing this tutorial, you will know:

  • How to scrape the exchange rates from
  • What is fbProphet, and how to use it
  • How to build your own forecasting model using fbProphet.

Scraping Data from the web

Importing the libraries:

import pandas as pd
import datetime
from datetime import timedelta, date

Method for yielding date range:

def daterange(start_date, end_date):
     for n in range(int ((end_date - start_date).days)):
         yield start_date + timedelta(n)

Setting the start date & end date:

Here, we are setting the start date as 1st September, 2019 and end date as today's date, so that we can fetch the entire data within this range.

start_date = date(2019, 9, 1)
end_date =

Defining Pandas Dataframe and fetching all the data for Hong Kong Dollars to Any other currency:

I was concerned about Hong Kong Dollars to Indian Rupee conversion rates, hence I have used "HKD", you can use whatever you feel like

df = pd.DataFrame()
for single_date in daterange(start_date, end_date):
    dfs = pd.read_html(f'{single_date.strftime("%Y-%m-%d")}')[0]
    dfs['Date'] = single_date.strftime("%Y-%m-%d")
    df = df.append(dfs)

Defining the Dataframe columns:

df.columns = ['Currency code', 'Currency name', 'Units per HKD', 'HKD per Unit', 'Date']
Extracting the currency for which we want to forecast:

Let say, we are trying to forecast the conversion rate of Hong Kong Dollars to Indian Rupee, then from the extracted data, we use a filter based on the Currency Code as "INR", so that just Indian Rupee data is extracted.

inr_df = df[df['Currency code'] == 'INR']

Check the data:



Plotting the graph:

inr_df.plot(x='Date', y='Units per HKD', figsize=(12, 8)

That's how the graph looks like for almost 13 months ranging from 1/09/2018 to 11/10/2019, accordingly the start date and end dates can be changed to fetch the entire data.


 What is fbProphet?

You can read about Facebook Prophet here: Click here


pip install pystan
pip install fbprophet

If the above steps, doesn't work, then try the below code in Anaconda Prompt:

conda install -c conda-forge fbprophet 

Forecasting - Facebook Prophet

Prophet follows the sklearn model API. We create an instance of the Prophet class and then call it's fit and predict methods.

You can read about the Prophet API's here: Click Here

First we'll import the data

import pandas as pd
from fbprophet import Prophet 
import plotly.graph_objs as go
import plotly.offline as py
import numpy as np
df= inr_df.drop(['Unnamed: 0', 'Currency code', 'Currency name', 'HKD per Unit'], axis=1)
df = df.rename(columns={'Units per HKD': 'y', 'Date': 'ds'})
df['ds'] =  pd.to_datetime(df['ds'], format='%d/%m/%Y')

Now, we perform a log transformation, just to make the time series stationary, and after forecasting is done, we can do the inverse transformation.

# to save a copy of the original'll see why shortly. 
df['y_orig'] = df['y'] 
# log-transform of y
df['y'] = np.log(df['y'])

We fit the model by instantiating a new Prophet object. Any settings to the forecasting procedure are passed into the constructor. Then you call its fit method and pass in the historical dataframe. Fitting should take 1-5 seconds.

#instantiate Prophet
model = Prophet()

Predictions are then made on a dataframe with a column ds containing the dates for which a prediction is to be made. You can get a suitable dataframe that extends into the future a specified number of days using the helper method Prophet.make_future_dataframe. By default it will also include the dates from the history, so we will see the model fit as well.

future_data = model.make_future_dataframe(periods=30, freq = 'D')

The predict method will assign each row in future a predicted value which it names yhat. If you pass in historical dates, it will provide an in-sample fit. The forecast object here is a new dataframe that includes a column yhat with the forecast, as well as columns for components and uncertainty intervals.

forecast_data = model.predict(future_data)
forecast_data[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail(5)

Inverse transformation (Using exponential) to get back the data to the original format.
# make sure we save the original forecast data
forecast_data_orig = forecast_data 
forecast_data_orig['yhat'] = np.exp(forecast_data_orig['yhat'])
forecast_data_orig['yhat_lower'] = np.exp(forecast_data_orig['yhat_lower'])
forecast_data_orig['yhat_upper'] = np.exp(forecast_data_orig['yhat_upper'])
fig = model.plot(forecast_data_orig)
If you want to see the forecast components, you can use the Prophet.plot_components method. By default you’ll see the trend, yearly seasonality, and weekly seasonality of the time series. If you include holidays, you’ll see those here, too.
fig2 = model.plot_components(forecast_data_orig)

From the time series component graph, it's clear that there's an increasing trend, which means the value of HKD is somehow increasing linearly. Apart from that, it's quite visible that the seasonality is high during Tuesday's & Wednesday's (I Hope you figured out that these are the best days in the week for a money transfer - cheers!!)

Copy the log-transformed data to another column


An interactive figure of the forecast can be created with plotly. You will need to install plotly separately, as it will not by default be installed with fbprophet

# Python
from fbprophet.plot import plot_plotly
import plotly.offline as py
fig = plot_plotly(model, forecast_data_orig)  # This returns a plotly Figure

If you want an offline graph, plotly provives an API named "offline", which we have already imported in the beginning of the tutorial, and we can use that feature to plot it in an interactive offline graph and can analyse deeply. The offline graph would open in a separate tab in your browser and would look like the below graph:

final_df = pd.DataFrame(forecast_data_orig)
actual_chart = go.Scatter(y=df["y_orig"], name= 'Actual')
predict_chart = go.Scatter(y=final_df["yhat"], name= 'Predicted')
predict_chart_upper = go.Scatter(y=final_df["yhat_upper"], name= 'Predicted Upper')
predict_chart_lower = go.Scatter(y=final_df["yhat_lower"], name= 'Predicted Lower')
py.plot([actual_chart, predict_chart, predict_chart_upper, predict_chart_lower])
Forecasting - Actual vs Predicted graph

The beauty of Facebook Prophet is that, it predicts a range i.e. Predicted upper & Predicted lower, and as you can see from the graph, the Actual data lies between the upper & lower range almost throughout the data, that's the accuracy of using this algorithm. Irrespective of the minor spikes, the prediction range carries the Actual data throughout the graph.

Adding to this, the above model is just the basic code of it, we can definitely fine tune by inserting holidays, understanding and changing the daily/weekly/monthly/yearly seasonality and various other factors.


I hope this document provides you the basic idea on Foreign exchange rate data scraping from, along with the time series forecasting of the same data (Hong Kong Dollars to Indian Rupee rates), keep exploring our other posts, cheers!!

Disclaimer: The scraping from data shown above is against XE Currency’s 
Terms of Use. Use the codes just for self learning & practice and not for business.

  • Zep Analytics
  • Mar, 05 2022

Add New Comments

Please login in order to make a comment.

Recent Comments

Be the first to start engaging with the bis blog.