第三天主要是講Pandas、Statsmodels等library,是入門的好材料,但想提高還要多加練習。
前言:
首先,非常感謝Jiang老師將其分享出來!本課件非常經典!
經過筆者親測,竟然確實只要三天,便可管中窺豹洞見Python及主要庫的應用。實屬難得誠意之作!
其次,只是鑒于Jiang老師提供的原始課件用英文寫成,而我作為Python的愛好者計算機英文又不太熟練,講義看起來比較慢,為了提高自學課件的效率,故我花了點時間將其翻譯成中文,以便將來自己快速復習用。
該版僅用于個人學習之用。
再次,譯者因工作中需要用到數據分析、風險可視化與管理,因此學習python,翻譯水平有限,請諒解。
在征得原作者Yupeng Jiang老師的同意后,現在我將中文版本分享給大家。
作者:Dr.Yupeng Jiang
- 倫敦大學學院 數學系 (全球頂尖大學,世界排名第7 《2018QS世界大學排名》,英國排名第3)
- 2016年6月5日
- [原版課件來自] https://zhuanlan.zhihu.com/p/21332075
- [中文版的說明] https://zhuanlan.zhihu.com/p/29184240
翻譯:Murphy Wan
大綱( Outline)
第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 np
import pandas as pd
df = pd.DataFrame([10, 20, 30, 40], \
columns = [’Numbers’], \
index = [’a’, ’b’, ’c’, ’d’])
- 讓我們看下DataFrame對象。它是顯示如下:
- 我們可以執行以下代碼在DataFrame對象中顯示一些典型的操作。
import pandas as pd
df = pd.DataFrame([10, 20, 30, 40], \
columns = [’Numbers’], \
index = [’a’, ’b’, ’c’, ’d’])
print(df.index) #顯示索引 show index
print(df.columns) #顯示列名 show column names
print(df.ix[’c’]) #通過索引選擇 select via index
print(df.ix[[’a’, ’d’]]) # 多選 multi-select
print(df.ix[df.index[1:3]]) # 其他another
print(df.sum()) # 每列求和 sum per column
ts = df ** 2 # 創建新的DataFrame create new DataFrame
print(ts)
放大DataFrame
import pandas as pd
df = pd.DataFrame([10, 20, 30, 40], \
columns = [’Numbers’], \
index = [’a’, ’b’, ’c’, ’d’])
#add a new column called ’floats’ directly
df[’floats’] = (1.5, 2.5, 3.5, 4.5)
#add a new column called ’names’ by index
df[’names’] = pd.DataFrame([’Dan’, \
’Cox’, ’Ale’, ’Bob’], \
index = [’d’, ’c’, ’a’, ’b’])
# add a new object to df
df = 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’) #<--squares
- 我們注意到沒有由“\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 pd
import pandas.io.data as web
FT = web.DataReader(name = ’^FTSE’, \
data_source = ’yahoo’, \
start = ’2000-1-1’)
print(FT.info()) # show information
print(FT.tail()) # show last 5 rows
# plot the FTSE 100 graph
FT[’Close’].plot(figsize = (8, 6), \
grid = True)
計算每日回報 (Calculate the daily return)
import pandas as pd
import pandas.io.data as web
import numpy as np
FT = 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 pd
import pandas.io.data as web
import numpy as np
FT = 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 pd
import pandas.io.data as web
import numpy as np
FT = 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 pd
import pandas.io.data as web
import numpy as np
FT = 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 npr
import matplotlib.pyplot as plt
import numpy as np
X = 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 np
import numpy.random as npr
from scipy.stats import norm
S = 100; K = 100; T = 1
r = 0.05; vol = 0.5
I = 10000 # MC paths
Z = 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 pd
import pandas.io.data as web
import numpy as np
FT = 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 pd
import pandas.io.data as web
import numpy as np
import statsmodels.api as sm
import matplotlib.pyplot as plt
FT = 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’)
QQ-plot
Skew and kurtosis (斜度與峰值?)
import pandas.io.data as web
import numpy as np
import scipy.stats as scs
FT = 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 nan
print(’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圖。
三天全部結束,辛苦了!想必你也獲得了不少收獲!繼續加油,讓我們做的更好!
傳送門-->回到第二天(Day1)
傳送門-->回到第一天(Day2)