@Jacob_Wang 提及的代码好老了,也有一些 bug。
最新的计算版本如下:
```
def fun_get_Dividend_yield(self, stocks, statsDate):
# 按照派息日计算,计算过去 12个月的派息率(TTM)
start_date = statsDate - dt.timedelta(366)
statsDate = statsDate - dt.timedelta(1)
year = statsDate.year
#将当前股票池转换为国泰安的6位股票池
stocks_symbol=[]
for s in stocks:
stocks_symbol.append(s[0:6])
# 按派息日,查找过去12个月的分红记录
# 4 steps
#0、查找当年有分红的(受派息日约束);
df = gta.run_query(query(
gta.STK_DIVIDEND.SYMBOL, # 股票代码
#gta.STK_DIVIDEND.PLANDIVIDENTBT, # 股票分红预案
gta.STK_DIVIDEND.DIVIDENTAT,
gta.STK_DIVIDEND.DISTRIBUTIONBASESHARES # 分红时的股本基数
).filter(
gta.STK_DIVIDEND.DECLAREDATE < statsDate,
gta.STK_DIVIDEND.PAYMENTDATE >= start_date,
gta.STK_DIVIDEND.DIVDENDYEAR == year,
gta.STK_DIVIDEND.TERMCODE <> 'P2799'
)).fillna(value=0, method=None, axis=0)
df = df[df.SYMBOL.isin(stocks_symbol)]
df = df.reset_index(drop = True)
#1、查找上一年有年度分红的(受派息日约束);
df1 = gta.run_query(query(
gta.STK_DIVIDEND.SYMBOL, # 股票代码
#gta.STK_DIVIDEND.PLANDIVIDENTBT, # 股票分红预案
gta.STK_DIVIDEND.DIVIDENTAT,
gta.STK_DIVIDEND.DISTRIBUTIONBASESHARES # 分红时的股本基数
).filter(
gta.STK_DIVIDEND.DECLAREDATE < statsDate,
gta.STK_DIVIDEND.PAYMENTDATE >= start_date,
gta.STK_DIVIDEND.DIVDENDYEAR == (year-1),
gta.STK_DIVIDEND.TERMCODE == 'P2702', # 年度分红
gta.STK_DIVIDEND.TERMCODE <> 'P2799'
)).fillna(value=0, method=None, axis=0)
df1 = df1[df1.SYMBOL.isin(stocks_symbol)]
df1 = df1.reset_index(drop = True)
#2、查找上一年非年度分红的(受派息日约束);
df2 = gta.run_query(query(
gta.STK_DIVIDEND.SYMBOL, # 股票代码
#gta.STK_DIVIDEND.PLANDIVIDENTBT, # 股票分红预案
gta.STK_DIVIDEND.DIVIDENTAT,
gta.STK_DIVIDEND.DISTRIBUTIONBASESHARES # 分红时的股本基数
).filter(
gta.STK_DIVIDEND.DECLAREDATE < statsDate,
gta.STK_DIVIDEND.PAYMENTDATE >= start_date,
gta.STK_DIVIDEND.DIVDENDYEAR == (year-1),
gta.STK_DIVIDEND.TERMCODE <> 'P2702', # 年度分红
gta.STK_DIVIDEND.TERMCODE <> 'P2799'
)).fillna(value=0, method=None, axis=0)
df2 = df2[df2.SYMBOL.isin(stocks_symbol)]
df2 = df2.reset_index(drop = True)
# 得到目前看起来,有上一年度年度分红的股票
stocks_symbol_this_year = list(set(list(df1['SYMBOL'])))
# 得到目前看起来,上一年度没有年度分红的股票
stocks_symbol_past_year = list(set(stocks_symbol) - set(stocks_symbol_this_year))
#3、查找上一年度还没分红,但上上年有分红的(受派息日约束)
df3 = gta.run_query(query(
gta.STK_DIVIDEND.SYMBOL, # 股票代码
#gta.STK_DIVIDEND.PLANDIVIDENTBT, # 股票分红预案
gta.STK_DIVIDEND.DIVIDENTAT,
gta.STK_DIVIDEND.DISTRIBUTIONBASESHARES # 分红时的股本基数
).filter(
gta.STK_DIVIDEND.DECLAREDATE < statsDate,
gta.STK_DIVIDEND.PAYMENTDATE >= start_date,
gta.STK_DIVIDEND.DIVDENDYEAR == (year-2),
#gta.STK_DIVIDEND.TERMCODE == 'P2702', # 年度分红
gta.STK_DIVIDEND.TERMCODE <> 'P2799'
)).fillna(value=0, method=None, axis=0)
df3 = df3[df3.SYMBOL.isin(stocks_symbol_past_year)]
df3 = df3.reset_index(drop = True)
df= pd.concat((df,df1))
df= pd.concat((df,df2))
df= pd.concat((df,df3))
df['SYMBOL']=map(normalize_code,list(df['SYMBOL']))
df.index=list(df['SYMBOL'])
# 获取最新股本
q = query(valuation.code, valuation.capitalization)
df2 = get_fundamentals(q).fillna(value=0)
df2 = df2[df2.code.isin(df.index)]
df2['SYMBOL'] = df2['code']
df2 = df2.drop(['code'], axis=1)
# 合并成一个 dataframe
df = df.merge(df2,on='SYMBOL')
df.index = list(df['SYMBOL'])
df = df.drop(['SYMBOL'], axis=1)
# 转换成 float
df['DISTRIBUTIONBASESHARES'] = map(float, df['DISTRIBUTIONBASESHARES'])
# 计算股份比值
df['CAP_RATIO'] = df['DISTRIBUTIONBASESHARES'] / (df['capitalization'] * 10000)
df['DIVIDENTAT'] = map(float, df['DIVIDENTAT'])
# 计算相对于目前股份而言的分红额度
df['DIVIDENTAT'] = df['DIVIDENTAT'] * df['CAP_RATIO']
#df = df.drop(['PLANDIVIDENTBT', 'DISTRIBUTIONBASESHARES','capitalization','CAP_RATIO'], axis=1)
df = df.drop(['DISTRIBUTIONBASESHARES','capitalization','CAP_RATIO'], axis=1)
#接下来这一步是考虑多次分红的股票,因此需要累加股票的多次分红
df = df.groupby(df.index).sum()
#得到当前股价
Price=history(1, unit='1d', field='close', security_list=list(df.index), df=True, skip_paused=False, fq='pre')
Price=Price.T
df['pre_close']=Price
#计算股息率 = 股息/股票价格,* 10 是因为取到的是每 10 股分红
df['divpercent']=df['DIVIDENTAT']/(df['pre_close'] * 10)
df = df.drop(['pre_close', 'DIVIDENTAT'], axis=1)
df = df[df.divpercent > 0]
return df
```
2017-05-09