@薛定谔の喵
import pandas as pd
from pandas import Series, DataFrame
import numpy as np
import statsmodels.api as sm
import scipy.stats as scs
import matplotlib.pyplot as plt
import datetime as dt
from jqdata import *
import time
from jqfactor import winsorize
from jqfactor import standardlize
from jqfactor import neutralize
def initialize(context):
#用沪深 300 做回报基准
set_benchmark('000001.XSHG')
# 滑点、真实价格
#set_slippage(FixedSlippage(0.000))
set_option('use_real_price', True)
g.index='000001.XSHG' # 定义股票池,上交所股票
# 关闭部分log
log.set_level('order', 'error')
#g.factors = ['B/M','EPS','PEG','ROE','ROA','GP/R','P/R','L/A','FAP','CMV']
run_daily(fun_main, '9:30')
g.shift = 21 # 设置一个观测天数(天数)
g.factors = ['CMV','BP','EP','NPOR','FLUC','NPORC','MTM1','MTM3','MTM6','MTM12','ALR','FACR','DP','PEG','CFP']
#g.factors = ['PS','ROA','ROAC','ROE','ROEC','OPTP','OPTPC','OPOR','OPORC','CMV','TR','TRC','VAR','VARC','reverse']
#g.factors = ['PEG','CMV']
#g.factors = ['ROA','ROAC','CMV']
pd.set_option('display.max_rows', 10000)
pd.set_option('display.max_columns', 10000)
#pd.set_option('display.width', 10000)
def fun_main(context):
#因为研究模块取fundmental数据默认date为研究日期的前一天。所以要自备时间序列。按月取
#year = ['2011','2012']
year = ['2008','2009','2010','2011','2012']
#year = ['2012','2013','2014','2015','2016']
#year = ['2009','2010','2011','2012','2013','2014','2015','2016']
#year = ['2012','2013','2014','2015','2016','2017','2018']
#year = ['2006','2007','2008','2009','2010','2011','2012']
month = ['01','02','03','04','05','06','07','08','09','10','11','12']
result = {}
#factors = ['BP','EP','PEG','CFP','PS','ROA','ROAC','ROE','ROEC','OPTP','OPTPC','OPOR','OPORC','CMC','TR','TRC','VAR','VARC','reverse']
for i in range((len(year)-1)*12):
startdate = year[i/12] + '-' + month[i%12] + '-01'
try:
enddate = year[(i+1)/12] + '-' + month[(i+1)%12] + '-01'
except IndexError:
enddate = '2012-01-01'
try:
nextdate = year[(i+2)/12] + '-' + month[(i+2)%12] + '-01'
except IndexError:
if enddate == '2012-01-01':
nextdate = '2012-02-01'
else:
nextdate = '2012-01-01'
print 'time %s'%startdate
#fdf = get_factors(startdate,factors)
g.feasible_stocks = set_feasible_stocks(get_index_stocks(g.index), g.shift,context,startdate)
#g.feasible_stocks = filter_specials(g.feasible_stocks)#[g.num_stocks:g.num_stocksplus]
g.feasible_stocks = delNew(context, g.feasible_stocks, 90,startdate)
fdf = get_factors(g.feasible_stocks, context, g.factors,startdate)
#print "--------------------------------factors-----------------------------------"
#print fdf
CMV = fdf['CMV']
#print "--------------------------------CMV-----------------------------------"
#print CMV
factors_length= len(g.factors)
#print factors_length
#5个组合,19个因子
df = DataFrame(np.zeros(6*factors_length).reshape(6,factors_length),index = ['port1','port2','port3','port4','port5','benchmark'],columns = g.factors)
#5个组合,2个因子
#df = DataFrame(np.zeros(6*2).reshape(6,2),index = ['port1','port2','port3','port4','port5','benchmark'],columns = g.factors)
#5个组合,3个因子
#df = DataFrame(np.zeros(6*3).reshape(6,3),index = ['port1','port2','port3','port4','port5','benchmark'],columns = g.factors)
for fac in g.factors:
score = fdf[fac].order()
port1 = list(score.index)[: len(score)/5]
port2 = list(score.index)[ len(score)/5: 2*len(score)/5]
port3 = list(score.index)[ 2*len(score)/5: 3*len(score)/5]
port4 = list(score.index)[ 3*len(score)/5: 4*len(score)/5]
port5 = list(score.index)[ 4*len(score)/5: ]
df.ix['port1',fac] = caculate_port_monthly_return(port1,startdate,enddate,nextdate,CMV)
df.ix['port2',fac] = caculate_port_monthly_return(port2,startdate,enddate,nextdate,CMV)
df.ix['port3',fac] = caculate_port_monthly_return(port3,startdate,enddate,nextdate,CMV)
df.ix['port4',fac] = caculate_port_monthly_return(port4,startdate,enddate,nextdate,CMV)
df.ix['port5',fac] = caculate_port_monthly_return(port5,startdate,enddate,nextdate,CMV)
df.ix['benchmark',fac] = caculate_benchmark_monthly_return(startdate,enddate,nextdate)
#print 'factor %s'%fac
result[i+1]=df
monthly_return = pd.Panel(result)
#monthly_return[:,:,'L/A']
#(monthly_return[:,:,'L/A'].T+1).cumprod().tail()
factors_value = {}
total_return = {}
annual_return = {}
excess_return = {}
win_prob = {}
loss_prob = {}
effect_test = {}
MinCorr = 0.3
Minbottom = -0.05
Mintop = 0.05
for fac in g.factors:
effect_test[fac] = {}
monthly = monthly_return[:,:,fac]
total_return[fac] = (monthly+1).T.cumprod().iloc[-1,:]-1
annual_return[fac] = (total_return[fac]+1)**(1./(len(year)-1))-1
excess_return[fac] = annual_return[fac]- annual_return[fac][-1]
print "--------------------------------monthly-----------------------------------"
print monthly
print "--------------------------------total_return-----------------------------------"
print fac
print total_return[fac]
print "===============================annual_return=============================="
print fac
print annual_return[fac]
print "-------------------------------excess_return------------------------------"
print excess_return[fac]
#判断因子有效性
#1.年化收益与组合序列的相关性 大于 阀值
effect_test[fac][1] = annual_return[fac][0:5].corr(Series([1,2,3,4,5],index = annual_return[fac][0:5].index))
#dfe=pd.DataFrame(annual_return[fac][0:5])
#s = Series([1,2,3,4,5],index=["port1","port2","port3","port4","port5"])
#effect_test[fac][1] = dfe.corrwith(s).values
#print "-------------------------------effect_test[fac][1]------------------------------"
#print type(effect_test[fac][1])
#print effect_test[fac][1]
#2.高收益组合跑赢概率
#因子小,收益小,port1是输家组合,port5是赢家组合 AR1
if total_return[fac][0] < total_return[fac][-2]:
factors_value[fac] = True
loss_excess = monthly.iloc[0,:]-monthly.iloc[-1,:]
loss_prob[fac] = loss_excess[loss_excess<0].count()/float(len(loss_excess))
win_excess = monthly.iloc[-2,:]-monthly.iloc[-1,:]
win_prob[fac] = win_excess[win_excess>0].count()/float(len(win_excess))
effect_test[fac][3] = [win_prob[fac],loss_prob[fac]]
#超额收益
effect_test[fac][2] = [excess_return[fac][-2]*100,excess_return[fac][0]*100]
#因子小,收益大,port1是赢家组合,port5是输家组合
else:
factors_value[fac] = False
loss_excess = monthly.iloc[-2,:]-monthly.iloc[-1,:]
loss_prob[fac] = loss_excess[loss_excess<0].count()/float(len(loss_excess))
win_excess = monthly.iloc[0,:]-monthly.iloc[-1,:]
win_prob[fac] = win_excess[win_excess>0].count()/float(len(win_excess))
effect_test[fac][3] = [win_prob[fac],loss_prob[fac]]
#超额收益
effect_test[fac][2] = [excess_return[fac][0]*100,excess_return[fac][-2]*100]
#effect_test[1]记录因子相关性,>0.5或
#effect_test[2]记录【赢家组合超额收益,输家组合超额收益】
#effect_test[3]记录赢家组合跑赢概率和输家组合跑输概率。【>0.5,>0.4】合格(因实际情况,跑输概率暂时不考虑)
DataFrame(effect_test)
print DataFrame(effect_test)
print "===============================factors_value=============================="
print factors_value
#effective_factors = ['B/M','PEG','P/R','FAP','CMV']
#DataFrame(total_return).ix[:,effective_factors]
#DataFrame(annual_return).ix[:,effective_factors]
# 某一日的前shift个交易日日期
# 输入:date为datetime.date对象(是一个date,而不是datetime);shift为int类型
# 输出:datetime.date对象(是一个date,而不是datetime)
def shift_trading_day(date, shift):
# 获取所有的交易日,返回一个包含所有交易日的 list,元素值为 datetime.date 类型.
tradingday = get_all_trade_days()
y=int(date[0:4])
m=int(date[5:7])
d=int(date[-2:])
# 得到date之后shift天那一天在列表中的行标号 返回一个数
if date in tradingday:
shiftday_index = list(tradingday).index(date)+shift
#print "===============================shiftday_index1=============================="
#print '(shiftday_index1 % s)' % tradingday[shiftday_index]
return tradingday[shiftday_index]
# 根据行号返回该日日期 为datetime.date类型
elif (datetime.date(y,m,d) + timedelta(1)) in tradingday:
shiftday_index = list(tradingday).index(datetime.date(y,m,d) + timedelta(1))+shift
#print "===============================shiftday_index2=============================="
#print '(shiftday_index2 % s)' % tradingday[shiftday_index]
return tradingday[shiftday_index]
elif (datetime.date(y,m,d) + timedelta(2)) in tradingday:
shiftday_index = list(tradingday).index(datetime.date(y,m,d) + timedelta(2))+shift
#print "===============================shiftday_index3=============================="
#print '(shiftday_index3 % s)' % tradingday[shiftday_index]
return tradingday[shiftday_index]
elif (datetime.date(y,m,d) + timedelta(3)) in tradingday:
shiftday_index = list(tradingday).index(datetime.date(y,m,d) + timedelta(3))+shift
#print "===============================shiftday_index4=============================="
#print '(shiftday_index4 % s)' % tradingday[shiftday_index]
return tradingday[shiftday_index]
elif (datetime.date(y,m,d) + timedelta(4)) in tradingday:
shiftday_index = list(tradingday).index(datetime.date(y,m,d) + timedelta(4))+shift
#print "===============================shiftday_index5=============================="
#print '(shiftday_index5 % s)' % tradingday[shiftday_index]
return tradingday[shiftday_index]
elif (datetime.date(y,m,d) + timedelta(5)) in tradingday:
shiftday_index = list(tradingday).index(datetime.date(y,m,d) + timedelta(5))+shift
#print "===============================shiftday_index6=============================="
#print '(shiftday_index6 % s)' % tradingday[shiftday_index]
return tradingday[shiftday_index]
elif (datetime.date(y,m,d) + timedelta(6)) in tradingday:
shiftday_index = list(tradingday).index(datetime.date(y,m,d) + timedelta(6))+shift
#print "===============================shiftday_index7=============================="
#print '(shiftday_index7 % s)' % tradingday[shiftday_index]
return tradingday[shiftday_index]
elif (datetime.date(y,m,d) + timedelta(7)) in tradingday:
shiftday_index = list(tradingday).index(datetime.date(y,m,d) + timedelta(7))+shift
#print "===============================shiftday_index8=============================="
#print '(shiftday_index8 % s)' % tradingday[shiftday_index]
return tradingday[shiftday_index]
elif (datetime.date(y,m,d) + timedelta(8)) in tradingday:
shiftday_index = list(tradingday).index(datetime.date(y,m,d) + timedelta(8))+shift
#print "===============================shiftday_index9=============================="
#print '(shiftday_index8 % s)' % tradingday[shiftday_index]
return tradingday[shiftday_index]
elif (datetime.date(y,m,d) + timedelta(9)) in tradingday:
shiftday_index = list(tradingday).index(datetime.date(y,m,d) + timedelta(9))+shift
#print "===============================shiftday_index10=============================="
#print '(shiftday_index8 % s)' % tradingday[shiftday_index]
return tradingday[shiftday_index]
elif (datetime.date(y,m,d) + timedelta(10)) in tradingday:
shiftday_index = list(tradingday).index(datetime.date(y,m,d) + timedelta(10))+shift
#print "===============================shiftday_index11=============================="
#print '(shiftday_index8 % s)' % tradingday[shiftday_index]
return tradingday[shiftday_index]
elif (datetime.date(y,m,d) + timedelta(11)) in tradingday:
shiftday_index = list(tradingday).index(datetime.date(y,m,d) + timedelta(11))+shift
#print "===============================shiftday_index12=============================="
#print '(shiftday_index8 % s)' % tradingday[shiftday_index]
return tradingday[shiftday_index]
else:
print "===============================shiftday_index4=============================="
print 'ooooo'
# 过滤掉当日停牌的股票,且筛选出前days天未停牌股票
# 输入:stock_list为list类型,样本天数days为int类型,context(见API)
# 输出:list=g.feasible_stocks
def set_feasible_stocks(stock_list,days,context,fdate):
# 得到是否停牌信息的dataframe,停牌的1,未停牌得0
start_date1=shift_trading_day(fdate,shift = 0)
suspened_info_df = get_price(list(stock_list),
start_date=shift_trading_day(fdate,shift = 0),
end_date=shift_trading_day(fdate,shift = 0),
frequency='daily',
fields='paused'
)['paused']
'''
suspened_info_df66 = get_price('600155.XSHG',
start_date=shift_trading_day(fdate,shift = 0),
end_date=shift_trading_day(fdate,shift = 0),
frequency='daily',
fields='paused'
)['paused']
print"===============================suspened_info_df66=============================="
print suspened_info_df66
'''
suspened_info_df = suspened_info_df.dropna(axis=1)
#print "===============================suspened_info_df1=============================="
#print type(suspened_info_df)
#print '(start_date1 % s)' % fdate
#print suspened_info_df
#print len(suspened_info_df)
suspened_info_df = suspened_info_df.T
#print"===============================len2=============================="
#print len(suspened_info_df)
#print "===============================suspened_info_df=============================="
#print type(suspened_info_df)
#print suspened_info_df
# 过滤停牌股票 返回dataframe
unsuspened_index = suspened_info_df.iloc[:,0]<1
#print "===============================unsuspened_index=============================="
#print type(unsuspened_index)
#print len(unsuspened_index)
#print unsuspened_index[600155.XSHG]
# 得到当日未停牌股票的代码list:
#aa=suspened_info_df[unsuspened_index]
unsuspened_stocks = suspened_info_df[unsuspened_index].index
#print aa
#print type(unsuspened_stocks)
#print len(unsuspened_stocks)
#unsuspened_stocks = unsuspened_index.index
# 进一步,筛选出前days天未曾停牌的股票list:
feasible_stocks = []
#current_data = get_current_data()
for stock in unsuspened_stocks:
df = get_price(stock,
end_date = shift_trading_day(fdate,shift = 0),
frequency='daily',
fields='paused',
skip_paused = False,
count= days
)['paused']
if sum(df)== 0:
feasible_stocks.append(stock)
#print "===============================df=============================="
#print sum(df)
#print 'sum(df)% f' % sum(df)[0]
'''
try:
for stock in unsuspened_stocks:
if sum(get_price(stock,
end_date = shift_trading_day(fdate,shift = 0),
frequency='daily',
fields='paused',
skip_paused = False,
count= days
)['paused']
) == 0:
feasible_stocks.append(stock)
except:
pass
'''
#print "===============================feasible_stocks=============================="
#print feasible_stocks
return feasible_stocks
## 过滤停牌 退市 st股票 当日未涨跌停股票
def filter_specials(stock_list):
curr_data = get_current_data()
stock_list = [stock for stock in stock_list if \
(not curr_data[stock].paused) # 未停牌
and (not curr_data[stock].is_st) # 非ST
and ('ST' not in curr_data[stock].name)
and ('*' not in curr_data[stock].name)
and ('退' not in curr_data[stock].name)
and (curr_data[stock].low_limit < curr_data[stock].day_open < curr_data[stock].high_limit) # 未涨跌停
]
return stock_list
##过滤上市时间短于deltaday 天的股票
def delNew(context,security_list, deltaday,fdate):
y=int(fdate[0:4])
m=int(fdate[5:7])
d=int(fdate[-2:])
#print y,m,d
deltaDate = datetime.date(y,m,d) - timedelta(deltaday)
tmpList = []
for stock in security_list:
if get_security_info(stock).start_date < deltaDate:
tmpList.append(stock)
return tmpList
def get_factors(stocks_list, context, factors,fdate):
# 从可行股票池中生成股票代码列表
df_all_raw = pd.DataFrame(stocks_list)
# 修改index为股票代码
df_all_raw['code'] = df_all_raw[0]
df_all_raw.index = df_all_raw.code
# 格式调整,没有一步到位中间有些东西还在摸索,简洁和效率的一个权衡
del df_all_raw[0]
#print "-------------1111111111111-------------------------------------------"
#print df_all_raw
stocks_list300 = list(df_all_raw.index)
# 每一个指标量都合并到一个dataframe里
for key in g.factors:
# 构建一个新的字符串,名字叫做 'get_df_'+ 'key'
tmp='get_df' + '_' + key
# 声明字符串是个方程
aa = globals()[tmp](stocks_list,context,fdate)#,value)
# 合并处理
df_all_raw = pd.concat([df_all_raw,aa], axis=1)
# 删除code列
del df_all_raw['code']
# 对于新生成的股票代码取list
stocks_list_more = list(df_all_raw.index)
# 可能在计算过程中并如的股票剔除
for stock in stocks_list_more[:]:
if stock not in stocks_list300:
df_all_raw.drop(stock)
if len(g.factors) >4:
df_all_raw=df_all_raw.dropna(how='all') #多因子
else:
df_all_raw=df_all_raw.dropna() #单因子
#print "-------------meanmeanmean-------------------------------------------"
#print df_all_raw
b = df_all_raw.mean(axis=0)
c = df_all_raw.describe()
values = {}
#print "-------------------------------平均值-------------------------------------"
#print b
#print "-----------------------------综述-------------------------------------------"
#print c
#print df_all_raw
for i in range(len(g.factors)):
a = b[i]
values[g.factors[i]] = a
#print "-------------aaaaaaaaaaaa-------------------------------------------"
#print values
#df_all_raw.fillna(value={g.factors[i]:a})
df_all_raw=df_all_raw.fillna(value=values)
#df_all_raw=df_all_raw.dropna()
#print "-------------meanmeanmean-------------------------------------------"
#print df_all_raw
return df_all_raw
# 1BP
# 得到一个dataframe:包含股票代码、账面市值比BP和对应排名BP_sorted_rank
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
# 获得市净率pb_ratio
def get_df_BP(stock_list, context,fdate):#, asc):
df_BP = get_fundamentals(query(valuation.code, valuation.pb_ratio
).filter(valuation.code.in_(stock_list)), date=fdate)
# 获得pb倒数
df_BP['BP'] = df_BP['pb_ratio'].apply(lambda x: 1/x)
# 删除nan,以备数据中某项没有产生nan
#df_BP = df_BP[pd.notnull(df_BP['BP'])]
df_BP['BP'] = df_BP['BP'].dropna()
# 生成排名序数
#df_BP['BP_sorted_rank'] = df_BP['BP'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_BP.index = df_BP.code
# 删除无用数据
del df_BP['code']
del df_BP['pb_ratio']
df_BP=winsorize(df_BP, scale=3, inclusive=True, inf2nan=True, axis=0)
#print "--------------------------------BP去极值-----------------------------------"
#print df_BP
#df_BP1= neutralize(df_BP, how=['jq_l1', 'market_cap'], date=fdate, axis=0)
#df_BP2=standardlize(df_BP1, inf2nan=True, axis=0)
#df_BP['BPN']=df_BP1['BP']
#df_BP['BPS']=df_BP2['BP']
#print "--------------------------------BP中性化-----------------------------------"
#print df_BP
df_BP=neutralize(df_BP, how=['jq_l1'], date=fdate, axis=0)
df_BP=standardlize(df_BP, inf2nan=True, axis=0)
#mean = df_BP['BP'].mean
#df_BP['BP'] = df_BP['BP'].fillna(mean)
#print "--------------------------------BP-----------------------------------"
#print df_BP
return df_BP
# 2EP
# 得到一个dataframe:包含股票代码、盈利收益率EP和EP_sorted_rank
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
# 获得动态市盈率pe_ratio
def get_df_EP(stock_list, context,fdate):#, asc):
df_EP = get_fundamentals(query(valuation.code, valuation.pe_ratio
).filter(valuation.code.in_(stock_list)), date=fdate)
# 获得pe倒数
df_EP['EP'] = df_EP['pe_ratio'].apply(lambda x: 1/x)
# 删除nan,以备数据中某项没有产生nan
df_EP = df_EP[pd.notnull(df_EP['EP'])]
# 复制一个dataframe,按对应项目排序
#df_EP['EP_sorted_rank'] = df_EP['EP'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_EP.index = df_EP.code
# 删除无用数据
del df_EP['code']
del df_EP['pe_ratio']
#mean = df_EP['EP'].mean
#df_EP['EP'] = df_EP['EP'].fillna(mean)
df_EP=winsorize(df_EP, scale=3, inclusive=True, inf2nan=True, axis=0)
df_EP=neutralize(df_EP, how=['jq_l1'], date=fdate, axis=0)
df_EP=standardlize(df_EP, inf2nan=True, axis=0)
#print "--------------------------------EP-----------------------------------"
#print df_EP
return df_EP
# 3PEG
# 输入:context(见API);stock_list为list类型,表示股票池
# 输出:df_PEG为dataframe: index为股票代码,data为相应的PEG值
def get_df_PEG(stock_list, context,fdate):#, asc):
# 查询股票池里股票的市盈率,收益增长率
q_PE_G = query(valuation.code, valuation.pe_ratio, indicator.inc_net_profit_year_on_year
).filter(valuation.code.in_(stock_list))
# 得到一个dataframe:包含股票代码、市盈率PE、收益增长率G
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
df_PE_G = get_fundamentals(q_PE_G, date=fdate)
# 筛选出成长股:删除市盈率或收益增长率为负值的股票
df_Growth_PE_G = df_PE_G[(df_PE_G.pe_ratio >0)&(df_PE_G.inc_net_profit_year_on_year >0)]
# 去除PE或G值为非数字的股票所在行
df_Growth_PE_G.dropna()
# 得到一个Series:存放股票的市盈率TTM,即PE值
Series_PE = df_Growth_PE_G.ix[:,'pe_ratio']
# 得到一个Series:存放股票的收益增长率,即G值
Series_G = df_Growth_PE_G.ix[:,'inc_net_profit_year_on_year']
# 得到一个Series:存放股票的PEG值
Series_PEG = Series_PE/Series_G
# 将股票与其PEG值对应
Series_PEG.index = df_Growth_PE_G.ix[:,0]
# 生成空dataframe
df_PEG = pd.DataFrame(Series_PEG)
# 将Series类型转换成dataframe类型
df_PEG['PEG'] = pd.DataFrame(Series_PEG)
# 得到一个dataframe:包含股票代码、盈利收益率PEG和PEG_sorted_rank
# 赋予顺序排列PEG数据序数编号
#df_PEG['PEG_sorted_rank'] = df_PEG['PEG'].rank(ascending = asc, method = 'dense')
# 删除不需要列
df_PEG = df_PEG.drop(0, 1)
df_PEG = df_PEG.dropna()
df_PEG=winsorize(df_PEG, scale=3, inclusive=True, inf2nan=True, axis=0)
df_PEG=neutralize(df_PEG, how=['jq_l1'], date=fdate, axis=0)
df_PEG=standardlize(df_PEG, inf2nan=True, axis=0)
#print "--------------------------------PEG-----------------------------------"
#print df_PEG
return df_PEG
# 4DP
# 得到一个dataframe:包含股票代码、股息率(DP)和DP_sorted_rank
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
def get_df_DP(stock_list, context,fdate):#, asc):
# 获得dividend_payable和market_cap 应付股利(元)和总市值(亿元)
df_DP = get_fundamentals(query(balance.code, balance.dividend_payable, valuation.market_cap
).filter(balance.code.in_(stock_list)), date=fdate)
# 按公式计算
df_DP['DP'] = df_DP['dividend_payable']/(df_DP['market_cap']*100000000)
# 删除nan
df_DP = df_DP.dropna()
# 生成排名序数
#df_DP['DP_sorted_rank'] = df_DP['DP'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_DP.index = df_DP.code
# 删除无用数据
del df_DP['code']
del df_DP['dividend_payable']
del df_DP['market_cap']
# 改个名字
df_DP.columns = ['DP']#, 'DP_sorted_rank']
df_DP=winsorize(df_DP, scale=3, inclusive=True, inf2nan=True, axis=0)
df_DP=neutralize(df_DP, how=['jq_l1'], date=fdate, axis=0)
df_DP=standardlize(df_DP, inf2nan=True, axis=0)
#print "--------------------------------DP-----------------------------------"
#print df_DP
return df_DP
# 5CFP
# 得到一个dataframe:包含股票代码、现金收益率CFP和CFP_sorted_rank
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
def get_df_CFP(stock_list, context,fdate):#, asc):
# 获得市现率pcf_ratio cashflow/price
df_CFP = get_fundamentals(query(valuation.code, valuation.pcf_ratio
).filter(valuation.code.in_(stock_list)), date=fdate)
# 获得pcf倒数
df_CFP['CFP'] = df_CFP['pcf_ratio'].apply(lambda x: 1/x)
# 删除nan,以备数据中某项没有产生nan
df_CFP = df_CFP[pd.notnull(df_CFP['CFP'])]
# 生成序列数字排名
#df_CFP['CFP_sorted_rank'] = df_CFP['CFP'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_CFP.index = df_CFP.code
# 删除无用数据
del df_CFP['pcf_ratio']
del df_CFP['code']
df_CFP=winsorize(df_CFP, scale=3, inclusive=True, inf2nan=True, axis=0)
df_CFP=neutralize(df_CFP, how=['jq_l1'], date=fdate, axis=0)
df_CFP=standardlize(df_CFP, inf2nan=True, axis=0)
#print "--------------------------------CFP-----------------------------------"
#print df_CFP
return df_CFP
# 6PS
# 得到一个dataframe:包含股票代码、P/SALES(PS市销率TTM)和PS_sorted_rank
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
def get_df_PS(stock_list, context,fdate):#, asc):
# 获得市销率TTMps_ratio
df_PS = get_fundamentals(query(valuation.code, valuation.ps_ratio
).filter(valuation.code.in_(stock_list)), date=fdate)
# 删除nan,以备数据中某项没有产生nan
df_PS = df_PS[pd.notnull(df_PS['ps_ratio'])]
# 生成排名序数
#df_PS['PS_sorted_rank'] = df_PS['ps_ratio'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_PS.index = df_PS.code
# 删除无用数据
del df_PS['code']
# 改个名字
df_PS.columns = ['PS']#, 'PS_sorted_rank']
df_PS=winsorize(df_PS, scale=3, inclusive=True, inf2nan=True, axis=0)
df_PS=neutralize(df_PS, how=['jq_l1'], date=fdate, axis=0)
df_PS=standardlize(df_PS, inf2nan=True, axis=0)
#print "--------------------------------PS-----------------------------------"
#print df_PS
return df_PS
# 7ALR
# 得到一个dataframe:包含股票代码、资产负债率(asset-liability ratio, ALR)
# 和ALR_sorted_rank
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
def get_df_ALR(stock_list, context,fdate):#, asc):
# 获得total_liability和total_assets 负债合计(元)和资产总计(元)
df_ALR = get_fundamentals(query(balance.code, balance.total_liability, balance.total_assets
).filter(balance.code.in_(stock_list)), date=fdate)
# 复制一个dataframe,按对应项目排序
df_ALR['ALR'] = df_ALR['total_liability']/df_ALR['total_assets']
# 删除nan
df_ALR = df_ALR.dropna()
# 生成排名序数
#df_ALR['ALR_sorted_rank'] = df_ALR['ALR'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_ALR.index = df_ALR.code
# 删除无用数据
del df_ALR['code']
del df_ALR['total_liability']
del df_ALR['total_assets']
df_ALR=winsorize(df_ALR, scale=3, inclusive=True, inf2nan=True, axis=0)
df_ALR=neutralize(df_ALR, how=['jq_l1'], date=fdate, axis=0)
df_ALR=standardlize(df_ALR, inf2nan=True, axis=0)
#print "--------------------------------ALR-----------------------------------"
#print df_ALR
return df_ALR
# 8FACR
# 得到一个dataframe:包含股票代码、固定资产比例(fixed assets to capital ratio, FACR )
# 和FACR_sorted_rank
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
def get_df_FACR(stock_list, context,fdate):#, asc):
# 获得fixed_assets和total_assets 固定资产(元)和资产总计(元)
df_FACR = get_fundamentals(query(balance.code, balance.fixed_assets, balance.total_assets
).filter(balance.code.in_(stock_list)), date=fdate)
# 根据公式计算
df_FACR['FACR'] = df_FACR['fixed_assets']/df_FACR['total_assets']
# 删除nan
df_FACR = df_FACR.dropna()
# 生成排名序数
#df_FACR['FACR_sorted_rank'] = df_FACR['FACR'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_FACR.index = df_FACR.code
# 删除无用数据
del df_FACR['code']
del df_FACR['fixed_assets']
del df_FACR['total_assets']
# 改个名字
df_FACR.columns = ['FACR']#, 'FACR_sorted_rank']
df_FACR=winsorize(df_FACR, scale=3, inclusive=True, inf2nan=True, axis=0)
df_FACR=neutralize(df_FACR, how=['jq_l1'], date=fdate, axis=0)
df_FACR=standardlize(df_FACR, inf2nan=True, axis=0)
#print "--------------------------------FACR-----------------------------------"
#print df_FACR
return df_FACR
# 9ROA
# 得到一个dataframe:包含股票代码、总资产净利率ROA(%)ROA(%)ROA和ROA_sorted_rank
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
def get_df_ROA(stock_list, context,fdate):#, asc):
# 获得总资产净利率ROA(%)roa需要的相关数据
df_ROA = get_fundamentals(query(indicator.code,
# 负债和股东权益合计
balance.total_sheet_owner_equities,
# 净利润(元)
income.net_profit,
# 所得税费用(元)
income.income_tax_expense,
# 应付利息(元)
balance.interest_payable
).filter(indicator.code.in_(stock_list)), date=fdate)
# 删除nan
df_ROA = df_ROA.dropna()
# 生成ROA数据
# ROA等于(净利润+所得税+利息费用)/负债和股东权益合计
df_ROA['ROA'] = (df_ROA['net_profit']
+ df_ROA['income_tax_expense']
+ df_ROA['interest_payable']
)/df_ROA['total_sheet_owner_equities']
# 生成排名序数
#df_ROA['ROA_sorted_rank'] = df_ROA['ROA'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_ROA.index = df_ROA.code
# 删除无用数据
del df_ROA['code']
del df_ROA['net_profit']
del df_ROA['income_tax_expense']
del df_ROA['interest_payable']
del df_ROA['total_sheet_owner_equities']
df_ROA=winsorize(df_ROA, scale=3, inclusive=True, inf2nan=True, axis=0)
df_ROA=neutralize(df_ROA, how=['jq_l1'], date=fdate, axis=0)
df_ROA=standardlize(df_ROA, inf2nan=True, axis=0)
#print "--------------------------------ROA-----------------------------------"
#print df_ROA
return df_ROA
# 10ROAC
# 得到一个dataframe:包含股票代码、净资产收益率ROA变动ROA_change(ROAC)和ROAC_sorted_rank
def get_df_ROAC(stock_list, context,fdate):#, asc):
# 前一个交易日
yest = context.previous_date
# 大约一个季度前
days_4shift_before = shift_trading_day(fdate, shift = -90)
# 获得市现率roa
df_ROAC = get_fundamentals(query(indicator.code,
# 负债和股东权益合计
balance.total_sheet_owner_equities,
# 净利润(元)
income.net_profit,
# 所得税费用(元)
income.income_tax_expense,
# 应付利息(元)
balance.interest_payable
).filter(indicator.code.in_(stock_list)), days_4shift_before )
# 用股票代码作为index
df_ROAC.index = df_ROAC['code']
# 删除nan
df_ROAC = df_ROAC.dropna()
# 生成ROA数据,小写roa为90天前数据
# roa等于(净利润+所得税+利息费用)/负债和股东权益合计
df_ROAC['roa'] = (df_ROAC['net_profit']
+ df_ROAC['income_tax_expense']
+ df_ROAC['interest_payable']
)/df_ROAC['total_sheet_owner_equities']
del df_ROAC['income_tax_expense']
del df_ROAC['interest_payable']
del df_ROAC['total_sheet_owner_equities']
del df_ROAC['net_profit']
del df_ROAC['code']
df_ROAC = df_ROAC.dropna()
#print "--------------------------------ROAC1-----------------------------------"
#print df_ROAC
# 获取当期roa,顺序无影响,随意假设
df_ROA = get_df_ROA(stock_list, context,fdate)
# ROA大写为当期值,roa小写为4个shift前的对应数据
df_ROAC['ROA'] = df_ROA['ROA']
# 计算ROA变动
df_ROAC['ROAC'] = df_ROAC['roa'] - df_ROAC['ROA']
# 删除nan
df_ROAC = df_ROAC.dropna()
# 生成序数序号
#df_ROAC['ROAC_sorted_rank'] = df_ROAC['ROAC'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
#df_ROAC.index = df_ROAC.code
# 删除无用数据
del df_ROAC['roa']
del df_ROAC['ROA']
df_ROAC=winsorize(df_ROAC, scale=3, inclusive=True, inf2nan=True, axis=0)
df_ROAC=neutralize(df_ROAC, how=['jq_l1'], date=fdate, axis=0)
df_ROAC=standardlize(df_ROAC, inf2nan=True, axis=0)
#print "--------------------------------ROAC-----------------------------------"
#print df_ROAC
return df_ROAC
# 11ROE
# 得到一个dataframe:包含股票代码、净资产收益率ROE(%)ROE和ROE_sorted_rank
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
def get_df_ROE(stock_list, context,fdate):#, asc):
# 获得净资产收益率roe
df_ROE = get_fundamentals(query(indicator.code, indicator.roe
).filter(indicator.code.in_(stock_list)), date=fdate)
# 删除nan
df_ROE = df_ROE.dropna()
# 生成排名序数
#df_ROE['ROE_sorted_rank'] = df_ROE['roe'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_ROE.index = df_ROE.code
# 删除无用数据
del df_ROE['code']
# 改个名字
df_ROE.columns = ['ROE']#, 'ROE_sorted_rank']
df_ROE=winsorize(df_ROE, scale=3, inclusive=True, inf2nan=True, axis=0)
df_ROE=neutralize(df_ROE, how=['jq_l1'], date=fdate, axis=0)
df_ROE=standardlize(df_ROE, inf2nan=True, axis=0)
#print "--------------------------------ROE-----------------------------------"
#print df_ROE
return df_ROE
# 12ROEC
# 得到一个dataframe:包含股票代码、净资产收益率ROE变动ROE_change(ROEC)和ROEC_sorted_rank
def get_df_ROEC(stock_list, context,fdate):#, asc):
# 前一个交易日
yest = context.previous_date
# 大约一个季度前
days_4shift_before = shift_trading_day(fdate, shift = -90)
# 获得市现率roe
df_ROEC = get_fundamentals(query(indicator.code, indicator.roe
).filter(indicator.code.in_(stock_list)), days_4shift_before )
# 用股票代码作为index
df_ROEC.index = df_ROEC['code']
# 获取当期roe,顺序无影响,随意假设
df_ROE = get_df_ROE(stock_list, context,fdate)
# ROE大写为当期值,roe小写为一个shift前的对应数据
df_ROEC['ROE'] = df_ROE['ROE']
# 计算ROE变动
df_ROEC['ROEC'] = df_ROEC['roe'] - df_ROEC['ROE']
# 删除nan
df_ROEC = df_ROEC.dropna()
# 生成序数序号
#df_ROEC['ROEC_sorted_rank'] = df_ROEC['ROEC'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_ROEC.index = df_ROEC.code
# 删除无用数据
del df_ROEC['code']
del df_ROEC['ROE']
del df_ROEC['roe']
df_ROEC=winsorize(df_ROEC, scale=3, inclusive=True, inf2nan=True, axis=0)
df_ROEC=neutralize(df_ROEC, how=['jq_l1'], date=fdate, axis=0)
df_ROEC=standardlize(df_ROEC, inf2nan=True, axis=0)
#print "--------------------------------ROEC-----------------------------------"
#print df_ROEC
return df_ROEC
# 13OPTP
# 得到一个dataframe:包含股票代码、主营业务利润占比(OPTP)和OPTP_sorted_rank
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
def get_df_OPTP(stock_list, context,fdate):#, asc):
# 获得operating_profit和total_profit营业利润(元)和利润总额(元)
df_OPTP = get_fundamentals(query(income.code, income.operating_profit, income.total_profit
).filter(income.code.in_(stock_list)), date=fdate)
# 复制一个dataframe,按对应项目排序
df_OPTP['OPTP'] = df_OPTP['operating_profit']/df_OPTP['total_profit']
# 删除nan
df_OPTP = df_OPTP.dropna()
# 生成排名序数
#df_OPTP['OPTP_sorted_rank'] = df_OPTP['OPTP'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_OPTP.index = df_OPTP.code
# 删除无用数据
del df_OPTP['code']
del df_OPTP['operating_profit']
del df_OPTP['total_profit']
# 改个名字
df_OPTP.columns = ['OPTP']#, 'OPTP_sorted_rank']
df_OPTP=winsorize(df_OPTP, scale=3, inclusive=True, inf2nan=True, axis=0)
df_OPTP=neutralize(df_OPTP, how=['jq_l1'], date=fdate, axis=0)
df_OPTP=standardlize(df_OPTP, inf2nan=True, axis=0)
#print "--------------------------------OPTP-----------------------------------"
#print df_OPTP
return df_OPTP
# 14OPTPC
def get_df_OPTPC(stock_list, context,fdate):#, asc):
# 前一个交易日
yest = context.previous_date
# 大约一个季度前
days_4shift_before = shift_trading_day(fdate, shift = -90)
# 获得operating_profit和total_profit营业利润(元)和利润总额(元)
df_OPTPC = get_fundamentals(query(income.code, income.operating_profit, income.total_profit
).filter(income.code.in_(stock_list)), days_4shift_before)
df_OPTPC.index = df_OPTPC['code']
df_OPTPC = df_OPTPC.dropna()
# 复制一个dataframe,按对应项目排序
df_OPTPC['optp'] = df_OPTPC['operating_profit']/df_OPTPC['total_profit']
df_OPTP = get_df_OPTP(stock_list, context,fdate)
df_OPTPC['OPTP'] = df_OPTP['OPTP']
df_OPTPC['OPTPC'] = df_OPTPC['optp'] - df_OPTPC['OPTP']
df_OPTPC = df_OPTPC.dropna()
# 生成排名序数
#df_OPTPC['OPTPC_sorted_rank'] = df_OPTPC['OPTPC'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_OPTPC.index = df_OPTPC.code
# 删除无用数据
del df_OPTPC['optp']
del df_OPTPC['OPTP']
del df_OPTPC['code']
del df_OPTPC['operating_profit']
del df_OPTPC['total_profit']
df_OPTPC=winsorize(df_OPTPC, scale=3, inclusive=True, inf2nan=True, axis=0)
df_OPTPC=neutralize(df_OPTPC, how=['jq_l1'], date=fdate, axis=0)
df_OPTPC=standardlize(df_OPTPC, inf2nan=True, axis=0)
#print "--------------------------------OPTPC-----------------------------------"
#print df_OPTPC
return df_OPTPC
# 15OPOR
# 得到一个dataframe:包含股票代码、主营业务利润收入占比(OPOR)和OPOR_sorted_rank
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
def get_df_OPOR(stock_list, context,fdate):#, asc):
# 获得operating_profit和operating_revenue营业利润(元)和总营业收入(元)
df_OPOR = get_fundamentals(query(income.code, income.operating_profit, income.operating_revenue
).filter(income.code.in_(stock_list)), date=fdate)
# 复制一个dataframe,按对应项目排序
df_OPOR['OPOR'] = df_OPOR['operating_profit']/df_OPOR['operating_revenue']
# 删除nan
df_OPOR = df_OPOR.dropna()
# 生成排名序数
#df_OPOR['OPOR_sorted_rank'] = df_OPOR['OPOR'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_OPOR.index = df_OPOR.code
# 删除无用数据
del df_OPOR['code']
del df_OPOR['operating_profit']
del df_OPOR['operating_revenue']
# 改个名字
df_OPOR.columns = ['OPOR']#, 'OPOR_sorted_rank']
df_OPOR=winsorize(df_OPOR, scale=3, inclusive=True, inf2nan=True, axis=0)
df_OPOR=neutralize(df_OPOR, how=['jq_l1'], date=fdate, axis=0)
df_OPOR=standardlize(df_OPOR, inf2nan=True, axis=0)
#df_OPOR=winsorize(df_OPOR, qrange=[0.05,0.93], inclusive=True, inf2nan=True, axis=0)
#print "--------------------------------OPOR-----------------------------------"
#print df_OPOR
return df_OPOR
'''
# 12OPOR
# 得到一个dataframe:包含股票代码、主营业务利润收入占比(OPOR)和OPOR_sorted_rank
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
def get_df_OPOR(stock_list, context,fdate):
# 获得operating_profit和operating_revenue营业利润(元)和总营业收入(元)
df_OPOR = get_fundamentals(query(income.code, income.operating_profit, income.operating_revenue
).filter(income.code.in_(stock_list)), date=fdate)
# 复制一个dataframe,按对应项目排序
df_OPOR['OPOR'] = df_OPOR['operating_profit']/df_OPOR['operating_revenue']
# 删除nan
df_OPOR = df_OPOR.dropna()
#df_OPOR.index = df_OPOR.code
df_OPOR = df_OPOR.drop(['operating_profit'], axis=1)
df_OPOR = df_OPOR.drop(['operating_revenue'], axis=1)
#df_OPTPC = df_OPTPC.reset_index(drop = True)
bp_ratio = {}
list_stock = []
list_value = []
industry_list = fun_get_industry(cycle=None)
for industry in industry_list:
tmpDict = fun_get_factor(df_OPOR, 'OPOR', industry, 2, fdate).to_dict()
for stock in tmpDict.keys():
if stock in bp_ratio:
if bp_ratio[stock] < tmpDict[stock]:
bp_ratio[stock] = tmpDict[stock]
else:
bp_ratio[stock] = tmpDict[stock]
#log.info(tmpDict)
#df_BP1 = pd.DataFrame(tmpseries)
#log.info("tmpDict % f" % (len(tmpseries)))
for stock in bp_ratio.keys():
list_stock.append(stock)
list_value.append(bp_ratio[stock])
df_OPOR1 = pd.DataFrame(data=list_value,index=list_stock)#,columns=BP)
df_OPOR1.columns = ['OPOR']
# 生成排名序数
#df_OPOR1['OPOR_sorted_rank'] = df_OPOR1['OPOR'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
#df_OPOR.index = df_OPOR.code
# 删除无用数据
#del df_OPOR['code']
#del df_OPOR['operating_profit']
#del df_OPOR['operating_revenue']
# 改个名字
#df_OPOR.columns = ['OPOR', 'OPOR_sorted_rank']
print "--------------------------------OPOR-----------------------------------"
print df_OPOR1
return df_OPOR1
'''
# 16OPORC
def get_df_OPORC(stock_list, context,fdate):#, asc):
# 前一个交易日
yest = context.previous_date
# 大约一个季度前
days_4shift_before = shift_trading_day(fdate, shift = -90)
# 获得operating_profit和operating_revenue营业利润(元)和总营业收入(元)
df_OPORC = get_fundamentals(query(income.code, income.operating_profit, income.operating_revenue
).filter(income.code.in_(stock_list)), days_4shift_before)
#df_OPORC.index = df_OPORC['code']
df_OPORC.index = df_OPORC.code
df_OPORC = df_OPORC.dropna()
# 复制一个dataframe,按对应项目排序
df_OPORC['opor'] = df_OPORC['operating_profit']/df_OPORC['operating_revenue']
del df_OPORC['operating_profit']
del df_OPORC['operating_revenue']
del df_OPORC['code']
df_OPORC=winsorize(df_OPORC, scale=3, inclusive=True, inf2nan=True, axis=0)
df_OPOR = get_df_OPOR(stock_list, context,fdate)
df_OPORC['OPOR'] = df_OPOR['OPOR']
df_OPORC['OPORC'] = df_OPORC['opor'] - df_OPORC['OPOR']
df_OPORC = df_OPORC.dropna()
# 生成排名序数
#df_OPORC['OPORC_sorted_rank'] = df_OPORC['OPORC'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
# 删除无用数据
del df_OPORC['opor']
del df_OPORC['OPOR']
df_OPORC=winsorize(df_OPORC, scale=3, inclusive=True, inf2nan=True, axis=0)
df_OPORC=neutralize(df_OPORC, how=['jq_l1'], date=fdate, axis=0)
df_OPORC=standardlize(df_OPORC, inf2nan=True, axis=0)
#print "--------------------------------OPORC-----------------------------------"
#print df_OPORC
return df_OPORC
# 17CMC
# 得到一个dataframe:包含股票代码、流通市值CMC和CMC_sorted_rank
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
def get_df_CMV(stock_list, context,fdate):#, asc):
# 获得流通市值 circulating_market_cap 流通市值(亿)
df_CMV = get_fundamentals(query(valuation.code, valuation.circulating_market_cap
).filter(valuation.code.in_(stock_list)), date=fdate)
# 删除nan
df_CMV = df_CMV.dropna()
# 生成排名序数
#df_CMC['CMC_sorted_rank'] = df_CMC['circulating_market_cap'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_CMV.index = df_CMV.code
# 删除无用数据
del df_CMV['code']
# 改个名字
df_CMV.columns = ['CMV']#, 'CMC_sorted_rank']
df_CMV = df_CMV.dropna()
df_CMV=winsorize(df_CMV, scale=3, inclusive=True, inf2nan=True, axis=0)
#df_CMV=neutralize(df_CMV, how=['jq_l1'], date=fdate, axis=0)
#df_CMV=standardlize(df_CMV, inf2nan=True, axis=0)
#print "--------------------------------CMV-----------------------------------"
#print df_CMV
return df_CMV
# 18NOPR
# 得到一个dataframe:包含股票代码、收入净利率(NPOR)和NPOR_sorted_rank
# 默认date = context.current_dt的前一天,使用默认值,避免未来函数,不建议修改
def get_df_NPOR(stock_list, context,fdate):#, asc):
# 获得net_profit和operating_revenue净利润(元)和营业收入(元)
df_NPOR = get_fundamentals(query(income.code, income.net_profit, income.operating_revenue
).filter(income.code.in_(stock_list)), date=fdate)
# 复制一个dataframe,按对应项目排序
df_NPOR['NPOR'] = df_NPOR['net_profit']/df_NPOR['operating_revenue']
# 删除nan
df_NPOR = df_NPOR.dropna()
# 生成排名序数
#df_NPOR['NPOR_sorted_rank'] = df_NPOR['NPOR'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_NPOR.index = df_NPOR.code
# 删除无用数据
del df_NPOR['code']
del df_NPOR['net_profit']
del df_NPOR['operating_revenue']
# 改个名字
df_NPOR.columns = ['NPOR']#, 'NPOR_sorted_rank']
df_NPOR=winsorize(df_NPOR, scale=3, inclusive=True, inf2nan=True, axis=0)
df_NPOR=neutralize(df_NPOR, how=['jq_l1'], date=fdate, axis=0)
df_NPOR=standardlize(df_NPOR, inf2nan=True, axis=0)
#print "--------------------------------NPOR-----------------------------------"
#print df_NPOR
return df_NPOR
# 19NPORC
# 得到一个dataframe:包含股票代码、收入净利率(NPORC)和NPORC_sorted_rank
def get_df_NPORC(stock_list, context,fdate):#, asc):
# 获得上一个交易日日期
yest = context.previous_date
# 大约一个季度前
days_4shift_before = shift_trading_day(fdate, shift = -90)
# 获得net_profit和operating_revenue净利润(元)和营业收入(元)
df_NPORC = get_fundamentals(query(income.code, income.net_profit, income.operating_revenue
).filter(income.code.in_(stock_list)),days_4shift_before )
# 股票编号设定为index
df_NPORC.index = df_NPORC['code']
# 前一期的npor
df_NPORC['npor'] = df_NPORC['net_profit']/df_NPORC['operating_revenue']
# 调取NPOR当期值,默认asc=False,这里只提取npor,排序在这里没关系
df_NPOR = get_df_NPOR(stock_list, context,fdate)
# 当期NPOR,需要区分大小写
df_NPORC['NPOR'] = df_NPOR['NPOR']
# 生成NPOR_change
df_NPORC['NPORC'] = df_NPORC['npor'] - df_NPORC['NPOR']
# 删除nan
df_NPORC = df_NPORC.dropna()
# 生成排名序数
#df_NPORC['NPORC_sorted_rank'] = df_NPORC['NPORC'].rank(ascending = asc, method = 'dense')
# 使用股票代码作为index
df_NPORC.index = df_NPORC.code
# 删除无用数据
del df_NPORC['code']
del df_NPORC['net_profit']
del df_NPORC['operating_revenue']
del df_NPORC['NPOR']
del df_NPORC['npor']
df_NPORC=winsorize(df_NPORC, scale=3, inclusive=True, inf2nan=True, axis=0)
df_NPORC=neutralize(df_NPORC, how=['jq_l1'], date=fdate, axis=0)
df_NPORC=standardlize(df_NPORC, inf2nan=True, axis=0)
#print "--------------------------------NPORC-----------------------------------"
#print df_NPORC
return df_NPORC
# 20MTM1
# 一个月动能,输入stock_list, context, asc = True/False
# 输出:dataframe,index为code
def get_df_MTM1(stock_list, context,fdate):#, asc):
# 上个交易日日期
yest = shift_trading_day(fdate, shift = 0)
# 一个shift前的交易日日期
days_1shift_before = shift_trading_day(fdate, shift = -21)
# 获得上个交易日收盘价
df_price_info = get_price(list(stock_list),
start_date=yest,
end_date=yest,
frequency='daily',
fields='close')['close'].T
# 1个月前收盘价信息
df_price_info_1shift = get_price(list(stock_list),
start_date=days_1shift_before,
end_date=days_1shift_before,
frequency='daily',
fields='close')['close'].T
# 1月的收益率,Series
Series_mtm1 = (df_price_info.ix[:,yest]
- df_price_info_1shift.ix[:,days_1shift_before]
)/df_price_info_1shift.ix[:,days_1shift_before]
# 生成dataframe格式
df_MTM1 = pd.DataFrame({'MTM1':Series_mtm1})
# 删除NaN
df_MTM1 = df_MTM1[pd.notnull(df_MTM1['MTM1'])]
# 排序给出排序打分,MTM1
#df_MTM1['MTM1_sorted_rank'] = df_MTM1['MTM1'].rank(ascending = asc, method = 'dense')
df_MTM1=winsorize(df_MTM1, scale=3, inclusive=True, inf2nan=True, axis=0)
df_MTM1=neutralize(df_MTM1, how=['jq_l1'], date=fdate, axis=0)
df_MTM1=standardlize(df_MTM1, inf2nan=True, axis=0)
#print "--------------------------------MTM1-----------------------------------"
#print df_MTM1
return df_MTM1
# 21MTM3
# 三个月动能,输入stock_list, context, asc = True/False
# 输出:dataframe,index为code
def get_df_MTM3(stock_list, context,fdate):#, asc):
# 上个交易日日期
yest = shift_trading_day(fdate, shift = 0)
# 3个shift前的交易日日期
days_3shift_before = shift_trading_day(fdate, shift = -63)
# 获得上个交易日收盘价
df_price_info = get_price(list(stock_list),
start_date=yest,
end_date=yest,
frequency='daily',
fields='close')['close'].T
# 1个月前收盘价信息
df_price_info_3shift = get_price(list(stock_list),
start_date=days_3shift_before,
end_date=days_3shift_before,
frequency='daily',
fields='close')['close'].T
# 3个月的收益率,Series
Series_mtm3 = (df_price_info.ix[:,yest]
- df_price_info_3shift.ix[:,days_3shift_before]
)/df_price_info_3shift.ix[:,days_3shift_before]
# 生成dataframe格式
df_MTM3 = pd.DataFrame({'MTM3':Series_mtm3})
# 删除NaN
df_MTM3 = df_MTM3[pd.notnull(df_MTM3['MTM3'])]
# 排序给出排序打分,MTM3
#df_MTM3['MTM3_sorted_rank'] = df_MTM3['MTM3'].rank(ascending = asc, method = 'dense')
df_MTM3=winsorize(df_MTM3, scale=3, inclusive=True, inf2nan=True, axis=0)
df_MTM3=neutralize(df_MTM3, how=['jq_l1'], date=fdate, axis=0)
df_MTM3=standardlize(df_MTM3, inf2nan=True, axis=0)
#print "--------------------------------MTM3-----------------------------------"
#print df_MTM3
return df_MTM3
# 22MTM6
# 六个月动能,输入stock_list, context, asc = True/False
# 输出:dataframe,index为code
def get_df_MTM6(stock_list, context,fdate):#, asc):
# 获得上一个交易日日期
yest = shift_trading_day(fdate, shift = 0)
# 一个shift前的交易日日期
days_6shift_before = shift_trading_day(fdate, shift = -125)
# 获得上个交易日收盘价
df_price_info = get_price(list(stock_list),
start_date=yest,
end_date=yest,
frequency='daily',
fields='close')['close'].T
# 6个月前收盘价信息
df_price_info_6shift = get_price(list(stock_list),
start_date=days_6shift_before,
end_date=days_6shift_before,
frequency='daily',
fields='close')['close'].T
# MTM6六月动量,Series
Series_mtm6 = (df_price_info.ix[:,yest]
- df_price_info_6shift.ix[:,days_6shift_before]
)/df_price_info_6shift.ix[:,days_6shift_before]
# 生成dataframe格式
df_MTM6 = pd.DataFrame({'MTM6':Series_mtm6})
# 删除NaN
df_MTM6 = df_MTM6[pd.notnull(df_MTM6['MTM6'])]
# 排序给出排序打分,MTM6
#df_MTM6['MTM6_sorted_rank'] = df_MTM6['MTM6'].rank(ascending = asc, method = 'dense')
df_MTM6=winsorize(df_MTM6, scale=3, inclusive=True, inf2nan=True, axis=0)
df_MTM6=neutralize(df_MTM6, how=['jq_l1'], date=fdate, axis=0)
df_MTM6=standardlize(df_MTM6, inf2nan=True, axis=0)
#print "--------------------------------MTM6-----------------------------------"
#print df_MTM6
return df_MTM6
# 23MTM12
# 十二个月动能,输入stock_list, context, asc = True/False
# 输出:dataframe,index为code
def get_df_MTM12(stock_list, context,fdate):#, asc):
# 上个交易日日期
yest = shift_trading_day(fdate, shift = 0)
# 一个shift前的交易日日期
days_12shift_before = shift_trading_day(fdate, shift = -250)
# 获得上个交易日收盘价
df_price_info = get_price(list(stock_list),
start_date=yest,
end_date=yest,
frequency='daily',
fields='close')['close'].T
# 12个月前收盘价信息
df_price_info_12shift = get_price(list(stock_list),
start_date=days_12shift_before,
end_date=days_12shift_before,
frequency='daily',
fields='close')['close'].T
# MTM12月动量,Series
Series_mtm12 = (df_price_info.ix[:,yest]
- df_price_info_12shift.ix[:,days_12shift_before]
)/df_price_info_12shift.ix[:,days_12shift_before]
# 生成dataframe格式
df_MTM12 = pd.DataFrame({'MTM12':Series_mtm12})
# 删除NaN
df_MTM12 = df_MTM12[pd.notnull(df_MTM12['MTM12'])]
# 排序给出排序打分,MTM12
#df_MTM12['MTM12_sorted_rank'] = df_MTM12['MTM12'].rank(ascending = asc, method = 'dense')
df_MTM12=winsorize(df_MTM12, scale=3, inclusive=True, inf2nan=True, axis=0)
df_MTM12=neutralize(df_MTM12, how=['jq_l1'], date=fdate, axis=0)
df_MTM12=standardlize(df_MTM12, inf2nan=True, axis=0)
#print "--------------------------------MTM12-----------------------------------"
#print df_MTM12
return df_MTM12
# 24TR
# 得到一个dataframe:包含股票代码、换手率(%)TR和TR_sorted_rank
# 默认date = context.previous_date,使用默认值,避免未来函数,不建议修改
def get_df_TR(stock_list, context,fdate):#, asc):
# 获取价格数据,当前到21天前一共22行,与之前get_price不同,没有使用转置,行为股票代码
# 列为日期,上边为较早最后为较晚
df_volume_info_between_1shift = get_price(list(stock_list),
count = 22,
end_date = fdate,
frequency = 'daily',
fields = 'volume')['volume'].T
# 换手量加总
df_volume_info_between_1shift['VOLUME'] = df_volume_info_between_1shift.sum(axis=1,skipna=True)
# 获得换手率(%)turnover_ratio
df_TR = get_fundamentals(query(valuation.code, valuation.circulating_cap
).filter(valuation.code.in_(stock_list)), date=fdate)
# 删除nan
df_TR = df_TR.dropna()
# 使用股
2018-08-02