做完股票的基础分析后,接下来我们可以做一些简单的风险分析。
首先还是导入数据并进行简单的处理:
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()
我们可以看下计算出的三只股票的日收益率:
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
对每个点进行标注,更多内容,可以查看相关的文档
输出如下:
从图中可以看出福特公司的股票风险最低,但同样收益率也较低,而特斯拉就属于高风险和高收益型股票了,从整张图明显的体现出了投资市场“高风险,高收益”的基本法则。
接下来,我们通过蒙特卡罗模拟法来模拟计算特斯拉公司股票的风险价值。
风险价值(VaR):即在市场正常波动的条件下,在一定概率水平α%下,某一金融资产或金融资产组合的VaR是在未来特定一段时间Δt内最大可能损失。
现在我们使用蒙特卡罗模拟法进行风险价值的估算。简单来说,蒙特卡罗模拟法即运用历史数据对未来进行多次模拟,以求得未来股价结果的概率分布。蒙特卡罗模拟法的公式如下:
'''
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')
可以看到,每一次模拟所得到股价走势都是不同的,但是大部分集中在中间。接下来我们进行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');
即在99%的置信水平下,特斯拉股票一年后的价格不会低于198.51,其风险价值为15.18,而其平均价格与其初始价格基本一致。