楼主: 数据洞见
666 0

去极值、标准化、中性化 [推广有奖]

  • 0关注
  • 0粉丝

硕士生

20%

还不是VIP/贵宾

-

威望
0
论坛币
197090 个
通用积分
447.7601
学术水平
4750 点
热心指数
4741 点
信用等级
4737 点
经验
222917 点
帖子
147
精华
0
在线时间
127 小时
注册时间
2021-6-20
最后登录
2024-3-23

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
# 导入函数库
import jqdata
import numpy as np
import pandas as pd
import math
from statsmodels import regression
import statsmodels.api as sm
import matplotlib.pyplot as plt

def winsorize(factor, std=3, have_negative = True):
    '''
    去极值函数
    factor:以股票code为index,因子值为value的Series
    std为几倍的标准差,have_negative 为布尔值,是否包括负值
    输出Series
    '''
    r=factor.dropna().copy()
    if have_negative == False:
        r = r[r>=0]
    else:
        pass
    #取极值
    edge_up = r.mean()+std*r.std()
    edge_low = r.mean()-std*r.std()
    r[r>edge_up] = edge_up
    r[r<edge_low] = edge_low
    return r

#标准化函数:
def standardize(s,ty=2):
    '''
    s为Series数据
    ty为标准化类型:1 MinMax,2 Standard,3 maxabs
    '''
    data=s.dropna().copy()
    if int(ty)==1:
        re = (data - data.min())/(data.max() - data.min())
    elif ty==2:
        re = (data - data.mean())/data.std()
    elif ty==3:
        re = data/10**np.ceil(np.log10(data.abs().max()))
    return re
   


#中性化函数
#传入:mkt_cap:以股票为index,市值为value的Series,
#factor:以股票code为index,因子值为value的Series,
#输出:中性化后的因子值series
def neutralization(factor,mkt_cap = False, industry = True):
    y = factor
    if type(mkt_cap) == pd.Series:
        LnMktCap = mkt_cap.apply(lambda x:math.log(x))
        if industry: #行业、市值
            dummy_industry = get_industry_exposure(factor.index)
            x = pd.concat([LnMktCap,dummy_industry.T],axis = 1)
        else: #仅市值
            x = LnMktCap
    elif industry: #仅行业
        dummy_industry = get_industry_exposure(factor.index)
        x = dummy_industry.T
    result = sm.OLS(y.astype(float),x.astype(float)).fit()
    return result.resid

#为股票池添加行业标记,return df格式 ,为中性化函数的子函数   
def get_industry_exposure(stock_list):
    df = pd.DataFrame(index=jqdata.get_industries(name='sw_l1').index, columns=stock_list)
    for stock in stock_list:
        try:
            df[stock][get_industry_code_from_security(stock)] = 1
        except:
            continue
    return df.fillna(0)#将NaN赋为0

# get_industry_exposure 执行效率 太低,优化如下,经测试,数据准确,速度提升几十倍。
def get_industry_exposure2(stock_list):
    indu = jqdata.get_industries(name='sw_l1').index.tolist()
    df = pd.DataFrame(0,index=stock_list, columns=indu)
    for iu in indu:
        ius = get_industry_stocks(iu)
        for s in ius:
            if s in stock_list:
                df.loc[s,iu]=1
    return df.fillna(0)


#查询个股所在行业函数代码(申万一级) ,为中性化函数的子函数   
def get_industry_code_from_security(security,date=None):
    industry_index=jqdata.get_industries(name='sw_l1').index
    for i in range(0,len(industry_index)):
        try:
            index = get_industry_stocks(industry_index[i],date=date).index(security)
            return industry_index[i]
        except:
            continue
    return u'未找到'   
   
#a=get_industry_code_from_security('600519.XSHG', date=pd.datetime.today())  
#print a

#stocks_industry=get_industry_exposure(stocks)
#print(stocks_industry)

def get_win_stand_neutra(stocks):
    h=get_fundamentals(query(valuation.pb_ratio,valuation.code,valuation.market_cap)\
        .filter(valuation.code.in_(stocks)))
    stocks_pb_se=pd.Series(list(h.pb_ratio),index=list(h.code))
    stocks_pb_win_standse=standardize(winsorize(stocks_pb_se))
    stocks_mktcap_se=pd.Series(list(h.market_cap),index=list(h.code))
    stocks_neutra_se=neutralization(stocks_pb_win_standse,stocks_mktcap_se)
    return stocks_neutra_se

#对沪深300成分股完成   
stocks=get_index_stocks('000300.XSHG')
win_stand_neutra=get_win_stand_neutra(stocks)


二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:标准化 Matplotlib regression regressio Winsorize

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-26 10:43