python绘图练习——股票分析(二):风险分析与蒙特卡罗模拟

做完股票的基础分析后,接下来我们可以做一些简单的风险分析。
首先还是导入数据并进行简单的处理:

from __future__ import division
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#import data
Tesla=pd.read_csv('Tesla_Stock.csv',index_col='Date')
Tesla.index=pd.to_datetime(Tesla.index)

GM=pd.read_csv('GM_stock.csv',index_col='Date')
GM.index=pd.to_datetime(GM.index)

Ford=pd.read_csv('Ford_Stock.csv',index_col='Date')
Ford.index=pd.to_datetime(Ford.index)

#count daily return
GM['Return']=GM['Close'].pct_change(1)
GM=GM.dropna()
Tesla['Return']=Tesla['Close'].pct_change(1)
Tesla=Tesla.dropna()
Ford['Return']=Ford['Close'].pct_change(1)
Ford=Ford.dropna()

#concatenate daily return of three stocks
ret_df=pd.concat([Tesla['Return'],GM['Return'],Ford['Return']],axis=1)
ret_df.columns=['Tesla','GM','Ford']
ret_df.head()

我们可以看下计算出的三只股票的日收益率:

python绘图练习——股票分析(二):风险分析与蒙特卡罗模拟_第1张图片

接下来我们可以通过绘图描述每只股票风险与收益率的关系图:


area = np.pi*20
plt.scatter(ret_df.mean(), ret_df.std(),alpha = 0.5,s =area)
plt.xlabel('Expected returns')
plt.ylabel('Risk')

# Label the scatter plots
for label, x, y in zip(ret_df.columns, ret_df.mean(), ret_df.std()):
    plt.annotate(
        label, 
        xy = (x, y), xytext = (50, 50),
        textcoords = 'offset points', ha = 'right', va = 'bottom',
        arrowprops = dict(arrowstyle = '-', connectionstyle = 'arc3,rad=-0.3'))

这里使用了plt.annotate对每个点进行标注,更多内容,可以查看相关的文档
输出如下:
python绘图练习——股票分析(二):风险分析与蒙特卡罗模拟_第2张图片

从图中可以看出福特公司的股票风险最低,但同样收益率也较低,而特斯拉就属于高风险和高收益型股票了,从整张图明显的体现出了投资市场“高风险,高收益”的基本法则。


蒙特卡罗模拟法

接下来,我们通过蒙特卡罗模拟法来模拟计算特斯拉公司股票的风险价值。
风险价值(VaR):即在市场正常波动的条件下,在一定概率水平α%下,某一金融资产或金融资产组合的VaR是在未来特定一段时间Δt内最大可能损失。
现在我们使用蒙特卡罗模拟法进行风险价值的估算。简单来说,蒙特卡罗模拟法即运用历史数据对未来进行多次模拟,以求得未来股价结果的概率分布。蒙特卡罗模拟法的公式如下:

ΔSS=μΔt+σεΔt Δ S S = μ Δ t + σ ε Δ t

其中S为股票的价格,μ为期望收益率,Δt为时间间隔,σ为股票风险,ε为随机变量。将S移项可得:
ΔS=S(μΔt+σεΔt) Δ S = S ( μ Δ t + σ ε Δ t )

可以看出,蒙特卡罗模拟法认为股票的价格波动可以分为两部分,第一部分为drift,即股票会根据收益率波动,第二部分为shock,即随机波动。如下图:
python绘图练习——股票分析(二):风险分析与蒙特卡罗模拟_第3张图片
这样,通过历史数据求得股票的平均收益率与风险,我们便可以通过蒙特卡罗模拟法对股票未来走势进行模拟。关于蒙特卡罗模拟法更多的介绍可以查看 How to use Monte Carlo simulation with GBM。接下来,我们通过python对特斯拉接下来一年的股价进行预测。

首先设置收益率与风险等参数。

'''
Monte Carlo method
'''
# Set up our time horizon
days = 365

# Now our delta
dt = 1/days

# Now let's grab our mu (drift) from the expected return data we got for AAPL
mu = ret_df.loc['2016-01-01':'2016-12-30'].mean()['Tesla']

# Now let's grab the volatility of the stock from the std() of the average return
sigma = ret_df.std()['Tesla']

接下来定义蒙特卡罗函数:

def stock_monte_carlo(start_price,days,mu,sigma):
    ''' This function takes in starting stock price, days of simulation,mu,sigma, and returns simulated price array'''

    # Define a price array
    price = np.zeros(days)
    price[0] = start_price
    # Schok and Drift
    shock = np.zeros(days)
    drift = np.zeros(days)

    # Run price array for number of days
    for x in xrange(1,days):

        # Calculate Schock
        shock[x] = np.random.normal(loc=mu * dt, scale=sigma * np.sqrt(dt))
        # Calculate Drift
        drift[x] = mu * dt
        # Calculate Price
        price[x] = price[x-1] + (price[x-1] * (drift[x] + shock[x]))

    return price

定义完蒙特卡罗函数,接下来便可以开始模拟了,首先我们模拟100次观察一下效果:


# Get start price 
start_price = Tesla['Close'][-1]

for run in xrange(100):
    plt.plot(stock_monte_carlo(start_price,days,mu,sigma))
plt.xlabel("Days")
plt.ylabel("Price")  
plt.title('Monte Carlo Analysis for Tesla')

python绘图练习——股票分析(二):风险分析与蒙特卡罗模拟_第4张图片
可以看到,每一次模拟所得到股价走势都是不同的,但是大部分集中在中间。接下来我们进行10000次模拟并计算风险价值:


# Set a large numebr of runs
runs = 10000

# Create an empty matrix to hold the end price data
simulations = np.zeros(runs)

# Set the print options of numpy to only display 0-5 points from an array to suppress output
np.set_printoptions(threshold=5)

for run in xrange(runs):    
    # Set the simulation data point as the last stock price for that run
    simulations[run] = stock_monte_carlo(start_price,days,mu,sigma)[days-1];

最后,我们定义置信水平为99%,尝试绘制股票最终价格的分布图:


#define q as the 1% empirical qunatile, this basically means that 99% of the values should fall between here
q = np.percentile(simulations, 1)

# plot the distribution of the end prices
plt.hist(simulations,bins=200)

# Using plt.figtext to fill in some additional information onto the plot

# Starting Price
plt.figtext(0.6, 0.8, s="Start price: $%.2f" %start_price)
# Mean ending price
plt.figtext(0.6, 0.7, "Mean final price: $%.2f" % simulations.mean())

# Variance of the price (within 99% confidence interval)
plt.figtext(0.6, 0.6, "VaR(0.99): $%.2f" % (start_price - q,))

# Display 1% quantile
plt.figtext(0.15, 0.6, "q(0.99): $%.2f" % q)

# Plot a line at the 1% quantile result
plt.axvline(x=q, linewidth=4, color='r')

# Title
plt.title(u"Final price distribution for Tesla Stock after %s days" % days, weight='bold');

python绘图练习——股票分析(二):风险分析与蒙特卡罗模拟_第5张图片
即在99%的置信水平下,特斯拉股票一年后的价格不会低于198.51,其风险价值为15.18,而其平均价格与其初始价格基本一致。

你可能感兴趣的:(量化投资,数据分析)