用Python中的一系列蒙特卡洛投影创建一个扇形图 [英] Creating a fanchart from a series of Monte Carlo projections in Python

查看:85
本文介绍了用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆