IMF Datatools

Learn how to install IMF Datatools and access data in R. IMF Datatools is a Python library that provides access to various internal and external data sources, which you can use directly in R.

Pre-requisites

Since IMF Datatools is Python based, we first need download Python 3.11 or above from the IMF Software Center and install our Python library.

After you have downloaded Python 3.11 or the latest version from the IMF Software Center, open the Command Prompt. You can load this by typing “cmd” in the Windows search option, as shown below.

In the command prompt, type the following command to install Datatools.

python \\ecnswn12p\ems_shared\pub\datatools\installer.py dev

You should generate something similar to the following message when the installation is complete.

Loading the Python Interpreter

After Python 3.11 is downloaded and Datatools is installed, we need to load it into R Studio. To use IMF Datatools in RStudio, you need to set the location of your Python interpreter.

In the menu tab of R Studio, go to Tools, Global Options, choose Python and then select the interpreter from your computer. When you click select, it should automatically populate under system after download. Click Apply and OK.

Your R session will likely need to be restarted to ensure the changes take into effect. This process only needs to be done once.

Loading additional packages

To bridge the communication between R and Python, you will also need to install and load the reticulate package, only once.

#install.packages("reticulate")
library(reticulate)

Handling Dates in Reticulate

When using the reticulate package to work with IMF Datatools, it is important to note that reticulate interprets dates in UTC time by default. This can lead to incorrect date stamps when downloading data if your system time is set to a different timezone.

To prevent this issue, you must set your system timezone to UTC before retrieving data. You can do this in R by running:

Sys.setenv(TZ = "UTC")

Lastly, you will need to import the sys module and the IMF Datatools library for calling from R.

sys <- import("sys")
imf_datatools  <-  import("imf_datatools")

You should now be set up to use IMF Datatools in R Studio.

Further documentation on IMF Datatools can also be found at this link.

Datasets available in IMF Datatools

Understanding the available data

IMF Datatools has direct access to a plethora of internal and external databases like Haver, OECD, and more. For exploratory work, you can view all the databases or import a specific database.

Utilizing the function imf_datatools$ in your console, you are interacting with an object which allows you to navigate available Datatools utilities using the $ operator. This will trigger an auto-complete pop-up showing the available modules (e.g., external data utilities, internal tools, metadata helpers).

With this information, you can then import a specific library under IMF Datatools, e.g., OECD. These “libraries” act as connectors that contain multiple functions for accessing data, metadata, and reference tables.

#Import a specific library under IMF Datatools, e.g., CEIC
imf_ceic_utilities <- imf_datatools$ceic_utilities

Within that library, you can then explore the functions within to get data, country codes, metadata, and more. Each utility typically includes functions to list available datasets, retrieve series, map country identifiers, and inspect metadata. You would explore this functionality by also utilizing the $ sign.

#You can then look at the functionality 
imf_ceic_utilities$

At this stage, you can explore functions that:

  • List available datasets or series

  • Retrieve time series data

  • Return country or entity code mappings

  • Expose metadata and documentation

After exploring the available connectors, we can now use them to pull actual datasets into our R session for analysis.

Using the datasets available in IMF Datatools

Let’s now download some series directly from these databases.

Using Haver data

For Haver data, make sure to specify the series and the database, such as GDP@USECON.

#Download Haver series for one country 
df  <-  imf_datatools$get_haver_data('GDP@USECON')

#Quickly glance at the tail end of the data
tail(df)
           GDP@USECON
2025-01-01    30042.1
2025-04-01    30485.7
2025-07-01    31098.0
2025-10-01    31422.5
2026-01-01    31865.7
2026-04-01    32486.1

You can also download multiple series in one command, but make sure they have compatible scales.

#Download multiple series in one command
df <- imf_datatools$get_haver_data(c('PJ4@USECON', 'PCUP@USECON'))

#Quickly glance at the tail end of the data
tail(df)
           PJ4@USECON PCUP@USECON
2026-02-01        0.5         0.3
2026-03-01        0.8         0.9
2026-04-01        1.1         0.6
2026-05-01        0.5         0.5
2026-06-01       -0.1        -0.4
2026-07-01        0.0         0.1

If you need more info on the scales, you can easily browse the metadata for an indicator.

#Obtain details on the metadata for a particular series
metadata <- imf_datatools$haver_utilities$get_haver_metadata('GDP@USECON')

#Quickly glance at the tail end the metadata
tail(metadata)
    database  startdate    enddate frequency
gdp   usecon 1947-03-31 2026-06-30         Q
                              descriptor numobs         datetimemod magnitude
gdp Gross Domestic Product (SAAR, Bil.$)    318 2026-08-26 12:31:00         9
    decprecision diftype aggtype datatype group geography1 geography2
gdp            1       0     AVG      US$   N01        111           
    shortsource                  longsource
gdp         BEA Bureau of Economic Analysis

Using World Bank data

You can also access World Bank data, but make sure you denote country abbreviation instead of IMF country code.

# Download series for population in USA from World Bank DAta
df  <-  imf_datatools$get_worldbank_data('SP.POP.TOTL', 'USA')

#Quickly glance at the tail end of the data
tail(df)
           USA.SP.POP.TOTL
2020-01-01       331578104
2021-01-01       332100166
2022-01-01       333996304
2023-01-01       336755052
2024-01-01       340003797
2025-01-01       341784857

Using iData

The new Fund‐wide iData (2025) replaces EcOS, EDI, and can be accessed via the reticulate package. This is slightly different than the other sites as it includes both publicly available and private datasets. Let’s explore those below.

In order to access publicly available datasets, you need to specify that no token is needed via stating “FALSE” below. Let’s explore how to see the public datasets in iData below.

#alias the imported Python module for brevity of calls
dt <- imf_datatools

#Public datasets (no token needed)
dt$idata_utilities$PRIVATE <- FALSE
head(dt$idata_utilities$get_databases())
                                                                              name
IMF.RES.WEO:WEO_LIVE_2021_APR_VINTAGE                          WEO Live 2021 April
ESTAT:ERT_BIL_EUR_M                         Euro/ECU exchange rates - monthly data
IMF.RES.GEE:GEE_LIVE_2026_JAN_FINAL_VINTAGE            GEE Live 2026 January Final
IMF.RES.GEE:GEE_LIVE_2016_APR_GAS3_VINTAGE                GEE Live 2016 April GAS3
IMF.RES.GEE:GEE_LIVE_2018_APR_FINAL_VINTAGE              GEE Live 2018 April Final
IMF.RES.WEO:WEO_LIVE_2018_JAN_VINTAGE                        WEO Live 2018 January
                                              Agency ID
IMF.RES.WEO:WEO_LIVE_2021_APR_VINTAGE       IMF.RES.WEO
ESTAT:ERT_BIL_EUR_M                               ESTAT
IMF.RES.GEE:GEE_LIVE_2026_JAN_FINAL_VINTAGE IMF.RES.GEE
IMF.RES.GEE:GEE_LIVE_2016_APR_GAS3_VINTAGE  IMF.RES.GEE
IMF.RES.GEE:GEE_LIVE_2018_APR_FINAL_VINTAGE IMF.RES.GEE
IMF.RES.WEO:WEO_LIVE_2018_JAN_VINTAGE       IMF.RES.WEO
                                                                Resource ID
IMF.RES.WEO:WEO_LIVE_2021_APR_VINTAGE             WEO_LIVE_2021_APR_VINTAGE
ESTAT:ERT_BIL_EUR_M                                           ERT_BIL_EUR_M
IMF.RES.GEE:GEE_LIVE_2026_JAN_FINAL_VINTAGE GEE_LIVE_2026_JAN_FINAL_VINTAGE
IMF.RES.GEE:GEE_LIVE_2016_APR_GAS3_VINTAGE   GEE_LIVE_2016_APR_GAS3_VINTAGE
IMF.RES.GEE:GEE_LIVE_2018_APR_FINAL_VINTAGE GEE_LIVE_2018_APR_FINAL_VINTAGE
IMF.RES.WEO:WEO_LIVE_2018_JAN_VINTAGE             WEO_LIVE_2018_JAN_VINTAGE
                                            Latest Version
IMF.RES.WEO:WEO_LIVE_2021_APR_VINTAGE                1.0.0
ESTAT:ERT_BIL_EUR_M                                    1.0
IMF.RES.GEE:GEE_LIVE_2026_JAN_FINAL_VINTAGE          1.0.0
IMF.RES.GEE:GEE_LIVE_2016_APR_GAS3_VINTAGE           1.0.0
IMF.RES.GEE:GEE_LIVE_2018_APR_FINAL_VINTAGE          1.0.0
IMF.RES.WEO:WEO_LIVE_2018_JAN_VINTAGE                1.0.0
                                                                                     Unique ID
IMF.RES.WEO:WEO_LIVE_2021_APR_VINTAGE             IMF.RES.WEO:WEO_LIVE_2021_APR_VINTAGE(1.0.0)
ESTAT:ERT_BIL_EUR_M                                                   ESTAT:ERT_BIL_EUR_M(1.0)
IMF.RES.GEE:GEE_LIVE_2026_JAN_FINAL_VINTAGE IMF.RES.GEE:GEE_LIVE_2026_JAN_FINAL_VINTAGE(1.0.0)
IMF.RES.GEE:GEE_LIVE_2016_APR_GAS3_VINTAGE   IMF.RES.GEE:GEE_LIVE_2016_APR_GAS3_VINTAGE(1.0.0)
IMF.RES.GEE:GEE_LIVE_2018_APR_FINAL_VINTAGE IMF.RES.GEE:GEE_LIVE_2018_APR_FINAL_VINTAGE(1.0.0)
IMF.RES.WEO:WEO_LIVE_2018_JAN_VINTAGE             IMF.RES.WEO:WEO_LIVE_2018_JAN_VINTAGE(1.0.0)

You can also list your private datasets, which you have access to.

#Private datasets based on your access level
dt$idata_utilities$PRIVATE <- TRUE
head(dt$idata_utilities$get_databases())
                                                                              name
IMF.RES.WEO:WEO_LIVE_2021_APR_VINTAGE                          WEO Live 2021 April
ESTAT:ERT_BIL_EUR_M                         Euro/ECU exchange rates - monthly data
IMF.RES.GEE:GEE_LIVE_2026_JAN_FINAL_VINTAGE            GEE Live 2026 January Final
IMF.RES.GEE:GEE_LIVE_2016_APR_GAS3_VINTAGE                GEE Live 2016 April GAS3
IMF.RES.GEE:GEE_LIVE_2018_APR_FINAL_VINTAGE              GEE Live 2018 April Final
IMF.RES.WEO:WEO_LIVE_2018_JAN_VINTAGE                        WEO Live 2018 January
                                              Agency ID
IMF.RES.WEO:WEO_LIVE_2021_APR_VINTAGE       IMF.RES.WEO
ESTAT:ERT_BIL_EUR_M                               ESTAT
IMF.RES.GEE:GEE_LIVE_2026_JAN_FINAL_VINTAGE IMF.RES.GEE
IMF.RES.GEE:GEE_LIVE_2016_APR_GAS3_VINTAGE  IMF.RES.GEE
IMF.RES.GEE:GEE_LIVE_2018_APR_FINAL_VINTAGE IMF.RES.GEE
IMF.RES.WEO:WEO_LIVE_2018_JAN_VINTAGE       IMF.RES.WEO
                                                                Resource ID
IMF.RES.WEO:WEO_LIVE_2021_APR_VINTAGE             WEO_LIVE_2021_APR_VINTAGE
ESTAT:ERT_BIL_EUR_M                                           ERT_BIL_EUR_M
IMF.RES.GEE:GEE_LIVE_2026_JAN_FINAL_VINTAGE GEE_LIVE_2026_JAN_FINAL_VINTAGE
IMF.RES.GEE:GEE_LIVE_2016_APR_GAS3_VINTAGE   GEE_LIVE_2016_APR_GAS3_VINTAGE
IMF.RES.GEE:GEE_LIVE_2018_APR_FINAL_VINTAGE GEE_LIVE_2018_APR_FINAL_VINTAGE
IMF.RES.WEO:WEO_LIVE_2018_JAN_VINTAGE             WEO_LIVE_2018_JAN_VINTAGE
                                            Latest Version
IMF.RES.WEO:WEO_LIVE_2021_APR_VINTAGE                1.0.0
ESTAT:ERT_BIL_EUR_M                                    1.0
IMF.RES.GEE:GEE_LIVE_2026_JAN_FINAL_VINTAGE          1.0.0
IMF.RES.GEE:GEE_LIVE_2016_APR_GAS3_VINTAGE           1.0.0
IMF.RES.GEE:GEE_LIVE_2018_APR_FINAL_VINTAGE          1.0.0
IMF.RES.WEO:WEO_LIVE_2018_JAN_VINTAGE                1.0.0
                                                                                     Unique ID
IMF.RES.WEO:WEO_LIVE_2021_APR_VINTAGE             IMF.RES.WEO:WEO_LIVE_2021_APR_VINTAGE(1.0.0)
ESTAT:ERT_BIL_EUR_M                                                   ESTAT:ERT_BIL_EUR_M(1.0)
IMF.RES.GEE:GEE_LIVE_2026_JAN_FINAL_VINTAGE IMF.RES.GEE:GEE_LIVE_2026_JAN_FINAL_VINTAGE(1.0.0)
IMF.RES.GEE:GEE_LIVE_2016_APR_GAS3_VINTAGE   IMF.RES.GEE:GEE_LIVE_2016_APR_GAS3_VINTAGE(1.0.0)
IMF.RES.GEE:GEE_LIVE_2018_APR_FINAL_VINTAGE IMF.RES.GEE:GEE_LIVE_2018_APR_FINAL_VINTAGE(1.0.0)
IMF.RES.WEO:WEO_LIVE_2018_JAN_VINTAGE             IMF.RES.WEO:WEO_LIVE_2018_JAN_VINTAGE(1.0.0)

Once you’ve picked a database (e.g. "IMF.STA:CPI"), you can also check its structure.

  • get_dimensions() lists all the ways you can slice your data, i.e., by country, frequency etc.
dims <- dt$idata_utilities$get_dimensions("IMF.STA:CPI")
print(dims)

  • get_dimension_values() this function provides the full list of entries within a specific dimension, e.g., Country.

    vals <- dt$idata_utilities$get_dimension_values("IMF.STA:CPI", "COUNTRY")
    head(vals)

Retrieving a series

Once you have itentified your dataset and explored its dimensions you can build a query by joining dimension codes with period. Leave the key specifications empty to include all values as shown below.

# Example: CPI level for USA & JPN monthly (_T = level, M = monthly)
key <- "USA+JPN.CPI._T..M"
df  <- dt$idata_utilities$get_idata_data("IMF.STA:CPI", key)
tail(df)

  • To obtain data in long format, add longformat = TRUE.

    # Long
    key <- "USA+JPN.CPI._T..M"
    lf <- dt$idata_utilities$get_idata_data("IMF.STA:CPI", key, longformat = TRUE)
    tail(lf)

  • To pivot by a dimension (e.g. COUNTRY), use panel = "COUNTRY"

    # Panel by country
    pf <- dt$idata_utilities$get_idata_data("IMF.STA:CPI", key, panel = "COUNTRY")
    tail(pf)

Using Bloomberg data

In the previous section, we used iData to retrieve IMF datasets. The same approach can be used to retrieve Bloomberg Data License series.

Bloomberg data that was previously accessed through EcOS should now be retrieved through iData. If you have historical files using the function get_ecos_bloomberg_data() and receive a connection error referencing `ecossdmx`, this usually means the function is still pointing to the old EcOS SDMX service rather than the current iData route.

To access Bloomberg data, we now reference it in iData through the database IMF.CSF:BBGDL. To retrieve a Bloomberg series, you need to build a query key using three parts:

Dimension Meaning Example
TICKER Bloomberg ticker code selected from the TICKER dimension
FIELD Bloomberg market field PX_LAST
FREQUENCY Data frequency D for daily or M for monthly

The key must follow this structure:

"TICKER.FIELD.FREQUENCY"

For example, to retrieve a daily Bloomberg series, we first define the Bloomberg database and inspect the available dimensions.

# Bloomberg Data License database in iData
bbg_db <- "IMF.CSF:BBGDL"

# Check the dimensions required for Bloomberg queries
dims <- dt$idata_utilities$get_dimensions(bbg_db)
print(dims)
           Description Dimension Order
TICKER          Ticker               0
FIELD     Market Field               1
FREQUENCY    Frequency               2

The Bloomberg database requires three dimensions: TICKER, FIELD, and FREQUENCY. You can then retrieve the available values for each dimension.

# Retrieve available Bloomberg dimension values
tickers <- dt$idata_utilities$get_dimension_values(bbg_db, "TICKER")
fields  <- dt$idata_utilities$get_dimension_values(bbg_db, "FIELD")
freqs   <- dt$idata_utilities$get_dimension_values(bbg_db, "FREQUENCY")

# View available fields and frequencies
fields
                                          Name
PX_ASK                               Ask Price
YLD_YTM_ASK              Ask Yield To Maturity
PX_BID                               Bid Price
YLD_YTM_BID              Bid Yield To Maturity
CUR_MKT_CAP                 Current Market Cap
PX_HIGH                             High Price
PX_LAST                             Last Price
PX_LOW                               Low Price
YLD_ANNUAL_MID                Mid Annual Yield
PX_MID                               Mid Price
YLD_YTM_MID              Mid Yield To Maturity
YLD_CNV_MID      Mid Yield To Worst Convention
PX_OPEN                             Open Price
PE_RATIO            Price Earnings Ratio (P/E)
PX_TO_BOOK_RATIO           Price to Book Ratio
PX_SETTLE                            PX_SETTLE
VOLATILITY_10D               Volatility 10 Day
VOLATILITY_180D             Volatility 180 Day
VOLATILITY_30D               Volatility 30 Day
PX_VOLUME                               Volume
freqs
     Name
D   Daily
M Monthly

For Bloomberg tickers, it is useful to search the ticker dimension first. The example below searches for VIX-related tickers.

# Search for VIX-related Bloomberg tickers
vix_tickers <- tickers[
  grepl("VIX", rownames(tickers), ignore.case = TRUE) |
    grepl("VIX", tickers$Name, ignore.case = TRUE),
  ,
  drop = FALSE
]

vix_tickers
                                                          Name
SRVIX_INDEX                Cboe Interest Rate Volatility Index
VIX_INDEX      Chicago Board Options Exchange Volatility Index
CVIX_INDEX                   Deutsche Bank FX Volatility Index
SPBMVVIX_INDEX                                 S&P/BMV IPC VIX
VIX3M_INDEX                                        VIX3M Index

Use the ticker code from the row name, then combine it with the field and frequency. In this example, we use PX_LAST for last price and D for daily frequency.

# Use the row name as the ticker code
ticker_code <- rownames(vix_tickers)[vix_tickers$Name == "VIX3M Index"]

# Choose the Bloomberg field and frequency
field_code <- "PX_LAST"
freq_code  <- "D"

# Build the iData query key
key <- paste(ticker_code, field_code, freq_code, sep = ".")
key
[1] "VIX3M_INDEX.PX_LAST.D"

Now retrieve the Bloomberg data.

# Retrieve daily Bloomberg data
df <- dt$idata_utilities$get_idata_data(
  bbg_db,
  key,
  longformat = TRUE
)

tail(df)
          TICKER   FIELD FREQUENCY      dates OBS_VALUE
6196 VIX3M_INDEX PX_LAST         D 2026-08-25     18.21
6197 VIX3M_INDEX PX_LAST         D 2026-08-26     17.99
6198 VIX3M_INDEX PX_LAST         D 2026-08-27     17.56
6199 VIX3M_INDEX PX_LAST         D 2026-08-28     17.48
6200 VIX3M_INDEX PX_LAST         D 2026-08-31     17.53
6201 VIX3M_INDEX PX_LAST         D 2026-09-01     18.33

IMF Datatools makes it easy to browse, inspect, and retrieve IMF datasets in R.