第1天:Python和科学编程介绍。 Python中的基础知识: 数据类型、控制结构、功能、I/O文件
第2天:用Numpy,Scipy,Matplotlib和其他模块进行计算。 用Python解决一些数学问题。
第3天:时间序列:用Pandas进行统计和实际数据分析。 随机和蒙特卡罗。
第三天的主要内容
Pandas
Stochastics and Monte Carlo (随机与蒙特卡罗)
Statistical application (统计应用)
Lab session (实验部分)
01 关于Pandas
开发者Wes McKinney从2008年开始专注于开发Pandas,当时在AQR资本管理公司,处理金融数据的定量分析需要高性能和高灵活性的工具。(注释:痛点和需求)
Pandas是一个开源库,为Python提供高性能,易于使用的数据结构和数据分析工具。
Python长期以来一直是数据管理和准备的手段,但是对于数据分析和建模来说,确实不太适用。Pandas的诞生填补了这个缺口。
Pandas线性和面板回归之外没有显著的建模功能。为此,请看Starmodels和Scikit-learn。
Pandas 基础
Numpy通常在Pandas对象上工作。在pandas中,索引和标签数据由DataFrame类管理。它类似于SQL 数据表和电子表格。例如:我们可以创建一个DataFrame对象:
import numpy as npimport pandas as pddf = pd.DataFrame([10, 20, 30, 40], \columns = [’Numbers’], \index = [’a’, ’b’, ’c’, ’d’])
让我们看下DataFrame对象。它是由给出
我们可以执行以下代码在DataFrame对象中显示一些典型的操作。
import pandas as pddf = pd.DataFrame([10, 20, 30, 40], \columns = [’Numbers’], \index = [’a’, ’b’, ’c’, ’d’])print(df.index) #显示索引 show indexprint(df.columns) #显示列名 show column namesprint(df.ix[’c’]) #通过索引选择 select via indexprint(df.ix[[’a’, ’d’]]) # 多选 multi-selectprint(df.ix[df.index[1:3]]) # 其他anotherprint(df.sum()) # 每列求和 sum per columnts = df ** 2 # 创建新的DataFrame create new DataFrameprint(ts)
放大DataFrame
import pandas as pddf = pd.DataFrame([10, 20, 30, 40], \columns = [’Numbers’], \index = [’a’, ’b’, ’c’, ’d’])#add a new column called ’floats’ directlydf[’floats’] = (1.5, 2.5, 3.5, 4.5)#add a new column called ’names’ by indexdf[’names’] = pd.DataFrame([’Dan’, \’Cox’, ’Ale’, ’Bob’], \index = [’d’, ’c’, ’a’, ’b’])# add a new object to dfdf = df.append(pd.DataFrame({ \’Numbers’:66, ’floats’:5.5, \’names’:’Yor’}, index=[’y’,]))
处理缺失的数据
我们通过"join"函数添加一个名为\squares的新列。
df = df.join(pd.DataFrame([1,4,9,16,25], \index=[’a’, ’b’, ’c’, ’d’, ’x’], \columns=[’squares’,]),how=’outer’) #
我们注意到没有由“\x”索引的行,且由“\y”索引的行在新列中没有被分配值。这里,我们使用
how=’outer’
用来显示所有的潜在数据。
(注释:没太搞清楚这几段话的意思。不过,看代码倒是很清楚,即通过外链outer方式join两张表,会显示所有数据,缺失数据的地方会显示nan。)
处理金融数据
Pandas内置函数DataReader从以下网站检索数据:
Yahoo! Finance (Yahoo)
Google Finance (Google)
St. Louis FED (Fred)
Kenneth French’s data library (Famafrench)
World Band (via pandas.io.wb)
要使用DataReader函数,我们需要
import pandas.io.data as web
富时100数据(FTSE 100 data)
import pandas as pdimport pandas.io.data as webFT = web.DataReader(name = ’^FTSE’, \data_source = ’yahoo’, \start = ’2000-1-1’)print(FT.info()) # show informationprint(FT.tail()) # show last 5 rows# plot the FTSE 100 graphFT[’Close’].plot(figsize = (8, 6), \grid = True)
计算每日回报 (Calculate the daily return)
import pandas as pdimport pandas.io.data as webimport numpy as npFT = web.DataReader(name = ’^FTSE’, \data_source = ’yahoo’, \start = ’2000-1-1’)FT[’Return’] = np.log(FT[’Close’] \/ FT[’Close’].shift(1))FT[’Return’].plot(figsize = (8, 6), \grid = True)
显示数据并同时返回(Show data and return simultaneously)
import pandas as pdimport pandas.io.data as webimport numpy as npFT = web.DataReader(name = ’^FTSE’, \data_source = ’yahoo’, \start = ’2000-1-1’)![Uploading datasub_463200.png . . .]FT[’Return’] = np.log(FT[’Close’] \/ FT[’Close’].shift(1))FT[[’Close’, ’Return’]].plot( \subplots = True, style = ’b’, \figsize = (8, 6), grid = True)
算术交易:移动平均(Algorithmic trading: Moving average)
import pandas as pdimport pandas.io.data as webimport numpy as npFT = web.DataReader(name = ’^FTSE’, \data_source = ’yahoo’, \start = ’2000-1-1’)FT[’MA42D’] = pd.rolling_mean(FT[’Close’], \window = 42)FT[’MA252D’] = pd.rolling_mean(FT[’Close’], \window = 252)FT[[’Close’, ’MA42D’, ’MA252D’]].plot( \figsize = (8, 6), grid = True)
波动率:年化日志回报标准差?(Volatility: Annualised log return StD)
import pandas as pdimport pandas.io.data as webimport numpy as npFT = web.DataReader(name = ’^FTSE’, \data_source = ’yahoo’, \start = ’2000-1-1’)FT[’Return’] = np.log(FT[’Close’] \/ FT[’Close’].shift(1))FT[’Vol’] = np.sqrt(252) * \pd.rolling_std(FT[’Return’],\window = 252)FT[’Vol’].plot(figsize = (8, 6), \grid = True)
相关和线性回归
我们实现一个符合以下目标的代码
捕获富时100指数和英国石油BP(伦敦)的历史价格。
评估这两种资产的历史回报。
对两个回报做线性回归,并获得其回归函数。
(代码在datacorr.py里)
应用实例:配对交易 (pair trading)
图:
左:从2011-01-01开始,壳牌(B)和BP(伦敦)的历史股价。
右:壳牌和BP的相对性能。
自学Pandas
Pandas的官方文件可以在这里找到:http://pandas.pydata.org/pandas-docs/stable/
官方文档为初学者提供了详细的结构化材料。
与其他软件包类似,只要遇到错误,请检查第一个错误消息。 如果您无法解决问题,请先尝试Google。 大量的人在互联网上问同样的问题。
02随机与蒙特卡罗
用Python产生随机数
随机数可以通过numpy.random生成。
import numpy.random as nprimport matplotlib.pyplot as pltimport numpy as npX = npr.standard_normal((5000))Y = npr.normal(1, 1, (5000))Z = npr.uniform(-3, 3, (5000))W = npr.lognormal(0, 1, (5000))
我们可以绘制直方图来检查分布。
![Uploading FThist_677874.png . . .]
图:在前一张幻灯片中生成的随机数的直方图。
蒙特卡洛
蒙特卡罗是摩纳哥的一个地区和赌场......
蒙特卡罗方法
第一次人们开始研究蒙特卡罗方法是要评估π。
通过概率论,蒙特卡罗可以用作数值积分法。 例如,
其中p(x)是U(0;1)的概率密度函数。
实践中,蒙特卡罗广泛应用于统计力学,量子物理学,金融衍生产品定价和风险管理。
一个MC示例:期权定价
蒙特卡洛通常用于评估期权价格。
我们不会涉及任何理论推论。 对于欧式看涨期权,其价格可以通过公式给出
其中S为当前基本股票价格,σ为股票波动率,r为利率,T为期权期权,K为行使价,Φ为标准正态随机变量。
对于这个例子。 让我们假设S = 100,K = 100,
σ= 50%,T = 1,r = 0.05。
通过Python实现MC (MC by Python)
import numpy as npimport numpy.random as nprfrom scipy.stats import normS = 100; K = 100; T = 1r = 0.05; vol = 0.5I = 10000 # MC pathsZ = npr.standard_normal(I)ST = S * np.exp((r - 0.5 * vol**2) \* T + vol * np.sqrt(T) * Z)V = np.mean(np.exp(-r * T) \* np.maximum(ST - K, 0))print(V)
蒙特卡罗路径图
图:一幅蒙特卡罗模拟股票的图。
MC的准确度如何?
您运行的所有MC都应同时输出方差或标准偏差。 对于最后一张幻灯片中的代码,我们有结果
V ≈ 21.54 , std ≈ 0.40
实际上,我们有一个封闭式的欧式看涨期权方案
当
(看到公式不要慌,先冷静哈!慢慢来。)
03统计应用 (Statistical application)
直方图 (Histogram plot)
import pandas as pdimport pandas.io.data as webimport numpy as npFT = web.DataReader(name = ’^FTSE’,\data_source = ’yahoo’,\start = ’2000-1-1’)FT[’Return’] = np.log(FT[’Adj Close’] \/ FT[’Adj Close’].shift(1))FT[’Return’].hist(bins = 100, \figsize = (8,6))
正态检验:QQ图
我们通常使用分位数分布图(QQ图)来验证该分布是否正常。
为了实现QQ图,我们需要一个名为statsmodels的库。 我们导入相应的库
import statsmodel.api as sm
statsmodels 是一个非常有用的统计分析库,但我们不会给出太多的介绍。
另一个有用的库被称为scikit-learning,它是一个统计和机器学习库。
QQ-plot
import pandas as pdimport pandas.io.data as webimport numpy as npimport statsmodels.api as smimport matplotlib.pyplot as pltFT = web.DataReader(name = ’^FTSE’,\data_source = ’yahoo’,\start = ’2000-1-1’)FT[’Return’] = np.log(FT[’Adj Close’] \/ FT[’Adj Close’].shift(1))sm.qqplot(FT[’Return’].dropna(),line=’s’)plt.grid(True)plt.xlabel(’Theoretical quantiles’)plt.ylabel(’Sample quantiles’)
Skew and kurtosis (斜度与峰值?)
import pandas.io.data as webimport numpy as npimport scipy.stats as scsFT = web.DataReader(name = ’^FTSE’,\data_source = ’yahoo’,\start = ’2000-1-1’)FT[’Return’] = np.log(FT[’Adj Close’] \/ FT[’Adj Close’].shift(1))data = FT[’Return’].dropna() # 将缺失值丢掉 leave nanprint(’Skew is %f’ %scs.skew(data))print(’Skew test p-value is %f’ \%scs.skewtest(data)[1])print(’Kurt is %f’ %scs.kurtosis(data))print(’Kurt test p-value is %f’ \%scs.kurtosistest(data)[1])print(’Normal test p-value is %f’ \%scs.normaltest(data)[1])
较小的p值意味着否决数据是正态分布的假设。
04 实验部分 (Lab session)
目标1:蒙特卡罗模拟
我有一个随机过程
其中ΦN(0,1)(标准正态分布),t是自变量,表示时间(x轴),参数为
x0 = 1,θ = 1, μ = 1, σ = 0.5
尝试为 t = 10 生成10000个Monte Carlo路径。然后评估您的MC路径的平均值,用解析平均(analytical mean)进行检查
目标2:P&L分析
去雅虎网站,试图用Pandas获取以下股票调整后的收盘价
['RDSB.L','BP.L','AAPL','MSFT']
然后绘制股票价格。
让我们假设两个静态交易策略:
原油策略:买1'RDSB.L',卖5'BP.L'
科技策略:买3'AAPL', 卖4'MSFT'
尝试获得两个Pandas series,存储的价值两个不同策略的组合。(Try to obtain two pandas series, which stored the value two portfolios of di erent strategies.)
尝试评估两种策略的每日损益(P&L)。 每日P&L由以下公式定义:
分析两个投资组合的日常损益,分别采用不同的正态检验。 绘制直方图和QQ图。