线性回归和量化交易基础(上)

回归法选股,是做以下几件事

1. 判断因子和股票收益的相关性

2. 选择合适的因子

3. 整理数据 判断横截面下 上个月的月末,因子对下个月初的股票的影响, 每个月统计一次,用系数表示

4. 当我们确定了所有因子对股票的影响后,就可以用回归方程来选择合适的股票,也即判断大盘中股票得分最高的 (沪深300也可以)

 

所用数学技术:

1. 标准化

2. 三倍中位数去极值

3. 市场中性化

4. 主成分分析

 

下面的代码获取total_data的数据

 1 import numpy as np
 2 import pandas as pd
 3 import datetime
 4 
 5 # 训练回测区间
 6 # 准备好因子对应日期的数据 获取每个月月末的数据
 7 dates=get_trading_dates(start_date="2008-01-01",end_date="2018-01-01")
 8 
 9 month_date=[]
10 for i in range(len(dates)-1):
11     if dates[i].year!=dates[i+1].year:
12         month_date.append(dates[i])
13     elif dates[i].month!=dates[i+1].month:
14         month_date.append(dates[i])
15 
16 month_date.append(dates[-1])
17 
18 # 获取沪深300的股票列表
19 stocks=index_components("000300.XSHG")
20 
21 total_data=pd.DataFrame()
22 
23 for date in month_date[:-1]:
24     q=query(fundamentals.eod_derivative_indicator.pe_ratio,
25        fundamentals.eod_derivative_indicator.market_cap,
26        fundamentals.eod_derivative_indicator.pb_ratio,
27        fundamentals.financial_indicator.return_on_equity,
28        fundamentals.financial_indicator.cost_to_sales,
29        fundamentals.income_statement.r_n_d,
30        fundamentals.income_statement.operating_revenue,
31        fundamentals.income_statement.net_profit,
32        fundamentals.income_statement.total_expense).filter(
33        fundamentals.stockcode.in_(stocks))
34     
35     fund=get_fundamentals(q,entry_date=date)
36     fund["date"]=date
37     fund=fund.to_frame()
38     # 数据拼接 处理数据格式
39     total_data=pd.concat([total_data,fund])
total_data=total_data.dropna() #把缺失值去除
total_data["next_month_return"]=np.nan
total_data.head()

 

 

 在上面我们看到了pandas.DataFrame中的数据

 下面计算收益率

total_price=pd.DataFrame()
for date in month_date:
    price=get_price(stocks,start_date=date,end_date=date,fields="close")
    total_price=pd.concat([total_price,price])

total_price=total_price.T
total_price = total_price.dropna()

for i in range(len(total_price.columns)-1):
    total_price.iloc[:,i] = (total_price.iloc[:,i+1] / total_price.iloc[:,i]) -1

total_price.head()

 

下面我们把收益率填充到total_data中

## 将收益率填充到total_data中
for i in range(len(total_data)):
    # 这里是一个tuple
    stock=total_data.index[i][1]
    
    date = total_data.ix[i,'date']
#     ans=total_price.columns[i].to_pydatetime().date()
#     print(ans)
#     print(type(total_price.columns[0]))
#     print(type(ans))
#     total_price.columns.iloc(i)=ans
#     print(stock in total_price.index)
#     print(str(stock))
    
    # got a stupid mistake !!! Just Instead [] with ()
    if stock in total_price.index and date == ans:
        total_data.ix[i,"next_month_return"]=total_price.loc[stock,date]

图示如下:

 

 

我们然后确定x,y即可,实际上一行的值,除了date和next_month_return 都是系数,只有next_month_return 是因变量

 

利用stand函数

def stand(factor):
    mean=np.mean(factor)
    std=np.std(factor)
    return (factor-mean)/std

和mad函数

def mad(factor):
    med=np.median(factor)
    mad=np.median(np.abs(factor-med))
    high=med+3*1.4826*mad
    low=med-3*1.4826*mad
    factor=np.where(factor>high,high,factor)
    factor=np.where(factor<low,low,factor)
    return factor

将值去极值并标准化

 

posted @ 2021-03-25 22:05  ProgrammerZT  阅读(87)  评论(0编辑  收藏  举报