import pandas as pd
from datetime import datetime
def roe_ttm(stocklist,scandate,num = 10,period ='Q',cut = True,tb = True):
if isinstance(scandate,datetime):
scandate = datetime.strftime(scandate,'%Y-%m-%d')
q = query(
income.statDate,
income.pubDate,
income.code,
income.np_parent_company_owners,
indicator.adjusted_profit,
balance.equities_parent_company_owners,
).filter(
income.code.in_(stocklist)
)
if period.upper() == 'Q':
datelist = [str(dt) for dt in pd.date_range(start = '2000-01-01',end = scandate,freq ='Q').to_period('Q')]
elif period.upper() == 'A':
datelist = [str(dt) for dt in pd.date_range(start = '2000-01-01',end = scandate,freq ='A').to_period('A')]
if num + 5 < len(datelist) and period.upper() == 'Q':
datelist = datelist[-num-5:]
elif num+1 < len(datelist) and period.upper() == 'A':
datelist = datelist[-num-1:]
df = pd.DataFrame()
for dt in datelist:
df = pd.concat([df,get_fundamentals(q,statDate = dt)],axis =0)
df.columns =['statDate','pubDate','code','net_profit','adjust_profit','equities']
df.set_index(['statDate','code'],inplace = True)
df = df.unstack('code')
if period.upper() == 'Q':
net_profit_ttm_df = pd.rolling_sum(df['net_profit'],4)
adjust_profit_ttm_df = pd.rolling_sum(df['adjust_profit'],4)
equities_avg_df = pd.rolling_apply(df['equities'],4,lambda x:x[0]/2+x[-1]/2)
#tb = 摊薄 cut =扣非
if cut and tb:
roe_df = adjust_profit_ttm_df/df['equities']
elif cut and (not tb):
roe_df = adjust_profit_ttm_df/equities_avg_df
elif (not cut) and tb:
roe_df = net_profit_ttm_df/df['equities']
else:
roe_df = net_profit_ttm_df/equities_avg_df
elif period.upper() == 'A':
equities_avg_df = pd.rolling_apply(df['equities'],2,lambda x:x[0]/2+x[-1]/2)
#tb = 摊薄 cut =扣非
if cut and tb:
roe_df = df['adjust_profit']/df['equities']
elif cut and (not tb):
roe_df = df['adjust_profit']/equities_avg_df
elif (not cut) and tb:
roe_df = df['net_profit']/df['equities']
else:
roe_df = df['net_profit']/equities_avg_df
roe_df = roe_df.stack()
roe_df.columns = 'roe'
df = df.stack()['pubDate']
df = pd.concat([df,roe_df],axis = 1)
if cut and tb:
field = 'roe_cut_tb'
elif cut and (not tb):
field = 'roe_cut'
elif (not cut) and tb:
field = 'roe_tb'
else:
field = 'roe'
df.columns =['pubDate',field]
df.reset_index(inplace = True)
return df.dropna()
#example#
roe_ttm(get_index_stocks('000010.XSHG'),'2017-04-28',num = 10,period ='Q',cut = True,tb = False)
statDate | code | pubDate | roe_cut | |
---|---|---|---|---|
482 | 2014-06-30 | 600000.XSHG | 2014-08-14 | 0.210588 |
483 | 2014-06-30 | 600008.XSHG | 2014-08-09 | 0.059405 |
484 | 2014-06-30 | 600009.XSHG | 2014-08-16 | 0.118285 |
485 | 2014-06-30 | 600010.XSHG | 2014-08-28 | 0.005136 |
486 | 2014-06-30 | 600015.XSHG | 2014-08-07 | 0.193525 |
487 | 2014-06-30 | 600016.XSHG | 2014-08-29 | 0.217664 |
488 | 2014-06-30 | 600018.XSHG | 2014-08-28 | 0.110354 |
489 | 2014-06-30 | 600019.XSHG | 2014-08-23 | 0.052379 |
490 | 2014-06-30 | 600021.XSHG | 2014-08-22 | 0.166727 |
492 | 2014-06-30 | 600028.XSHG | 2014-08-23 | 0.120284 |
493 | 2014-06-30 | 600029.XSHG | 2014-08-30 | 0.013820 |
494 | 2014-06-30 | 600030.XSHG | 2014-08-29 | 0.063144 |
495 | 2014-06-30 | 600031.XSHG | 2014-08-30 | 0.044918 |
496 | 2014-06-30 | 600036.XSHG | 2014-08-30 | 0.204238 |
497 | 2014-06-30 | 600037.XSHG | 2014-08-29 | -0.005275 |
498 | 2014-06-30 | 600048.XSHG | 2014-08-26 | 0.221525 |
499 | 2014-06-30 | 600050.XSHG | 2014-08-08 | 0.048828 |
500 | 2014-06-30 | 600060.XSHG | 2014-08-22 | 0.134402 |
501 | 2014-06-30 | 600061.XSHG | 2014-08-28 | 0.007070 |
502 | 2014-06-30 | 600066.XSHG | 2014-08-30 | 0.208256 |
503 | 2014-06-30 | 600068.XSHG | 2014-08-26 | 0.120540 |
504 | 2014-06-30 | 600074.XSHG | 2014-08-30 | -2.646246 |
505 | 2014-06-30 | 600079.XSHG | 2014-08-15 | 0.094289 |
506 | 2014-06-30 | 600085.XSHG | 2014-08-26 | 0.135753 |
507 | 2014-06-30 | 600089.XSHG | 2014-08-28 | 0.081980 |
508 | 2014-06-30 | 600094.XSHG | 2014-08-23 | 0.047403 |
509 | 2014-06-30 | 600100.XSHG | 2014-08-15 | 0.023661 |
510 | 2014-06-30 | 600104.XSHG | 2014-08-14 | 0.188374 |
511 | 2014-06-30 | 600109.XSHG | 2014-08-28 | 0.071772 |
512 | 2014-06-30 | 600111.XSHG | 2014-08-26 | 0.090932 |
... | ... | ... | ... | ... |
2473 | 2017-03-31 | 601600.XSHG | 2017-04-26 | 0.015356 |
2474 | 2017-03-31 | 601601.XSHG | 2017-04-29 | 0.091480 |
2475 | 2017-03-31 | 601607.XSHG | 2017-04-28 | 0.097245 |
2476 | 2017-03-31 | 601608.XSHG | 2017-04-28 | -0.222652 |
2478 | 2017-03-31 | 601618.XSHG | 2017-04-29 | 0.066518 |
2479 | 2017-03-31 | 601628.XSHG | 2017-04-28 | 0.065898 |
2480 | 2017-03-31 | 601633.XSHG | 2017-04-28 | 0.216108 |
2481 | 2017-03-31 | 601668.XSHG | 2017-04-27 | 0.158732 |
2482 | 2017-03-31 | 601669.XSHG | 2017-04-28 | 0.108152 |
2483 | 2017-03-31 | 601688.XSHG | 2017-04-27 | 0.075053 |
2484 | 2017-03-31 | 601699.XSHG | 2017-04-28 | 0.070156 |
2485 | 2017-03-31 | 601718.XSHG | 2017-04-26 | -0.016722 |
2486 | 2017-03-31 | 601727.XSHG | 2017-04-22 | 0.032152 |
2487 | 2017-03-31 | 601766.XSHG | 2017-04-28 | 0.076205 |
2488 | 2017-03-31 | 601788.XSHG | 2017-04-29 | 0.063190 |
2489 | 2017-03-31 | 601800.XSHG | 2017-04-28 | 0.101710 |
2490 | 2017-03-31 | 601818.XSHG | 2017-04-29 | 0.123080 |
2491 | 2017-03-31 | 601857.XSHG | 2017-04-28 | 0.019394 |
2493 | 2017-03-31 | 601899.XSHG | 2017-04-29 | 0.047350 |
2494 | 2017-03-31 | 601901.XSHG | 2017-04-29 | 0.060062 |
2495 | 2017-03-31 | 601919.XSHG | 2017-04-29 | -0.248604 |
2496 | 2017-03-31 | 601933.XSHG | 2017-04-15 | 0.082635 |
2497 | 2017-03-31 | 601939.XSHG | 2017-04-28 | 0.147695 |
2499 | 2017-03-31 | 601985.XSHG | 2017-04-27 | 0.109253 |
2500 | 2017-03-31 | 601988.XSHG | 2017-04-29 | 0.101839 |
2501 | 2017-03-31 | 601989.XSHG | 2017-04-26 | -0.003626 |
2502 | 2017-03-31 | 601992.XSHG | 2017-04-27 | 0.057516 |
2503 | 2017-03-31 | 601998.XSHG | 2017-04-26 | 0.116574 |
2505 | 2017-03-31 | 603589.XSHG | 2017-04-28 | 0.193625 |
2508 | 2017-03-31 | 603993.XSHG | 2017-04-28 | 0.074434 |
1966 rows × 4 columns
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程