蒙特卡洛实例和代码:计算货币对冲组合的var

蒙特卡洛方法是一种通过随机模拟来估计数值的技术。在金融领域,用蒙特卡洛方法计算对冲组合的 VaR是一种常见的风险度量方法。VaR是衡量金融资产或组合可能损失的最大金额的统计指标,在给定的置信水平下。

在选出两个币种进行对冲时,需要考虑一些因素,例如这两个币种的相关性和历史表现。通常,对冲的目标是找到两个资产,它们的价格走势在一定程度上是相反的,这样在一个资产表现较差时,另一个资产表现较好,从而减少整体组合的波动性。

本文重点解决如下几个问题:

(1)如何选取对冲组合?根据组合,如何制定对冲比例?

(2)计算对冲组合的日收益率,并利用蒙特卡洛模拟未来收益率

(3)根据模拟结果,计算对冲组合的风险价值(VaR)

代码源文件和数据可关注gzh‘finance褪黑素’回复关键词获取

一、对冲组合

1.1 数据准备和处理

收集从2023-01-01到2023-06-30期间的多种币种的收盘价数据。这些数据可以来自可靠的金融数据源或交易所。

 使用收盘价数据计算每个币种的日收益率。日收益率可以通过以下公式计算:

收益率 = (当日收盘价 - 前一日收盘价) / 前一日收盘价

扫描二维码关注公众号,回复: 17229351 查看本文章

import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
import datetime
%matplotlib inline
import warnings
warnings.filterwarnings('ignore')

df=pd.read_csv('bina_data_return.csv')

1.2 选取对冲组合和比例

计算每两个币种之间的相关性。相关性衡量两个资产之间的价格走势相似程度,取值范围为-1到1。当相关性为负值时,表示两个资产的价格走势相反;当相关性为正值时,表示两个资产的价格走势相似;当相关性接近0时,表示两个资产的价格走势没有明显关系。

 从相关性分析中选择相关性较低或为负值的两个币种,作为对冲组合的候选。根据结果显示,负相关系数最大的组合是GASBTC与LRCBTC。

#求收益率相关系数
df_return_corr=df.corr()

对选出的两个币种进行历史表现的分析。了解它们过去的价格波动情况和是否有长期稳定的对冲效果。

选取的两个币种在收益率走势上具有一定的负相关性。

import pandas as pd
import matplotlib.pyplot as plt
# 假设您有两个币种,分别命名为'coin1'和'coin2'
coin1 = 'GASBTC' # 替换为您的第⼀个币种名称
coin2 = 'LRCBTC' # 替换为您的第⼆个币种名称
price_coin1 = df['GASBTC']
price_coin2 = df['LRCBTC']
# 绘制折线图
plt.figure(figsize=(12, 6))
plt.plot(price_coin1, label=coin1)
plt.plot(price_coin2, label=coin2)
plt.title('Price Return Trend of {} and {}'.format(coin1, coin2))
plt.xlabel('Date')
plt.ylabel('Price Return (USDT)')
plt.legend()
plt.grid(True)
plt.show()

根据历史数据和风险偏好,决定两个币种在对冲组合中的权重比例。

决定两个币种的对冲比例通常是通过优化技术来实现的。在优化过程中,我们希望找到一个对冲比例,使得对冲组合的风险最小化或收益最大化。最常用的优化方法之一是最小方差对冲(Minimum Variance Hedge),该方法可以帮助找到最优的对冲比例。在Python中,可以使用SciPy库来进行最小方差对冲优化。

最终得到GASBTC和LRCBTC 的对冲比例为0.23 : 0.77。

import pandas as pd
import numpy as np
from scipy.optimize import minimize
# 计算收益率
returns_coin1 = price_coin1
returns_coin2 = price_coin2
# 定义最⼩⽅差函数
def min_variance_hedge(x):
 hedge_portfolio = x[0] * returns_coin1 + x[1] * returns_coin2
 return np.var(hedge_portfolio)
# 初始化对冲⽐例
x0 = np.array([0.5, 0.5]) # 假设初始对冲⽐例为0.5和0.5
# 设置约束条件,对冲⽐例之和为1
constraints = {'type': 'eq', 'fun': lambda x: np.sum(x) - 1}
# 最⼩化⽅差,得到最优对冲⽐例
result = minimize(min_variance_hedge, x0, constraints=constraints)

二、蒙特卡洛预测

2.1 计算对冲组合的日收益率

使用收盘价数据计算对冲组合的日收益率。对冲组合的每日收益率可以通过以下公式计算:

组合收益率 = (0.23 * GASBTC收益率) + (0.77 * LRCBTC收益率)

weight1 = 0.23
weight2 = 0.77
# 计算对冲组合的⽇收益率
hedge_portfolio_returns = (returns_coin1 * weight1) + (returns_coin2 * weight2)
print(hedge_portfolio_returns)

2.2 蒙特卡洛模拟未来收益率

使用蒙特卡洛方法模拟未来一段时间(比如1个月或3个月)的收益率变化。我们可以根据历史收益率数据的统计特性(例如均值和标准差)来模拟未来的收益率。

假设我们希望模拟未来一个月的交易日数量,进行1000次模拟。使用alpha=0.5参数来设置折线图的透明度,这样可以让多条折线图重叠在一起,形成一个统计图。每次模拟都会生成一个模拟的未来价格变化曲线,而所有模拟的结果都会在同一个图中显示。通过这样的绘图方式,可以更清晰地看到模拟结果的整体分布情况,以及未来价格变化的不确定性。

 蒙特卡洛模拟结果曲线密密麻麻地集合在一起,形成了一个正态分布的形状,这可能意味着模拟的未来收益率变化相对较小,模拟结果的波动性较低。

# 假设我们希望模拟未来⼀个⽉的交易⽇数量
num_simulations = 30
# 假设我们希望进⾏1000次模拟
num_trials = 1000
# 计算对冲组合的每⽇平均收益率和标准差
mean_return = np.mean(hedge_portfolio_returns)
std_dev = np.std(hedge_portfolio_returns)
# 使⽤蒙特卡洛⽅法模拟未来收益率变化
simulated_returns = np.random.normal(mean_return, std_dev, size=(num_simulations, num_trials))
# 计算每个模拟序列的累积收益率
cumulative_returns = np.cumprod(1 + simulated_returns, axis=0)
# 将初始值设为1.0,得到模拟的未来收益率变化序列
simulated_prices = 1.0 * cumulative_returns
# 绘制模拟的未来收益率变化统计图
plt.figure(figsize=(12, 6))
plt.plot(simulated_prices, alpha=0.5)
plt.title('Monte Carlo Simulation of Future Prices Return')
plt.xlabel('Trading Days')
plt.ylabel('Price Return')
plt.grid(True)
plt.show()

2.3 计算组合价值 

根据模拟得到的未来收益率,计算对冲组合的未来价值。可以根据以下公式计算:

未来组合价值 = 当前组合价值 * (1 + 组合收益率)

以未来五天为例,得到的未来价值为0.04924968818330657, 0.049472121812033386, 0.049958179678478404, 0.04990120258099386, 0.051128552327471107。

# 假设对冲组合的初始价值为V0
V0 = 0.048706 
# 假设模拟得到的未来收益率序列为returns,是⼀个⻓度为n的numpy数组
returns = hedge_portfolio_returns
# 计算未来价值序列
def calculate_future_values(initial_value, returns):
 future_values = [initial_value]
 for ret in returns:
 future_value = future_values[-1] * (1 + ret)
 future_values.append(future_value)
 return future_values[1:] # 去除初始值,返回未来价值序列
# 计算对冲组合的未来价值序列
future_values = calculate_future_values(V0, returns)
# 打印未来价值序列
print(future_values)

2.4 计算风险价值(VaR)

根据模拟结果,计算对冲组合的风险价值(VaR)。VaR是在给定的置信水平下,对冲组合可能的最大损失金额。

计算VaR时使用的索引是基于所有模拟结果的总数,而不仅仅是单个模拟序列的长度。

计算得到的VaR值为0.04,表示在5%的置信水平下,投资组合的预期损失不会超过0.04(或4%)。

import numpy as np
# 假设模拟未来的交易⽇数量
num_simulations = 30
# 假设模拟次数
num_trials = 1000
# 假设置信⽔平为alpha(例如0.95表示95%置信⽔平)
alpha1 = 0.95
alpha2=0.90
alpha3=0.99
# 将simulation_results转换为NumPy数组
simulation_results_array = np.array(simulation_results)
# 将数组展平成⼀维数组,⽅便排序
flattened_values = simulation_results_array.flatten()
# 对所有模拟结果进⾏排序
sorted_values = np.sort(flattened_values)
# 计算在给定置信⽔平下的VaR值
var_index = int(np.ceil((1 - alpha1) * num_trials * num_simulations)) - 1
var_value1 = sorted_values[var_index]
var_index = int(np.ceil((1 - alpha2) * num_trials * num_simulations)) - 1
var_value2 = sorted_values[var_index]
var_index = int(np.ceil((1 - alpha3) * num_trials * num_simulations)) - 1
var_value3 = sorted_values[var_index]
# 输出VaR值
print(f"VaR (at {alpha1*100:.1f}% confidence level) is: {var_value1:.2f}")
print(f"VaR (at {alpha2*100:.1f}% confidence level) is: {var_value2:.2f}")
print(f"VaR (at {alpha3*100:.1f}% confidence level) is: {var_value3:.2f}")

三、回测

回测(Backtesting)是金融领域中常用的一种测试和评估投资策略的方法。它通过使用历史市场数据来模拟和验证投资策略的表现,以评估该策略在过去的实际市场条件下的效果和可行性。

95% 置信⽔平下,基于蒙特卡罗模拟法超过⻛险价值的天数 : 164
95% 置信⽔平下,基于蒙特卡罗模拟法超过⻛险价值天数占全部交易天数的⽐例 : 0.9111
99% 置信⽔平下,基于蒙特卡罗模拟法超过⻛险价值的天数 : 162
99% 置信⽔平下,基于蒙特卡罗模拟法超过⻛险价值天数占全部交易天数的⽐例 : 0.9
Return=hedge_portfolio_returns

days=len(Return)
VaR_MC_90=pd.Series(var_value2*np.ones_like(Return), index=Return.index) #⽣成蒙特卡洛模拟⻛险价值的时间序列(90%)
VaR_MC_95=pd.Series(var_value1*np.ones_like(Return), index=Return.index) #⽣成蒙特卡洛模拟⻛险价值的时间序列(95%)
VaR_MC_99=pd.Series(var_value3*np.ones_like(Return), index=Return.index) #⽣成蒙特卡洛模拟⻛险价值的时间序列(99%)

plt.rcParams["font.sans-serif"]=["SimHei"]
plt.rcParams["axes.unicode_minus"]=False
plt.figure(figsize=(10,8))
plt.subplot(1,1,1)
plt.plot(Return,'b-',label=u'Daily return')
plt.plot(VaR_MC_90,'r-',label=u'90% Confidence Level',lw=1.0)
plt.plot(VaR_MC_95,'b-.',label=u'95% Confidence Level',lw=1.0)
plt.plot(VaR_MC_99,'y-.',label=u'99% Confidence Level',lw=1.0)
plt.ylabel(u'Yield',rotation=0)
plt.xticks(rotation=30)
plt.yticks(rotation=30)
plt.legend(fontsize=12)
plt.grid('True')

dayexcept_MC_95=len(Return[Return<VaR_MC_95]) #基于蒙特卡洛模拟法做回溯检验,并计算超过⻛险价值天数
dayexcept_MC_99=len(Return[Return<VaR_MC_99]) #基于蒙特卡洛模拟法做回溯检验,并计算超过⻛险价值天数
print('95%置信⽔平下,基于蒙特卡罗模拟法超过⻛险价值的天数:',dayexcept_MC_95)
print('95%置信⽔平下,基于蒙特卡罗模拟法超过⻛险价值天数占全部交易天数的⽐例:',round(dayexcept_MC_95/days,4)
print('99%置信⽔平下,基于蒙特卡罗模拟法超过⻛险价值的天数:',dayexcept_MC_99)
print('99%置信⽔平下,基于蒙特卡罗模拟法超过⻛险价值天数占全部交易天数的⽐例:',round(dayexcept_MC_99/days,4)

代码源文件和数据可关注gzh‘finance褪黑素’回复关键词获取

猜你喜欢

转载自blog.csdn.net/celiaweiwei/article/details/131977124