用Python中的一系列蒙特卡洛投影创建一个扇形图 [英] Creating a fanchart from a series of Monte Carlo projections in Python
问题描述
我有一个程序,可以为投资组合生成一系列随机回报,如下所示:
产生以上图形的代码:
S = 1#起始价格= 1T = 180#计划的月数mu = max_sharpe_port [0]#返回vol = max_sharpe_port [1] ** 2#波动率对于我在范围(10000)中:month_returns = np.random.normal((1 + mu)**(1/T),vol/math.sqrt(T),T)price_list = [S]对于month_returns中的x:price_list.append(price_list [-1] * x)price_list = [x-price_list中x的x-1]plt.plot(price_list)result.append(price_list [-1])
我希望此图看起来像下图所示的扇形图:
在这里,我仅使用了100个样本,因此看起来更加锯齿.您使用的样本越多,每个百分位范围的分布看起来就越平滑.
I have a program that generates a series of randomized returns for a portfolio, which looks like this:
The code that produces the above graph:
S = 1 # starting price = 1
T = 180 # Number of months to project
mu = max_sharpe_port[0] # Return
vol = max_sharpe_port[1]**2 # Volatility
for i in range(10000):
monthly_returns = np.random.normal((1+mu)**(1/T), vol/math.sqrt(T), T)
price_list = [S]
for x in monthly_returns:
price_list.append(price_list[-1] * x)
price_list = [x - 1 for x in price_list]
plt.plot(price_list)
result.append(price_list[-1])
I would like this graph to rather look like a fanchart like the image below:
plt.fill_between()
can create a fanchart by filling the graph between two points. In order to achieve your result, you need to call it 4 times, once for the range between the percentiles 40 and 60, once for 30 and 70, etc.
import matplotlib.pyplot as plt
import numpy as np
def create_fanchart(arr):
x = np.arange(arr.shape[0])
# for the median use `np.median` and change the legend below
mean = np.mean(result, axis=1)
offsets = (10, 20, 30, 40)
fig, ax = plt.subplots()
ax.plot(mean, color='black', lw=2)
for offset in offsets:
low = np.percentile(result, 50-offset, axis=1)
high = np.percentile(result, 50+offset, axis=1)
# since `offset` will never be bigger than 50, do 55-offset so that
# even for the whole range of the graph the fanchart is visible
alpha = (55 - offset) / 100
ax.fill_between(x, low, high, color='blue', alpha=alpha)
ax.legend(['Mean'] + [f'Pct{2*o}' for o in offsets])
return fig, ax
S = 1
T = 180
mu = 0.15
vol = 0.05
samples = 100
result = []
for i in range(samples):
monthly_returns = np.random.normal((1+mu)**(1/T), vol/np.sqrt(T), T)
monthly_returns = np.hstack([1, monthly_returns])
price_list = np.cumprod(monthly_returns) * S - 1
result.append(price_list)
result = np.array(result).T
# plt.plot(result) # for the individual samples
fig, ax = create_fanchart(result)
plt.show()
Output
Here I used only 100 samples so it looks more jagged. The more samples you use, the smoother the spread for each percentile range will look.
这篇关于用Python中的一系列蒙特卡洛投影创建一个扇形图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!