【手把手教你】使用pyfinance進行證券收益分析

pyfinance簡介


在查找如何使用Python實現(xiàn)滾動回歸時吝镣,發(fā)現(xiàn)一個很有用的量化金融包——pyfinance。顧名思義,pyfinance是為投資管理和證券收益分析而構建的Python分析包,主要是對面向定量金融的現(xiàn)有包進行補充,如pyfolio和pandas等凰荚。pyfinance包含六個模塊燃观,


  • datasets.py :金融數(shù)據(jù)下載(基于request進行數(shù)據(jù)爬蟲,有些數(shù)據(jù)由于外網(wǎng)受限已經(jīng)無法下載)便瑟;

  • general.py:通用財務計算缆毁,例如主動份額計算,收益分配近似值和跟蹤誤差優(yōu)化到涂;

  • ols.py:回歸分析脊框,支持pandas滾動窗口回歸;

  • options.py:期權衍生品計算和策略分析践啄;

  • returns.py:通過CAPM框架對財務時間序列進行統(tǒng)計分析浇雹,旨在模擬FactSet Research Systems和Zephyr等軟件的功能,并提高了速度和靈活性屿讽;

  • utils.py:基礎架構昭灵。


  • 本文主要圍繞returns模塊,介紹pyfinance在證券投資分析中的應用,后續(xù)將逐步介紹datasets烂完、options试疙、ols等模塊。


    returns模塊應用實例


    pyfinance的安裝比較簡單抠蚣,直接在cmd(或anaconda prompt)上輸入"pip install pyfinance"即可祝旷。returns模塊主要以TSeries類為主體(暫不支持dataframe),相當于對pandas的Series進行類擴展嘶窄,使其實現(xiàn)更多功能怀跛,支持證券投資分析中基于CAMP(資本資產定價模型)框架的業(yè)績評價指標計算。引用returns模塊時护侮,直接使用"from pyfinance import TSeries"即可敌完。



    下面以tushare為數(shù)據(jù)接口,先定義一個數(shù)據(jù)獲取函數(shù)羊初,在函數(shù)里對收益率數(shù)據(jù)使用TSeries進行轉換滨溉,之后便可以直接使用TSeries類的相關函數(shù)。

    import?pandas?as?pd??
    import?numpy?as?np
    from?pyfinance?import?TSeries
    import?tushare?as?ts
    def?get_data(code,start='2011-01-01',end=''):
    ????df=ts.get_k_data(code,start,end)
    ????df.index=pd.to_datetime(df.date)
    ????ret=df.close/df.close.shift(1)-1
    ????#返回TSeries序列
    ????return?TSeries(ret.dropna())

    #獲取中國平安數(shù)據(jù)
    tss=get_data('601318')
    #tss.head()


    01收益率計算


    pyfinance的returns提供了年化收益率(anlzd_ret)长赞、累計收益率(cuml_ret)和周期收益率(rollup)等晦攒,下面以平安銀行股票為例,計算收益率指標得哆。

    #年化收益率
    anl_ret=tss.anlzd_ret()
    #累計收益率
    cum_ret=tss.cuml_ret()
    #計算周期收益率
    q_ret=tss.rollup('Q')
    a_ret=tss.rollup('A')

    print(f'年化收益率:{anl_ret*100:.2f}%')
    print(f'累計收益率:{cum_ret*100:.2f}%')
    #print(f'季度收益率:{q_ret.tail().round(4)}')
    #print(f'歷年收益率:{a_ret.round(4)}')

    輸出結果:

    累計收益率:205.79%

    年化收益率:12.24%


    可視化每個季度(年)收益率

    from?pyecharts?import?Bar
    attr=q_ret.index.strftime('%Y%m')
    v1=(q_ret*100).round(2).values
    bar=Bar('中國平安各季度收益率%')
    bar.add('',attr,v1,)
    bar


    from?pyecharts?import?Bar
    attr=a_ret.index.strftime('%Y')
    v1=(a_ret*100).round(2).values
    bar=Bar('中國平安歷年收益率%')
    bar.add('',attr,v1,is_label_show=True,
    ???????is_splitline_show=False)
    bar


    02CAPM模型相關指標


    基于CAPM模型計算alpha脯颜、beta、回歸決定系數(shù)R2贩据、t統(tǒng)計量和殘差項等栋操。實際上主要使用了ols回歸,因此如果要獲得這些動態(tài)的alpha和beta值饱亮,可以進一步借助ols模塊的滾動回歸函數(shù)(PandasRollingOLS)了矾芙,這將在后續(xù)推文介紹其應用。


    #以滬深300指數(shù)為基準
    #為保證二者長度一致近上,以中國平安的索引為準
    benchmark=get_data('hs300')
    benchmark=benchmark.loc[tss.index]

    alpha,beta,rsq=tss.alpha(benchmark),tss.beta(benchmark),tss.rsq(benchmark)
    tstat_a,tstat_b=tss.tstat_alpha(benchmark),tss.tstat_beta(benchmark)
    print(f'alpha:{alpha:.4f}剔宪,t統(tǒng)計量:{tstat_a:.2f}')
    print(f'beta?:{beta:.4f},t統(tǒng)計量:{tstat_b:.2f}')
    print(f'回歸決定系數(shù)R2:{tss.rsq(benchmark):.3f}')

    alpha:0.0004壹无,t統(tǒng)計量:1.55
    beta?:1.0634葱绒,t統(tǒng)計量:60.09
    回歸決定系數(shù)R2:0.606


    03風險指標


    風險指標主要包括標準差和最大回撤。在計算標準差時斗锭,注意需要修改默認參數(shù)地淀,打開pyfinance安裝包所在路徑,如果是安裝了Anaconda岖是,進入以下路徑:

    c:\Anaconda3\Lib\site-packages\pyfinance骚秦,打開returns源文件她倘,找到anlzd_stdev和semi_stdev函數(shù),將freq默認None改成250(一年的交易天數(shù))作箍。


    #年化標準差
    a_std=tss.anlzd_stdev()
    #下行標準差
    s_std=tss.semi_stdev()
    #最大回撤
    md=tss.max_drawdown()
    print(f'年化標準差:{a_std*100:.2f}%')
    print(f'下偏標準差:{s_std*100:.2f}%')
    print(f'最大回撤差:{md*100:.2f}%')

    年化標準差:31.37%
    下偏標準差:0.43%
    最大回撤差:-45.76%


    下偏標準差主要是為解決收益率分布的不對稱問題硬梁,當收益率函數(shù)分布左偏的情況下,使用正態(tài)分布會低估風險胞得,因此使用傳統(tǒng)夏普比率分母使用全樣本標準差進行估計不太合適荧止,應使用收益對無風險投資收益的偏離。


    04基準比較指標


    基準比較指標是需要指定一個基準(benchmark)阶剑,如將滬深300指數(shù)作為中國平安個股的基準進行比較分析跃巡。

    bat=tss.batting_avg(benchmark)
    uc=tss.up_capture(benchmark)
    dc=tss.down_capture(benchmark)
    tc=uc/dc
    pct_neg=tss.pct_negative()
    pct_pos=tss.pct_positive()
    print(f'比基準收益高的時間占比:{bat*100:.2f}%')
    print(f'上行期與基準收益比:{uc*100:.2f}%')
    print(f'下行期與基準收益比:{dc*100:.2f}%')
    print(f'上行期與下行期比:{tc*100:.2f}%')
    print(f'個股下行(收益負)時間占比:{pct_neg*100:.2f}%')
    print(f'個股上行(收益正)時間占比:{pct_pos*100:.2f}%')

    比基準收益高的時間占比:47.83%
    上行期與基準收益比:111.70%
    下行期與基準收益比:105.32%
    上行期與下行期比:106.06%
    個股下行(收益負)時間占比:48.94%
    個股上行(收益正)時間占比:50.00%


    此外,信息比率特雷諾指數(shù)是兩個常用的基準比較評價指標牧愁,特別是用于對基金產品或投資組合的業(yè)績進行量化評價素邪。


  • 信息比率(information ratio):以馬克維茨的均值方差模型為基礎,衡量超額風險所帶來的超額收益猪半,表示單位主動風險所帶來的超額收益兔朦。IR=α ∕ ω (α為組合的超額收益,ω為主動風險)磨确,分子α為真實預期收益率與定價模型所計算出的收益率的差沽甥,分母為殘差風險即殘差項的標準差。

  • 特雷諾指數(shù)(Treynor ratio):衡量單位風險的超額收益乏奥,計算公式為:TR=(Rp―Rf)/βp摆舟,其中:TR表示特雷諾業(yè)績指數(shù),Rp表示某投資組合平均收益率邓了,Rf為平均無風險利率恨诱,βp表示某投資組合的系統(tǒng)風險。

  • ir=tss.info_ratio(benchmark)
    tr=tss.treynor_ratio(benchmark)
    print(f'信息比率:{ir:.3f}')
    print(f'特雷諾指數(shù):{tr:.3f}')
    信息比率:0.433
    特雷諾指數(shù):0.096



    05風險調整收益指標


    風險調整收益率指標比較常用的有夏普比率(sharpe ratio)骗炉、索提諾比率(sortino ratio)和卡瑪比率(calmar ratio)照宝,這三個指標都是風險調整后收益比率,因此分子都是收益指標痕鳍,分母都是風險指標。

  • 夏普比率(Sharpe Ratio):風險調整后的收益率龙巨,計算公式:=[E(Rp)-Rf]/σp笼呆,其中E(Rp):投資組合預期報酬率,Rf:無風險利率旨别,σp:投資組合的標準差诗赌。計算投資組合每承受一單位總風險,會產生多少的超額報酬秸弛。

  • 索提諾比率(Sortino Ratio):與夏普比率思路一致铭若,核心在于分母應用了下行波動率概念(Downside Risk)洪碳,計算標準差的時候,不采用均值叼屠,而是一個設定的可接受最小收益率(r_min)瞳腌,收益率序列中,超出這個最小收益率的收益距離按照0計算镜雨,低于這個收益率的平方距離累積嫂侍,這樣標準差就變成了半個下行標準差。對應的荚坞,索提諾比率的分子也采用策略收益超出最低收益的部分挑宠。與夏普比率相比,索提諾比率更看重對(左)尾部的預期損失分析颓影,而夏普比率則是對全體樣本進行分析各淀。

  • Calmar比率(Calmar Ratio) :描述收益和最大回撤之間的關系,計算方式為年化收益率與歷史最大回撤之間的比率诡挂。Calmar比率數(shù)值越大碎浇,投資組合業(yè)績表現(xiàn)越好。

  • sr=tss.sharpe_ratio()
    sor=tss.sortino_ratio(freq=250)
    cr=tss.calmar_ratio()
    print(f'夏普比率:{sr:.2f}')
    print(f'索提諾比率:{sor:.2f}')
    print(f'卡瑪比率:{cr:.2f}')

    夏普比率:0.33
    索提諾比率:28.35
    卡瑪比率:0.27


    06綜合業(yè)績評價指標分析實例


    下面將上述常用指標進行綜合咆畏,并獲取多只個股進行比較分析南捂。

    def?performance(code,start='2011-01-01',end=''):
    ????tss=get_data(code,start,end)
    ????benchmark=get_data('hs300',start,end).loc[tss.index]
    ????dd={}
    ????#收益率
    ????#年化收益率
    ????dd['年化收益率']=tss.anlzd_ret()
    ????#累積收益率
    ????dd['累計收益率']=tss.cuml_ret()
    ????#alpha和beta
    ????dd['alpha']=tss.alpha(benchmark)
    ????dd['beta']=tss.beta(benchmark)
    ????#風險指標
    ????#年化標準差
    ????dd['年化標準差']=tss.anlzd_stdev()
    ????#下行標準差
    ????dd['下行標準差']=tss.semi_stdev()
    ????#最大回撤
    ????dd['最大回撤']=tss.max_drawdown()
    ????#信息比率和特雷諾指數(shù)
    ????dd['信息比率']=tss.info_ratio(benchmark)
    ????dd['特雷納指數(shù)']=tss.treynor_ratio(benchmark)
    ????#風險調整收益率
    ????dd['夏普比率']=tss.sharpe_ratio()
    ????dd['索提諾比率']=tss.sortino_ratio(freq=250)
    ????dd['calmar比率']=tss.calmar_ratio()
    ????df=pd.DataFrame(dd.values(),index=dd.keys()).round(4)
    ????return?df


    獲取多只個股(也構建投資組合)數(shù)據(jù),對比評估業(yè)績評價指標:


    #獲取多只股票數(shù)據(jù)

    df=pd.DataFrame(index=performance('601318').index)
    stocks={'中國平安':'601318','貴州茅臺':'600519',\
    ????????'海天味業(yè)':'603288','格力電器':'000651',\
    ????????'萬科A':'00002','比亞迪':'002594',\
    ????????'云南白藥':'000538','雙匯發(fā)展':'000895',\
    ????????'海爾智家':'600690','青島啤酒':'600600'}
    for?name,code?in?stocks.items():
    ????try:
    ????????df[name]=performance(code).values
    ????except:
    ????????continue

    df



    結語


    pyfinance主要為證券投資管理和績效評價指標而設計的python包旧找,對于考CFA和FRM的讀者相當實用溺健。實際上,pyfinance的returns模塊是對pandas的Series類進行了擴展钮蛛,從而支持證券投資收益分析和績效評價鞭缭。Python是建立在各種輪子上(module)的“膠水”語言,因此善于借用已有的包進行計算和編程魏颓,可以提高效率岭辣,減少自己“造輪子”的時間和精力。本文主要介紹了pyfinance中returns模塊的應用甸饱,其他模塊的應用將在后續(xù)推文中進行介紹沦童。

    最后編輯于
    ?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
    • 序言:七十年代末,一起剝皮案震驚了整個濱河市叹话,隨后出現(xiàn)的幾起案子偷遗,更是在濱河造成了極大的恐慌,老刑警劉巖驼壶,帶你破解...
      沈念sama閱讀 217,185評論 6 503
    • 序言:濱河連續(xù)發(fā)生了三起死亡事件氏豌,死亡現(xiàn)場離奇詭異,居然都是意外死亡热凹,警方通過查閱死者的電腦和手機泵喘,發(fā)現(xiàn)死者居然都...
      沈念sama閱讀 92,652評論 3 393
    • 文/潘曉璐 我一進店門泪电,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人纪铺,你說我怎么就攤上這事相速。” “怎么了霹陡?”我有些...
      開封第一講書人閱讀 163,524評論 0 353
    • 文/不壞的土叔 我叫張陵和蚪,是天一觀的道長。 經(jīng)常有香客問我烹棉,道長攒霹,這世上最難降的妖魔是什么? 我笑而不...
      開封第一講書人閱讀 58,339評論 1 293
    • 正文 為了忘掉前任浆洗,我火速辦了婚禮催束,結果婚禮上,老公的妹妹穿的比我還像新娘伏社。我一直安慰自己抠刺,他們只是感情好,可當我...
      茶點故事閱讀 67,387評論 6 391
    • 文/花漫 我一把揭開白布摘昌。 她就那樣靜靜地躺著速妖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪聪黎。 梳的紋絲不亂的頭發(fā)上罕容,一...
      開封第一講書人閱讀 51,287評論 1 301
    • 那天,我揣著相機與錄音稿饰,去河邊找鬼锦秒。 笑死,一個胖子當著我的面吹牛喉镰,可吹牛的內容都是我干的旅择。 我是一名探鬼主播,決...
      沈念sama閱讀 40,130評論 3 418
    • 文/蒼蘭香墨 我猛地睜開眼侣姆,長吁一口氣:“原來是場噩夢啊……” “哼生真!你這毒婦竟也來了?” 一聲冷哼從身側響起捺宗,我...
      開封第一講書人閱讀 38,985評論 0 275
    • 序言:老撾萬榮一對情侶失蹤柱蟀,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后偿凭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體产弹,經(jīng)...
      沈念sama閱讀 45,420評論 1 313
    • 正文 獨居荒郊野嶺守林人離奇死亡派歌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
      茶點故事閱讀 37,617評論 3 334
    • 正文 我和宋清朗相戀三年弯囊,在試婚紗的時候發(fā)現(xiàn)自己被綠了痰哨。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
      茶點故事閱讀 39,779評論 1 348
    • 序言:一個原本活蹦亂跳的男人離奇死亡匾嘱,死狀恐怖斤斧,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情霎烙,我是刑警寧澤撬讽,帶...
      沈念sama閱讀 35,477評論 5 345
    • 正文 年R本政府宣布,位于F島的核電站悬垃,受9級特大地震影響游昼,放射性物質發(fā)生泄漏。R本人自食惡果不足惜尝蠕,卻給世界環(huán)境...
      茶點故事閱讀 41,088評論 3 328
    • 文/蒙蒙 一烘豌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧看彼,春花似錦廊佩、人聲如沸。這莊子的主人今日做“春日...
      開封第一講書人閱讀 31,716評論 0 22
    • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至茁计,卻和暖如春料皇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背簸淀。 一陣腳步聲響...
      開封第一講書人閱讀 32,857評論 1 269
    • 我被黑心中介騙來泰國打工瓶蝴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人租幕。 一個月前我還...
      沈念sama閱讀 47,876評論 2 370
    • 正文 我出身青樓舷手,卻偏偏與公主長得像,于是被迫代替她去往敵國和親劲绪。 傳聞我的和親對象是個殘疾皇子男窟,可洞房花燭夜當晚...
      茶點故事閱讀 44,700評論 2 354