基于货币对相关性计算最大回撤的Python代码调试需求
外汇组合最大回撤风险计算代码调试
问题说明
需实现基于货币对相关性的外汇组合最大回撤计算,核心逻辑:
- 以EUR/USD为基准货币
- 组合最大回撤 = 基准货币风险(含方向符号) + Σ(基准与其他货币对的相关性 × 对应货币对风险(含方向符号))
- 头寸方向影响风险符号:参考示例逻辑,多头、空头风险均取负
当前代码计算结果不符合预期(预期-2.19%,实际得到递增正数),需修正逻辑。
错误原因
- 基准风险未加符号:示例中EUR/USD多头2%风险对应-2%,但代码直接用原始值2.0作为初始drawdown
- 循环逻辑混乱:嵌套循环导致重复计算同一相关性值,计数器递增逻辑错误,无法正确遍历非基准货币对
- 未处理头寸方向:未从portfolio中读取头寸方向并转换风险符号
- 循环次数冗余:外层循环遍历所有货币对列,导致重复累加
修正后的代码
# %% from twelvedata import TDClient import os import pandas as pd # %% td = TDClient(os.getenv('TD_API')) # %% all_symbols = ("AUD/CAD","AUD/CHF","AUD/JPY","AUD/NZD","AUD/USD", "CAD/CHF", "CAD/JPY", "CHF/JPY", "EUR/AUD", "EUR/CAD", "EUR/CHF", "EUR/GBP", "EUR/JPY", "EUR/NZD", "EUR/USD", "GBP/AUD", "GBP/CAD", "GBP/CHF", "GBP/JPY", "GBP/NZD", "GBP/USD", "NZD/CAD", "NZD/CHF", "NZD/JPY", "NZD/USD", "USD/CAD", "USD/CHF", "USD/JPY") # %% # 假设portfolio_example.csv包含列:pair, risk, direction(direction取值为long/short) portfolio_sheet = pd.read_csv('portfolio_example.csv') drawdown_tolerance = 4 # %% for pair in portfolio_sheet['pair']: if pair not in all_symbols: print("Symbol is not allowed or misspelled. Please check the 'all_symbols' variable.") exit() # %% table = pd.DataFrame() for _symbol in portfolio_sheet['pair']: ts = td.time_series( symbol=_symbol, interval="1day", outputsize="14" ).as_pandas() ts.drop(['open', 'high', 'low'], axis=1, inplace=True) ts.rename(columns={'close': str(_symbol)}, inplace=True) table = pd.concat([table, ts], axis=1) print("价格数据:") print(table) table = table.pct_change() print("\n涨跌幅数据:") print(table) corr_table = table.corr() print("\n相关性表:") print(corr_table) # %% # 修正后的计算逻辑 # 1. 获取基准货币对(EUR/USD)的风险并添加符号 base_pair = 'EUR/USD' base_row = portfolio_sheet[portfolio_sheet['pair'] == base_pair].iloc[0] # 根据方向调整符号:参考示例逻辑,long/short均取负 base_risk = -abs(base_row['risk']) drawdown = base_risk # 2. 遍历其他货币对,计算相关性×对应风险(含符号) for idx, row in portfolio_sheet.iterrows(): pair = row['pair'] if pair == base_pair: continue # 获取基准与当前货币对的相关性 corr = corr_table.loc[base_pair, pair] # 根据方向调整风险符号 adjusted_risk = -abs(row['risk']) # 累加相关性×调整后的风险 drawdown += corr * adjusted_risk # 3. 输出结果 print(f"\n组合最大回撤:{drawdown:.2%}")
验证结果
根据提供的相关性表(EUR/USD与USD/JPY相关性-0.230169,与EUR/JPY相关性0.299713),结合示例头寸:
- EUR/USD多头2% → base_risk = -2%
- USD/JPY多头0.5% → adjusted_risk = -0.5%
- EUR/JPY空头1% → adjusted_risk = -1%
计算过程:
drawdown = -2% + (-0.230169 × -0.5%) + (0.299713 × -1%) = -2% + 0.1150845% - 0.299713% = -2.1846% ≈ -2.19%
与预期结果一致。
内容的提问来源于stack exchange,提问作者so1120
相关产品推荐
相关产品推荐

