量化学习——三因子组合

#三因子模型中的3个因子均为投资组合的收益率:
# 市场风险溢酬因子(Rmt)对应了(市场投资组合的收益率减去无风险利率);

# 市值因子(SMB)对应了做多市值较小的公司与做空市值较大的公司的投资组合带来的收益率;

# 账面市值比因子(HML)对应的是做多高BM公司、做空低BM公司的投资组合带来的收益率。

import baostock as bs
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams ['font.sans-serif'] ='SimHei'               #显示中文
plt.rcParams ['axes.unicode_minus']=False               #显示负号

factors = pd.read_csv('fivefactor_daily.csv', index_col = 'trddy',parse_dates=['trddy'])
factors = factors[['mkt_rf','rf','smb','hml']].copy()
three_factors = factors['2021-11-01':'2022-11-1']
three_factors = three_factors.reset_index()
three_factors = three_factors.rename(columns={'trddy':'date'})
three_factors.head()
lg = bs.login()
# 获取沪深A股601318的历史K线数据
rs_result = bs.query_history_k_data_plus("sh.601318",  fields="date,open,high,low,close,volume",   
                        start_date='2021-11-01',   end_date='2022-11-1',  
                        frequency="d",  adjustflag="3")
df_result = rs_result.get_data()
bs.logout()
df_result=df_result.set_index('date')
df_result=df_result.astype('float64')
df_result = df_result.reset_index()
df_result.head()
#收益率计算分析
#计算对数收益率,画图查看
day_return = np.log(df_result['close'] /df_result['close'].shift(1))
day_return.dropna(inplace = True)
day_return.name = 'Return'
day_return.plot(figsize=(7,3))
plt.title('中国平安日收益率')
plt.show()

 

#将因子数据和每日的对数收益率合并
#zgpa_threefactor = pd.merge(three_factors, day_return,left_index=True, right_index=True)
zgpa_threefactor= pd.merge(three_factors, day_return,left_index=True,right_index=True)
zgpa_threefactor = zgpa_threefactor.set_index('date')
zgpa_threefactor.head()
#画散点图进行分析

sns.pairplot(zgpa_threefactor[['mkt_rf','smb','hml','Return']])

 sns.heatmap(zgpa_threefactor[['mkt_rf','smb','hml','Return']].corr(),annot=True,square=True)

 

 

#回归模型
import statsmodels.api as sm
result = sm.OLS(zgpa_threefactor['Return'], sm.add_constant(zgpa_threefactor.loc[:,['mkt_rf','smb','hml']])).fit()
result.summary()

 

#其他指标计算 
def sum_return_ratio(price_list):
    '''实际总收益率'''
    price_list=price_list.to_numpy()
    return (price_list[-1]-price_list[0])/price_list[0]
def MaxDrawdown(price_list):
    '''最大回撤率'''
    i = np.argmax((np.maximum.accumulate(price_list) - price_list) / np.maximum.accumulate(price_list))  # 结束位置
    if i == 0:
        return 0
    j = np.argmax(price_list[:i])  # 开始位置
    return (price_list[j] - price_list[i]) / (price_list[j])
def sharpe_ratio(price_list,rf=0.000041):
    '''夏普比率'''
    #公式 夏普率 = (回报率均值 - 无风险率) / 回报率的标准差
    # pct_change()是pandas里面的自带的计算每日增长率的函数
    daily_return = price_list.pct_change()
    return daily_return.mean()-rf/ daily_return.std()
def Information_Ratio(price_list,rf=0.000041):
    '''信息比率'''
    chaoer=sum_return_ratio(price_list)-((1+rf)**365-1)
    return chaoer/np.std(price_list.pct_change()-rf)
#计算上述的中国平安的相应的四个指标为:
sum_return_ratio(df_result['close']),MaxDrawdown(df_result['close']),sharpe_ratio(df_result['close']),Information_Ratio(df_result['close'],rf=0.000041)
#多公司对比 
def deal(stock='sh.601318',start_date='2021-11-01',end_date='2022-11-1'):
    lg = bs.login()
    rs_result = bs.query_history_k_data_plus(stock,  fields="date,close", start_date=start_date,end_date=end_date, frequency="d", adjustflag="3")
    df_result = rs_result.get_data()
    df_result=df_result.set_index('date')
    df_result=df_result.astype('float64')
    bs.logout()
    three_factors = factors[start_date:end_date]
    three_factors = three_factors.reset_index()
    three_factors = three_factors.rename(columns={'trddy':'date'})
    
    assert len(three_factors)==len(df_result), "数量长度不一样" 
    # print(three_factors.head())
    day_return = np.log(df_result['close'] /df_result['close'].shift(1))
    day_return.dropna(inplace = True)
    day_return.name = 'Return'
    day_return = day_return.reset_index()
    
    zgpa_threefactor = pd.merge(three_factors, day_return,left_index=True, right_index=True)
    #zgpa_threefactor = zgpa_threefactor.set_index('date')
    print(zgpa_threefactor.head())
    result = sm.OLS(zgpa_threefactor['Return'], sm.add_constant(zgpa_threefactor.loc[:,['mkt_rf','smb','hml']])).fit()
    betas=result.params
    实际总收益率=sum_return_ratio(df_result['close'])
    最大回测率=MaxDrawdown(df_result['close'])
    夏普比率=sharpe_ratio(df_result['close'])
    信息比率=Information_Ratio(df_result['close'])
    return pd.DataFrame({'阿尔法':betas[0],'贝塔':betas[1],'市值因子SMB':betas[2],'账面市值因子HML':betas[3],
                        '实际总收益率':实际总收益率,'最大回测率':最大回测率,'夏普比率':夏普比率,'信息比率':信息比率},index=[stock])

deal(stock='sh.601318')

stocks=['sh.601318','sh.600519','sh.600416','sh.600765','sh.600535','sz.300129','sh.600036','sz.000001']
df_deals=pd.DataFrame()
for s in stocks:
    df_deal=deal(stock=s)
    df_deals=pd.concat([df_deals,df_deal],axis=0)

df_deals

 

 文章所用文件,我上传到资源库,自己下载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

神出鬼没,指的就是我!

必须花钱,数据超好

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值