日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python量化交易05——基于多因子选择和选股策略(随机森林,LGBM)

發布時間:2024/5/8 python 128 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python量化交易05——基于多因子选择和选股策略(随机森林,LGBM) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??參考書目:深入淺出Python量化交易實戰


在機器學習里面的X叫做特征變量,在統計學里面叫做協變量也叫自變量,在量化投資里面則叫做因子,所謂多因子就是有很多的特征變量。

本次帶來的就是多因子模型,并且使用的是機器學習的強大的非線性模型,集成學習里面的隨機森林和LGBM模型,帶來因子的選擇策略和股票的選擇策略。


由于股票數據的獲取都需要第三方庫或者是專業的量化投資框架,很多第三方庫某些功能需要收費(Tushare),而免費的一些庫(證券寶)獲取的數據特征變量又沒那么多。所以這里是用聚寬量化投資框架,是可以免費使用一些功能的(只需要注冊一個賬號)。這里獲取數據就采用聚寬平臺的功能了。


數據獲取

本次使用滬深300作為股票池,選獲取一些財務指標:

#創建query對象,指定獲取股票的代碼、市值、凈運營資本
#凈債務、產權比率、股東權益比率、營收增長率、換手率、
#市盈率(PE)、市凈率(PB)、市銷率(PS)、總資產收益率因子

#還是先導入jqdata和技術分析工具 import jqdata from jqlib.technical_analysis import * #同樣選擇滬深300成分股做股票池 stocks = get_index_stocks('000300.XSHG')q = query(valuation.code, valuation.market_cap,balance.total_current_assets- balance.total_current_liability,balance.total_liability- balance.total_assets,balance.total_liability/balance.equities_parent_company_owners,(balance.total_assets-balance.total_current_assets)/balance.total_assets,balance.equities_parent_company_owners/balance.total_assets,indicator.inc_total_revenue_year_on_year,valuation.turnover_ratio,valuation.pe_ratio,valuation.pb_ratio,valuation.ps_ratio,indicator.roa).filter(valuation.code.in_(stocks)) #將獲得的因子值存入一個數據表 df = get_fundamentals(q, date = None) #把數據表的字段名指定為對應的因子名 df.columns = ['code', '市值', '凈營運資本', '凈債務', '產權比率','非流動資產比率','股東權益比率', '營收增長率','換手率','PE','PB','PS','總資產收益率'] #檢查結果 df.head()

?

?需要在聚寬的環境才能獲得上面的數據,本地Python是出不來的。

設置一下股票代碼作為索引,獲取一些時間格式。

#將股票代碼作為數據表的index df.index = df.code.values #使用del也可以刪除列 del df['code'] #下面來把時間變量都定義好 today = datetime.datetime.today() #設定3個時間差,分別是50天,1天和2天 delta50 = datetime.timedelta(days=50) delta1 = datetime.timedelta(days=1) delta2 = datetime.timedelta(days=2) #50日前作為一個歷史節點 history = today - delta50 #再計算昨天和2天前的日期 yesterday = today - delta1 two_days_ago = today - delta2

再然后獲取一些技術指標數據:

#下面就獲取股票的動量線、成交量、累計能量線、平均差、
#指數移動平均、移動平均、乖離率等因子
#時間范圍都設為10天

df['動量線']=list(MTM(df.index, two_days_ago, timeperiod=10, unit = '1d', include_now = True, fq_ref_date = None).values())df['成交量']=list(VOL(df.index, two_days_ago, M1=10 ,unit = '1d', include_now = True, fq_ref_date = None)[0].values())df['累計能量線']=list(OBV(df.index,check_date=two_days_ago, timeperiod=10).values())df['平均差']=list(DMA(df.index, two_days_ago, N1 = 10, unit = '1d', include_now = True, fq_ref_date = None)[0].values())df['指數移動平均']=list(EMA(df.index, two_days_ago, timeperiod=10, unit = '1d', include_now = True, fq_ref_date = None).values())df['移動平均']=list(MA(df.index, two_days_ago, timeperiod=10, unit = '1d', include_now = True, fq_ref_date = None).values())df['乖離率']=list(BIAS(df.index,two_days_ago, N1=10, unit = '1d', include_now = True, fq_ref_date = None)[0].values()) #把數據表中的空值用0來代替 df.fillna(0,inplace=True) #檢查是否成功 df.head()

這樣就獲得了很多X,即特征變量,即因子。

下面構建y,我們的響應變量是一個分類的變量,即是否獲得了超過市場的平均回報的收益率,是的話為1,不是為0 。

這里使用前一日的收盤價除以前50天的收盤價?然后減去1,作為收益率的值,計算出那些收益率大于均值的樣本股則y為1 ,否則為0 。

#獲取股票前一日的收盤價 df['close1']=list(get_price(stocks, end_date=yesterday, count = 1,fq='pre',panel=False)['close']) #獲取股票50日前的收盤價 df['close2']=list(get_price(stocks, end_date=history, count = 1,fq ='pre',panel=False)['close'])#計算出收益 df['return']=df['close1']/df['close2']-1 #如果收益大于平均水平,則標記為1 #否則標記為0 df['signal']=np.where(df['return']<df['return'].mean(),0,1) #檢查是否成功 df.head()

?可以看到最后一列是我們的響應變量y。


模型構建

將X和y都準備好。劃分訓練集和測試集,導入隨機森林分類器。

#導入數據集拆分工具 from sklearn.model_selection import train_test_split #導入隨機森林分類器 from sklearn.ensemble import RandomForestClassifier #把因子值作為樣本的特征,所以要去掉剛剛添加的幾個字段 X = df.drop(['close1', 'close2', 'return', 'signal'], axis = 1) #把signal作為分類標簽 y = df['signal'] #將數據拆分為訓練集和驗證集 X_train,X_test,y_train,y_test=train_test_split(X,y,test_size = 0.2) #創建隨機森林分類器實例,指定random_state便于復現 clf = RandomForestClassifier(n_estimators=5000,random_state=100) #擬合訓練集數據 clf.fit(X_train, y_train) #查看分類器在訓練集和驗證集中的準確率 print(clf.score(X_train, y_train),clf.score(X_test, y_test))

?

分類問題,所以采用隨機森林分類器,然后進行擬合和評價。

可以看到在訓練集上的準確率為100%,在測試集刪高的準確率為0.9333,說明模型的擬合效果很不錯。


?

?因子重要性

接下來使用隨機森林的變量的重要性排序,原理是基礎學習器決策樹分裂時,若一個變量分裂時讓損失函數下降得越多,說明這個變量越重要。

#為了便于觀察,我們創建一個數據表
#數據表有兩個字段,分別是特征名和重要性
#特征名就是因子的名稱

factor_weight = pd.DataFrame({'features':list(X.columns),'importance':clf.feature_importances_}).sort_values(#這里根據重要程度降序排列,一遍遍找到重要性最高的特征by='importance', ascending = False) #檢查結果 factor_weight

?可以看到最重要的變量是技術指標平均差。這也是肯定的,因為平均差里面包含了過去和現在的股價信息最多,和我們的響應變量最為相似。

畫圖更加直觀的查看變量重要性排序。

import seaborn as sns plt.figure(figsize=(6,4),dpi=128) sns.barplot(y=factor_weight['features'],x=factor_weight['importance'],orient="h") plt.xlabel('重要程度') plt.ylabel('因子名稱') plt.xticks(fontsize=10,rotation=35) plt.title("因子重要性對比") plt.show()

?和上面結論一樣,技術指標平均差對我們的響應變量是否獲得超額回報的影響最大,然后是公司本身的財務指標,營業收入增長率,凈收運營資本等。


選股策略

接下來我們使用對于表格數據最強的機器學習方法,輕量梯度提升方法——LGBM模型,對我們的股票市值進行預測,然后選取實際值和預測值差距最大的股票作為選股策略。即選取價值被低估的股票。

此時y是股票市值,X是前面那些財務技術指標

X=df.iloc[:,1:-3] y=df.iloc[:,0]

構建回歸器

from lightgbm import LGBMRegressor model = LGBMRegressor(n_estimators=100,objective='regression', random_state=0) model.fit(X, y) model.score(X, y)

?整體模型的擬合優度為86%,還不錯。

用真實值減去預測值,然后進行排序,算的找出前10 的被低估的公司

diff = pd.DataFrame(np.array(y)-model.predict(X), index = y.index, columns = ['預測值和真實值的差值']) #將該數據表中的值,按生序進行排列 diff = diff.sort_values(by = '預測值和真實值的差值', ascending = True) #找到市值被低估最多的10只股票 diff.head(10)

?前十都是被低估了,負得越多說明被低估的越厲害。


?受限于框架的使用,該策略我本人沒有進行回測檢驗其收益率。書上的收益率大概是年化6%,不高,但是也算不錯了。

(本案例僅作為策略研究,不構成任何投資意見。)

總結

以上是生活随笔為你收集整理的Python量化交易05——基于多因子选择和选股策略(随机森林,LGBM)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。