India's real policy rate from RBI repo and CPI data, done carefully
In this article (8 sections)
Related programme: the Data Science course (6 months; ₹1,30,000 (inclusive of GST) · EMI from ₹5,000/month).
The real policy rate, the repo rate minus inflation, is the number economists use to judge whether monetary policy is tight or loose. Building it yourself from primary data is a compact data science project. You will align a step-function policy rate with a monthly price index, handle a CPI base-year change, and show that the answer depends on which inflation measure you subtract. You finish with a chart and a short argument about what "real rate" should mean, backed by your own numbers.
Two primary sources
- Policy rates: RBI's Database on Indian Economy (DBIE). Its menus include Indicators, Statistics, Publications and an SDMX data query. When we checked in September 2026, the site's ticker showed the policy repo rate at 5.25%, the standing deposit facility rate at 5.00%, CRR at 3.00% and SLR at 18.00%. Find the policy rate series and check the downloaded file's header, because we did not confirm its exact column names.
- Inflation: MoSPI's eSankhyiki CPI page. The current series is base 2024, with columns including Year, Month, State, Sector, Index, Inflation (%) and an Imputation flag. Use State = All India, Sector = Combined, and the General index.
Cross-check each repo change against RBI's monetary policy press releases. A policy rate is a list of decisions with effective dates. If your monthly series changes in the wrong month, every real-rate figure after it is wrong too.
Why this is a good data science interview piece
Treasury desks, bank ALM teams, NBFC risk functions and economic research teams all reason about real rates. The project tests things a model-building course often skips: time alignment, a series break and a measurement choice that changes the conclusion. Presenting three definitions side by side, and saying which you prefer and why, is exactly the judgement interviewers look for.
Three definitions to compare
| Definition | Formula | What it answers |
|---|---|---|
| Ex-post, current | repo(t) − CPI inflation(t) | How tight policy looks against today's inflation |
| Ex-post, lagged | repo(t) − CPI inflation(t−1) | The same, using only data available at the decision |
| Forward-looking proxy | repo(t) − realised CPI inflation over the next 12 months | A hindsight stand-in for expected inflation |
The third is not a forecast, because it uses future data. Label it clearly as a hindsight benchmark. If you can source a published inflation expectations measure, such as the RBI's household survey, add it as a fourth line, and check its format first.
Code: build the monthly panel on synthetic inputs
The decision dates, rates and inflation values below are synthetic. They illustrate the method only and are not RBI or MoSPI history.
import pandas as pd
import numpy as np
# Policy decisions: effective date and new repo rate (synthetic)
decisions = pd.DataFrame({
"effective": pd.to_datetime(["2024-02-08", "2024-12-06", "2025-04-09", "2025-06-06", "2026-02-06"]),
"repo": [6.50, 6.50, 6.25, 5.75, 5.25],
})
months = pd.period_range("2024-03", "2026-08", freq="M")
panel = pd.DataFrame({"month": months})
panel["month_end"] = panel["month"].dt.to_timestamp(how="end").dt.normalize()
# Rate in force at the end of each month: merge_asof needs both sides sorted
panel = pd.merge_asof(panel.sort_values("month_end"), decisions.sort_values("effective"),
left_on="month_end", right_on="effective", direction="backward")
rng = np.random.default_rng(8)
panel["cpi_yoy"] = np.round(4.5 + np.cumsum(rng.normal(0, 0.35, len(panel))) * 0.5, 2)
panel.loc[5, "cpi_yoy"] = np.nan # a missing release
panel["real_current"] = panel["repo"] - panel["cpi_yoy"]
panel["real_lagged"] = panel["repo"] - panel["cpi_yoy"].shift(1)
panel["fwd_12m_infl"] = panel["cpi_yoy"].shift(-12) # hindsight only
panel["real_hindsight"] = panel["repo"] - panel["fwd_12m_infl"]
print(panel[["month", "repo", "cpi_yoy", "real_current", "real_lagged", "real_hindsight"]].head(8))
print("months where the definitions disagree on sign:",
int(((np.sign(panel["real_current"]) != np.sign(panel["real_hindsight"]))
& panel["real_hindsight"].notna() & panel["real_current"].notna()).sum()))merge_asof with direction="backward" is the right tool for a step function. It attaches the most recent decision on or before each month end. A plain left join on month would miss any month with no decision, which is most of them. Leave the missing CPI month as missing. Filling it would invent a data point.
Handling the CPI base change
The current CPI series has base 2024. Earlier releases used an older base. Two consequences:
- 1For long histories, splice the published inflation rates rather than the index levels. Record the splice month in your README.
- 2Expect a short overlap, or none, between series. Do not compute inflation across the join from mixed index levels.
If you only have base-2024 data, keep the project to that span. A shorter series you can defend is better than a longer one you cannot.
Analysis plan
- Build the monthly panel for as long a span as your data honestly supports.
- Plot the three real-rate definitions on one chart, with repo changes marked as vertical lines.
- Report the months in which the definitions disagree on the sign of the real rate, which is when "tight or loose" is genuinely contested.
- Test sensitivity: use the Urban index instead of Combined, and core inflation if you can build or source it. Report how much each choice moves the average real rate.
Deliverables
- One chart with three lines, clearly labelled, including the words "hindsight benchmark" on the third.
- A table of monthly repo, inflation and each real-rate definition, downloadable as CSV.
- A decision-date check table: each RBI press release date against the month your panel changes.
- A README with sources, download dates, series identifiers, the alignment rule, splice method and limitations.
What you will be asked
- Why
merge_asofand not a join on month? - What is wrong with using future inflation, and why include it anyway?
- How would you get a real-time version that uses only information available at each policy meeting?
- Your chart shows a negative real rate for six months. Does that mean policy was loose?
- What changes if you use CPI excluding food and fuel?
The same inflation source drives the Delhi vs all-India CPI project. Time alignment and careful measurement choices come up throughout our Data Science programme.
Frequently asked questions
What is the real repo rate?
It is the RBI's policy repo rate minus a measure of inflation. Subtracting current CPI inflation gives a backward-looking real rate. Subtracting an inflation forecast or expectation gives a forward-looking one, which is closer to what policy is meant to target.
Where do I get the repo rate history?
RBI's Database on Indian Economy at data.rbi.org.in/DBIE carries policy rates alongside other statistics. RBI's own press releases record each monetary policy decision, which lets you check the dates of changes.
Pankit Kumar has 10 years in Data Science & AI, building and shipping production systems in regulated pharma and clinical environments. He is a freelance trainer at Boston Institute of Analytics, AnalytixLabs and Scaler, and has taught this material to thousands of working professionals.
This article is part of our Data Science programme — 6 months. From data foundations to machine learning, deep learning and deployment.
Explore Data Science