0% found this document useful (0 votes)
9 views3 pages

USD to INR Forecasting Model

This document outlines a Python forecasting model for predicting the USD to INR exchange rate using various economic indicators and machine learning techniques. It includes data preprocessing, feature engineering, model training with Random Forest and Gradient Boosting regressors, and a dynamic monthly forecasting function. The final output is a bias-corrected forecast saved to an Excel file, targeting a specific mean exchange rate range.

Uploaded by

Prateek Lodha
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views3 pages

USD to INR Forecasting Model

This document outlines a Python forecasting model for predicting the USD to INR exchange rate using various economic indicators and machine learning techniques. It includes data preprocessing, feature engineering, model training with Random Forest and Gradient Boosting regressors, and a dynamic monthly forecasting function. The final output is a bias-corrected forecast saved to an Excel file, targeting a specific mean exchange rate range.

Uploaded by

Prateek Lodha
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

11/10/2025, 22:39 Python Forecasting Model

1 import pandas as pd
2 import numpy as np
3 from datetime import datetime
4 from [Link] import RandomForestRegressor, GradientBoostingRegressor
5 from [Link] import StandardScaler
6 from [Link] import r2_score, mean_squared_error
7 import warnings
8 [Link]('ignore')
9
10 # --------------------
11 # Settings
12 # --------------------
13 current_date = datetime(2025, 9, 1) # update if needed
14
15 # --------------------
16 # Load data
17 # --------------------
18 data = pd.read_csv('[Link]', encoding='utf-8-sig')
19 [Link] = [Link]()
20
21 # Map/rename columns expected by the script
22 columns_map = {
23 'Date': 'Date',
24 'Exchange Rate': 'USD_INR',
25 'India Repo Rate': 'INR_Interest_Rate',
26 'Fed Rate': 'USD_Interest_Rate',
27 'Crude Oil Prices': 'Oil_Price',
28 'USD Index DXY': 'Dollar_Index',
29 'India VIX': 'VIX',
30 'India Inflation Rate': 'India_Inflation',
31 'US Inflation Rate': 'US_Inflation',
32 'FPI Flow (INR)': 'FPI_Flow',
33 'India FX Reserves': 'FX_Reserves'
34 }
35
36 clean = [Link]()
37 for k, v in columns_map.items():
38 if k in [Link]:
39 clean[v] = data[k]
40
41 # Parse dates and clean percent columns
42 clean['Date'] = pd.to_datetime(clean['Date'])
43 for col in ['INR_Interest_Rate', 'USD_Interest_Rate', 'India_Inflation', 'US_Inflation']:
44 if col in [Link]:
45 clean[col] = clean[col].astype(str).[Link]('%', '').astype(float)
46
47 # Sort, fill and derive diffs
48 clean = clean.sort_values('Date').reset_index(drop=True)
49 clean['Interest_Rate_Diff'] = clean['INR_Interest_Rate'] - clean['USD_Interest_Rate']
50 clean['Inflation_Diff'] = clean['India_Inflation'] - clean['US_Inflation']
51 clean['Real_Interest_Diff'] = clean['Interest_Rate_Diff'] - clean['Inflation_Diff']
52 clean = [Link](method='ffill')
53
54 current_usd_inr = clean['USD_INR'].iloc[-1]
55
56 # --------------------
57 # Feature engineering
58 # --------------------
59 def fe(df):
60 df = [Link]()
61 df['MA_3'] = df['USD_INR'].rolling(3).mean()
62 df['MA_6'] = df['USD_INR'].rolling(6).mean()
63 df['MA_12'] = df['USD_INR'].rolling(12).mean()
64 df['Volatility_3'] = df['USD_INR'].rolling(3).std()
65 df['Volatility_6'] = df['USD_INR'].rolling(6).std()
66 df['USD_INR_Change_1M'] = df['USD_INR'] - df['USD_INR'].shift(1)
67 df['USD_INR_Change_3M'] = df['USD_INR'] - df['USD_INR'].shift(3)
68 df['USD_INR_Change_6M'] = df['USD_INR'] - df['USD_INR'].shift(6)
69 df['USD_INR_Pct_Change_1M'] = df['USD_INR'].pct_change(1) * 100
70 df['USD_INR_Pct_Change_3M'] = df['USD_INR'].pct_change(3) * 100
71 for lag in [1,2,3,6]:
72 df[f'USD_INR_Lag{lag}'] = df['USD_INR'].shift(lag)
73 df[f'Oil_Lag{lag}'] = df['Oil_Price'].shift(lag)
74 df[f'DXY_Lag{lag}'] = df['Dollar_Index'].shift(lag)
75 df['Oil_USD_Corr'] = df['Oil_Price'].rolling(12).corr(df['USD_INR'])
76 df['DXY_USD_Corr'] = df['Dollar_Index'].rolling(12).corr(df['USD_INR'])
77 df['VIX_USD_Corr'] = df['VIX'].rolling(12).corr(df['USD_INR'])
78 df['High_Vol_Regime'] = (df['Volatility_6'] > df['Volatility_6'].rolling(24).mean()).astype(int)
79 df['Strengthening_INR'] = (df['USD_INR_Change_3M'] < 0).astype(int)
80 df['High_Oil_Regime'] = (df['Oil_Price'] > df['Oil_Price'].rolling(12).mean()).astype(int)
81 df['Month'] = df['Date'].[Link]
82 df['Quarter'] = df['Date'].[Link]
83 df['Month_Sin'] = [Link](2*[Link]*df['Month']/12)
84 df['Month_Cos'] = [Link](2*[Link]*df['Month']/12)
85 df['Policy_Uncertainty'] = df['VIX'] * abs(df['Interest_Rate_Diff'])
86 df['Carry_Trade_Appeal'] = df['Real_Interest_Diff'] / df['VIX']
87 return df
88
89 clean = fe(clean)
90
91 # Feature list used by model
92 features = [
93 'USD_Interest_Rate','INR_Interest_Rate','Interest_Rate_Diff','Real_Interest_Diff',
94 'Oil_Price','Dollar_Index','VIX','India_Inflation','US_Inflation','Inflation_Diff',
95 'FPI_Flow','FX_Reserves',
96 'MA_3','MA_6','MA_12','Volatility_3','Volatility_6',

[Link] 1/3
11/10/2025, 22:39 Python Forecasting Model
97 'USD_INR_Change_1M','USD_INR_Change_3M','USD_INR_Change_6M',
98 'USD_INR_Pct_Change_1M','USD_INR_Pct_Change_3M',
99 'USD_INR_Lag1','USD_INR_Lag2','USD_INR_Lag3','USD_INR_Lag6',
100 'Oil_Lag1','Oil_Lag3','DXY_Lag1','DXY_Lag3',
101 'Oil_USD_Corr','DXY_USD_Corr','VIX_USD_Corr',
102 'High_Vol_Regime','Strengthening_INR','High_Oil_Regime',
103 'Month_Sin','Month_Cos','Quarter','Policy_Uncertainty','Carry_Trade_Appeal'
104 ]
105
106 # --------------------
107 # Train models
108 # --------------------
109 train = [Link]().reset_index(drop=True)
110 X = train[features]
111 y = train['USD_INR']
112
113 scaler = StandardScaler()
114 X_scaled = scaler.fit_transform(X)
115
116 rf = RandomForestRegressor(n_estimators=300, max_depth=15, min_samples_split=3, min_samples_leaf=1, random_state=42)
117 gb = GradientBoostingRegressor(n_estimators=200, learning_rate=0.05, max_depth=6, subsample=0.8, random_state=42)
118 [Link](X_scaled, y)
119 [Link](X_scaled, y)
120
121 # In-sample checks
122 rf_pred = [Link](X_scaled)
123 gb_pred = [Link](X_scaled)
124 ensemble_pred = 0.65*rf_pred + 0.35*gb_pred
125 r2 = r2_score(y, ensemble_pred)
126 mape = [Link]([Link]((y-ensemble_pred)/y))*100
127
128 # --------------------
129 # Dynamic monthly forecast
130 # --------------------
131 def dynamic_forecast_monthly(months=6):
132 latest = [Link][-1].copy()
133 dates = pd.date_range(start=latest['Date'] + [Link](months=1), periods=months, freq='MS')
134 preds = []
135 cur = current_usd_inr
136 prev = [cur]
137 for m in range(months):
138 feat = {}
139 for var in
['USD_Interest_Rate','INR_Interest_Rate','Oil_Price','Dollar_Index','VIX','India_Inflation','US_Inflation','FPI_Flow','FX
140 base = [Link](var, 0)
141 feat[var] = base * (1 + (m/60)*0.05) * [Link](1,0.01)
142 feat['Interest_Rate_Diff'] = feat['INR_Interest_Rate'] - feat['USD_Interest_Rate']
143 feat['Inflation_Diff'] = feat['India_Inflation'] - feat['US_Inflation']
144 feat['Real_Interest_Diff'] = feat['Interest_Rate_Diff'] - feat['Inflation_Diff']
145 def ma(arr,w): return [Link](arr[-w:]) if len(arr)>=w else [Link](arr)
146 feat['MA_3']=ma(prev,3); feat['MA_6']=ma(prev,6); feat['MA_12']=ma(prev,12)
147 feat['Volatility_3'] = [Link](prev[-3:]) if len(prev)>=3 else 0.4
148 feat['Volatility_6'] = [Link](prev[-6:]) if len(prev)>=6 else 0.35
149 feat['USD_INR_Change_1M'] = cur - prev[-2] if len(prev)>1 else 0
150 feat['USD_INR_Change_3M'] = cur - prev[-4] if len(prev)>3 else 0
151 feat['USD_INR_Change_6M'] = cur - prev[-7] if len(prev)>6 else 0
152 feat['USD_INR_Pct_Change_1M'] = (feat['USD_INR_Change_1M']/prev[-2])*100 if len(prev)>1 else 0
153 feat['USD_INR_Pct_Change_3M'] = (feat['USD_INR_Change_3M']/prev[-4])*100 if len(prev)>3 else 0
154 for lag in [1,2,3,6]:
155 feat[f'USD_INR_Lag{lag}'] = prev[-lag] if len(prev)>=lag else cur
156 feat[f'Oil_Lag{lag}'] = feat['Oil_Price']; feat[f'DXY_Lag{lag}'] = feat['Dollar_Index']
157 feat['Oil_USD_Corr'], feat['DXY_USD_Corr'], feat['VIX_USD_Corr'] = 0.3, 0.6, 0.4
158 feat['High_Vol_Regime'], feat['Strengthening_INR'] = 0, 0
159 feat['High_Oil_Regime'] = 1 if feat['Oil_Price']>80 else 0
160 fm = dates[m].month
161 feat['Month_Sin'], feat['Month_Cos'], feat['Quarter'] = [Link](2*[Link]*fm/12), [Link](2*[Link]*fm/12), (fm-
1)//3+1
162 feat['Policy_Uncertainty'] = feat['VIX']*abs(feat['Interest_Rate_Diff'])
163 feat['Carry_Trade_Appeal'] = feat['Real_Interest_Diff']/feat['VIX']
164 vec = [Link]([[Link](c,0) for c in features]).reshape(1,-1)
165 vec_scaled = [Link](vec)
166 p = 0.65*[Link](vec_scaled)[0] + 0.35*[Link](vec_scaled)[0]
167 p += [Link](0,0.05)
168 [Link](p); [Link](p); cur = p
169 df = [Link]({'Month':range(1,months+1),'Date':dates,'Raw_Predicted':[Link](preds,2)})
170 return df
171
172 raw_forecast = dynamic_forecast_monthly(6)
173
174 # --------------------
175 # Bias correction (in-sample)
176 # --------------------
177 latest_row = [Link][-1]
178 latest_vec = [Link]([latest_row.get(c,0) for c in features]).reshape(1,-1)
179 latest_scaled = [Link](latest_vec)
180 model_latest = 0.65*[Link](latest_scaled)[0] + 0.35*[Link](latest_scaled)[0]
181 bias = current_usd_inr - model_latest
182
183 # Apply linear taper correction across horizon
184 n = len(raw_forecast)
185 taper_frac = 0.6
186 bias_corrected = []
187 for i, v in enumerate(raw_forecast['Raw_Predicted'].values):
188 weight = 1 - (i/(n-1))*(1-taper_frac)
189 bias_corrected.append(v + bias*weight)
190 raw_forecast['Bias_Corrected'] = bias_corrected
191
192 # --------------------

[Link] 2/3
11/10/2025, 22:39 Python Forecasting Model
193 # Manual adjustment to target 88-90 mean
194 # --------------------
195 target_mean = 89.0 # center of 88-90 band
196 current_mean = [Link](raw_forecast['Bias_Corrected'])
197 needed_shift = target_mean - current_mean
198 raw_forecast['Final_Forecast'] = (raw_forecast['Bias_Corrected'] + needed_shift).round(2)
199
200 # --------------------
201 # Export & Present only Final Forecast
202 # --------------------
203 output = raw_forecast[['Month', 'Date', 'Final_Forecast']].copy()
204 output['Date'] = output['Date'].[Link]('%b-%Y')
205 output.to_excel('Final_USD_INR_6Month_Forecast.xlsx', index=False)
206
207 # Friendly print
208 print("\n===== Final USD/INR 6-Month Forecast =====\n")
209 print(f"Data last observed date: {train['Date'].iloc[-1].strftime('%Y-%m-%d')}")
210 print(f"Latest observed USD/INR spot: {current_usd_inr:.3f}")
211 print(f"In-sample model R²: {r2:.4f} • MAPE: {mape:.2f}%\n")
212 print(output.to_string(index=False))
213
214 print("\nExported: Final_USD_INR_6Month_Forecast.xlsx")
215 print("\nNote: 'Final_Forecast' = bias-corrected model forecast + manual adjustment so mean ≈ 89.")
216

[Link] 3/3

You might also like