我正在处理一个文件,其中有三列,从场景 [+100、+25、-25、-100、暗示、EBA 向上、EBA 向下] 开始,然后是评级索引 [GL-AUD-AONIA-01D、GL -INR-01D] 然后以月度格式对未来 5 年的日期进行评级。
我担心的是,如果对于特定利率指数,隐含或基本冲击情景利率为 5.00,那么在 +100 冲击情景的情况下,它应该是隐含利率 + 100 bps 意味着 5 + 1 = 6.00,但如果文件正在加载到 pandas 数据帧具有不同的速率,例如 9.00 与 +100 冲击场景相比,那么它应该在比较文件中将其标记为 false,而这没有发生。事实上代码正在做什么,而不是重新计算除隐含场景之外的所有场景的速率只需根据该场景从现有利率中添加/减去基点值,而不是使用隐含利率+-冲击
import pandas as pd
import numpy as np
def apply_scenario(rate, scenario, rate_index):
if 'Implied' in scenario:
return rate # Implied scenario does not modify the rate
elif '+100' in scenario:
# Apply +100 shock
return rate + 1
elif '+25' in scenario:
# Apply +25 shock
return rate + 0.25
elif '-100' in scenario:
# Apply -100 shock
return rate - 1
elif 'EBA up' in scenario:
# Apply EBA up shock
currency = rate_index.split('-')[1]
shock_value = get_shock_value(currency)
return rate + shock_value
elif 'EBA down' in scenario:
# Apply EBA down shock
currency = rate_index.split('-')[1]
shock_value = get_shock_value(currency)
# Ensure it doesn't go below -1%
new_rate = rate - shock_value
return max(new_rate, -0.01)
elif 'Static' in scenario:
# Static scenario, return the same rate
return rate
else:
# Handle unknown scenarios
return None
def get_shock_value(currency):
# Define shock values per currency
shock_values = {
'ARS': 400, 'AUD': 350, 'BRL': 400, 'CAD': 250, 'CHF': 150,
'CNY': 300, 'EUR': 250, 'GBP': 300, 'HKD': 200, 'IDR': 400,
'INR': 350, 'JPY': 100, 'KRW': 250, 'MXN': 400, 'RUB': 400,
'SAR': 300, 'SEK': 300, 'SGD': 150, 'TRY': 400, 'USD': 200,
'ZAR': 350
}
# Return shock value for the given currency
return shock_values.get(currency, 0)
def process_excel_data(file_path, sheet_name, output_file):
# Load data from Excel
df = pd.read_excel(file_path, sheet_name=sheet_name, header=5) # Adjust header as needed
# Rename 'Forecast with timestamp' column to 'Scenario'
df = df.rename(columns={df.columns[0]: 'Scenario', df.columns[1]: 'Rate Index'})
df['Scenario'] = df['Scenario'].str.split('/').str[1]
# Initialize an empty DataFrame to store calculated rates
calculated_rates_df = df.copy()
# Iterate through each row in the DataFrame
for index, row in df.iterrows():
scenario = row['Scenario'] # Fetch scenario from the DataFrame
rate_index = row['Rate Index'] # Fetch rate index from the DataFrame
# Iterate through each date column starting from the third column
for column in df.columns[2:]:
t0_rate = row[column]
if pd.notna(t0_rate):
# Calculate the rate for the scenario
calculated_rate = apply_scenario(t0_rate, scenario, rate_index)
if calculated_rate is not None:
# Update the calculated rate in the DataFrame
calculated_rates_df.at[index, column] = calculated_rate
# Comparison DataFrame for True/False comparison
comparison_results = (np.abs(df.iloc[:, 2:] - calculated_rates_df.iloc[:, 2:]) < 1e-10).astype(int)
# Create Excel writer
writer = pd.ExcelWriter('output.xlsx', engine='openpyxl')
with pd.ExcelWriter(output_file_path, engine='openpyxl') as writer:
# Write each DataFrame to a different sheet
df.to_excel(writer, sheet_name='Original Data', index=False)
calculated_rates_df.to_excel(writer, sheet_name='Calculated Rates', index=False)
comparison_results.to_excel(writer, sheet_name='Result', index=False)
# Example usage:
file_path = "C:\\Users\\45320750\\Desktop\\Rate_index\\MF.xlsx"
sheet_name = 'Market Forecast Rate Indexes'
output_file_path = 'C:\\Users\\45320750\\Desktop\\Rate_index\\Market Forecast_comparison.xlsx'
process_excel_data(file_path, sheet_name,output_file)
输入
|场景| 利率指数| 30/06/2024 |
|+100 | GL-AUD-AONIA-01D | GL-AUD-AONIA-01D | 5.5 |
|-100 | GL-AUD-AONIA-01D | GL-AUD-AONIA-01D | 4 |
|隐含| GL-AUD-AONIA-01D| 5
|EBA 上行| GL-AUD-AONIA-01D | GL-AUD-AONIA-01D | 8.5 |
正确的计算利率
|场景| 利率指数| 30/06/2024 |
|+100 | GL-AUD-AONIA-01D | GL-AUD-AONIA-01D | 6 |
|-100 | GL-AUD-AONIA-01D | GL-AUD-AONIA-01D | 4 |
|隐含| GL-AUD-AONIA-01D| 5 |
|EBA 上行| GL-AUD-AONIA-01D | GL-AUD-AONIA-01D | 8.5|
我的代码正在计算什么
|场景| 利率指数| 30/06/2024 |
|+100 | GL-AUD-AONIA-01D | GL-AUD-AONIA-01D | 6.5 |
|-100 | GL-AUD-AONIA-01D | GL-AUD-AONIA-01D | 4 |
|暗示| GL-AUD-AONIA-01D| 5
基本上,代码是在现有的 +100 利率之上,针对 +100 冲击场景应用 +1 bps 的冲击,即 5.5 +1 = 6.5,这是不正确的,它应该是隐含利率 + 1 bps 冲击,因此 5+1 = 6
在 EBA 上下波动的情况下,它应该根据我在代码中定义的货币价值给出冲击,因此如果利率指数是 GL-AUD-AONIA-01D,则意味着它是基于澳元的曲线,对于澳元 ccy冲击值为 350 bps,因此如果隐含利率为 5 ,则 EBA 上涨利率将为 5 + 3.5 = 8.5
我的建议是对您的数据框进行一些预处理。
假设您的原始数据框由以下方式给出:
d = {'Scenario': ['+100', '-100','Implied','EBA up'],
'Rate Index': ['GL-AUD-AONIA-01D','GL-AUD-AONIA-01D','GL-AUD-AONIA-01D','GL-AUD-AONIA-01D' ],
'DATE':['30/06/2024','30/06/2024','30/06/2024','30/06/2024'],
'Rate':[5.5,4,5,8.5]}
original_df = pd.DataFrame(data=d)
预处理:
# Getting implied rates and date
implied_rates = original_df.loc[original_df['Scenario'].str.contains('Implied'), ['DATE','Rate']]
# Rename 'Rate' to 'Implied Rate'
implied_rates.rename({'Rate': 'Implied Rate'}, axis=1, inplace=True)
# Merging implied_rate to original_df
new_df = original_df.merge(implied_rates,on='DATE',how='right')
完成这些操作后,您的数据框将如下所示:
Scenario Rate Index DATE Rate Implied Rate
+100 GL-AUD-AONIA-01D 30/06/2024 5.5 5.0
-100 GL-AUD-AONIA-01D 30/06/2024 4.0 5.0
Implied GL-AUD-AONIA-01D 30/06/2024 5.0 5.0
EBA up GL-AUD-AONIA-01D 30/06/2024 8.5 5.0
因此,在您的代码中,您可以在任何需要的地方使用隐式利率。
注意:我创建了一个“日期”字段以允许对隐含和非隐含汇率进行分组。