请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  数理科学 帖子:3364809 新帖:7

研究中进行市场底部特征分析

好的名字都没了发表于:5 月 10 日 08:22回复(1)

前几天看到一篇市场底部特征研究的文章【华创金工】,觉得有点意思,下面就是将这些衡量底部特征的内容在研究里进行实现。
文章的核心逻辑如下所述:

  1. 低价股比例:逻辑是牛市消灭仙股,熊市产生仙股
  2. 破净股比例:打折促销,领先指标。
  3. M2/总市值中位数:相当于每一元的市值,有多少M2支撑和刺激?可以理解为“施肥率”。
  4. PE中位数和十年国债收益率倒数:比较股票和国债收益率的高低,经典的股债轮动指标。
  5. 全市交易额有没有触底?全市场人气。
  6. 个股流动性有没有触底?大底中大部分个股流动性枯竭。
  7. 区间最大跌幅的中位数: 大底是跌出来的,大底的水准是高点腰斩,在腰斩。
  8. 人气指标:次新股的破发率。
  9. 除了全市场的估值低,各个行业也一片惨淡,几无例外。

大底的九个衡量维度具体介绍

  • 熊市时泥沙俱下,牛市时鸡犬升天,市场总是在恐惧和疯狂的情绪中起起落落落落落......大家都知道高抛低吸,低买高卖是股市操作的致胜秘籍,问题就在于市场什么时候会迎来转折的时机。
    sanhu.jpeg

1. 低价股比例

1-1.png

  • 牛市消灭仙股,熊市产生仙股,仙股原意是指价格已经低于1元的股票,这里放大了仙股价格区间,设定为小于2元的股票,统计了从07年开始,低价股数量占比的时间序列。可是,考虑到时间跨度超过10年,那是当年可以买碗牛肉拉面的两块钱,为了抵消通货膨胀的影响,所以这里做了些改动,将条件按每年4%的无风险收益进行增长,到目前,这个低价格的阈值已经是3.2元。
  • 目前看到的几个拐点基本上都是和市场的拐点同步,这里讲最近一次的拐点放大看到如下情况
    1-2.png
      #返回股价低于2元的股票个数占比
      def f1(self,date_list):
          bei = len(date_list)//13
          se_price_2 = []
          for i in range(1,13):
              e = date_list[i*bei]
              s = date_list[(i-1)*bei]
              if i == 0:
                  s = date_list[0]
              elif i == 12:
                  e = date_list[-1]
              all_stock = list(get_all_securities(types='stock',date=e).index)
              def f1_1(x):
                  x=x.dropna(axis=0)
                  return sum(x)
              df = get_price(all_stock,start_date=s,end_date=e,fields=['close'],fq=None)['close']
              df_1 = df<=2*(1.04)**i
              #print(2*(1.04)**i)
              se1 = df_1.apply(f1_1,axis=1)
              l2 = [len(get_all_securities(types='stock',date=i)) for i in se1.index ]
              se2 = pd.Series(l2,index=se1.index)
              #se2 = df_1.apply(f1_1[1],axis=1)
              se_price_2.append(se1/se2)
          return pd.concat(se_price_2)
    

2. 破净股比例

  • 破净是指股价跌破净资产值,破净股具体就是指股票的每股市场价格低于它每股净资产价格,破净的特点和逻辑,和低价股类似。这一点从下面的图中看确实如此,从历史走势来看,破净股数据的变化情况,与股票市场的顶底区域是同步的。针对这个问题,我们找出市场中对应的几个位置特别位置和该指标数据进行对比,这里是2018年2月9号的具体表现
    WechatIMG1.png
  • 具体来看,2017年年底以来该比例骤然上升,从0.57%到目前达到6.1%的水平,接近2014年底部的比例。
    2-1.png2-2.png
      #返回破净股比例
      def f2(self,date_list):     
          pb = []
          for d in date_list:
              df_temp = get_fundamentals(query(valuation.code,valuation.pb_ratio,valuation.circulating_market_cap,valuation.pe_ratio),date=d)
              a = len(df_temp)
              b = len(df_temp[df_temp['pb_ratio']<=1])
              #b = len(df_temp[(df_temp['pb_ratio']<=1)&amp;(df_temp['pb_ratio']>=0)])
              pb.append(b/a)
          df_2 = pd.DataFrame(pb,index=date_list,columns=['pb_ratio'])
          return df_2['pb_ratio']
    

3. M2/总市值中位数

  • 先来看下什么是M2:
    M2(广义货币)= 流通中的现金(即流通于银行体系之外的现金) 企业活期存款 准货币(定期存款 居民储蓄存款 其他存款 证券公司客户保证金)
    简单粗暴的来讲就是指现金 活期存款 定期存款,M2越大越有钱,有了钱就可以大胆的买买买了,买酒、买药、买榨菜、买面条......M2被比作市场的肥料,这里将M2/总市值中位数进行了指标构建,相当于每平方米的施肥率。而选择中位数却不用总市值,是想弱化权重股对这个指标的过度影响,这里也是可以理解,毕竟中小盘股的参与度要高于超级大盘股。
    图中已经可以看到目前指标值已经逼近之前高点
    3-1.png
    注意这里市值数据为了和M2数据在同一个图中对比做了缩放
      def f3_1(self,date_list):
          M2_date = pd.read_excel('M2.xls')
          M2_date = M2_date[(M2_date['time']>date_list[0]) &amp; (M2_date['time']<date_list[-1])]
          M2_date.index = M2_date['time'].values
          date_list_new = M2_date.time
          market = []
          for d in date_list_new:
              df_temp = get_fundamentals(query(valuation.code,valuation.circulating_market_cap),date=d)
              c = df_temp['circulating_market_cap'].quantile(0.5)
              market.append(c)
          df_3 = pd.DataFrame(market,index=date_list_new,columns=['market_50%'])
          df_3['m2'] = M2_date['M2']
          df_3['M2/总市值中位数'] = df_3['m2']/df_3['market_50%']
          df_3 = df_3.sort_index(ascending=1)
          return df_3#['M2/总市值中位数']
    
    国债和M2数据 链接: https://pan.baidu.com/s/11RMzo7RjXRj5FJ4Gind6ow 密码: 2dwk

4. PE中位数和十年国债收益率倒数的比较

  • 先说说国债收益率和股市的关系,国债作为固收类产品,其收益率就是我们常说的无风险收益率,稳赚不赔,国债收益率较高的时候,会吸引资金 从高风险领域不断流入低风险的国债,造成流动性紧张,其他资产价格就会下跌;国债利率低,就会导致更多资金流入高风险领域,如间接持有股票型基金,或直接入市等,导致市场热度上升,这就是股债轮动存在的依据。
  • 下图就是市场PE中位数和十年国债收益率倒数的走势情况。
    • “第一、就是PE中位数随着小盘股占比越来越高,PE中位数也水涨船高。现在的PE中位数和08年PE中位数,内涵已经差了很多。”
      目前,看到PE中位数已经接近前低,假设PE是以线性增长的话很明显已经跌破了之前两次低点的连线,PE中位数和国债收益倒数非常接近,但还未产生交叉
    • “第二、蓝色线和灰色线的交叉,注意,通常不止一次。”
      前几次的数据曲线中我们看到,红线(PE中位数)几次下跌都是在熊市中下穿蓝线(10年国债收益率倒数),在市场回暖的过程中红线势必突破蓝线,我们可以看到一轮完整的牛熊市切换貌似都要触及一次蓝线,构成市场的左侧信息和右侧信号,中间即是买票上车的时间。
      4.png
      #PE中位数和十年国债收益率倒数的比较
      def f4_1(self,date_list):
        deb_date = pd.read_excel('10年国债数据.xls')
        deb_date = deb_date[(deb_date['time']>date_list[0]) &amp; (deb_date['time']<date_list[-1])]
        deb_date.index = deb_date['time'].values
        date_list_new = deb_date.time
        pe = []
        cir_market_ratio = []
        for d in date_list_new:
            df_temp = get_fundamentals(query(valuation.code,valuation.pe_ratio,valuation.circulating_market_cap),date=d)
            a = len(df_temp)
            b = len(df_temp[df_temp['circulating_market_cap']<45])
            #print(df_temp['circulating_market_cap'].quantile(0.5))
            c = df_temp['pe_ratio'].quantile(0.5)
            cir_market_ratio.append(b/a)
            pe.append(c)
        df_4 = pd.DataFrame(pe,index=date_list_new,columns=['pe_50%'])
        df_4['returns'] = deb_date['returns']
        df_4['1/returns'] = 100/deb_date['returns']
        df_4['cir_market_ratio'] = cir_market_ratio
        #df_4['pe中位数/10年国债收益倒数'] = df_4['pe_50%']/df_4['1/returns']
        return df_4[['pe_50%','1/returns','cir_market_ratio']]
      

5. 全市场成交额

  • “大底时全市成交额,是高点全市成交额的10%。目前已经符合大底的标准。”
    下面的图是将沪深两市每日成交额进行合计,惊奇的发现,2015年市场成交额数据竟然如此高不可攀,直逼2万亿,达到所有历史行情之最,让人不得不感慨这2015年杠杆牛的威力,明处券商两融业务做得风生水起,暗处场外配资遍地开花。虽然点数没有突破历史,但是成交金额却创下了历史记录。
    将近几年的成交额数据放大,可以发现近期成交额基本处于15年以来成交额2千多万的底线水平,占最高点成交额的11%
    5.png
    #全市场成交额
    #输出两个市场成交额数据变化
    def f5(self,date_list):
        s,e = date_list[0],date_list[-1]
        pl = get_price(['399001.XSHE','000001.XSHG'],start_date=s,end_date=e,fields=['money'])['money']
        pl['money'] = pl['399001.XSHE'] pl['000001.XSHG']
        return pl['money']

6. 个图成交冷淡

  • 市场整体热度不够,个股自然不会好到哪里。目前从图中看到,个股的成交已经是在上次股灾值附近。
    6.png
  • 这里以100万/天的成交额作为判断标准,来衡量市场个股是否冷淡。同样,由于时间跨度较大,也要考虑到市场整体的上涨对该判断带来的影响,不过这里是以M2增速的标准进行处理,我们也参考这个标准进行处理:
    M2在2005年6月底数据为275,785.53,到2018年6月底数据为1,770,200.00,按复利增长计算,基本上是每年14%的速度上升,将该速度套用在2008年每天100万成交额的基础上,得出了2018年418万成交额的条件。图中看到貌似目前还未能满足该条件,未做比例统计
      #个股成交的冷淡
      #返回个股成交金额
      def f6(self,date_list):
          l_money_mean = []
          for i in date_list:
              all_stock = list(get_all_securities(types='stock',date=i).index)
              df_money = get_price(all_stock,end_date=i,count=1)['money']
              df_money = df_money.dropna(axis=1)
              money_mean = sum(df_money.T)/df_money.shape[1]
              l_money_mean.append(money_mean.values)
          df_money_mean = pd.DataFrame(l_money_mean,index=date_list,columns=['money_mean'])
          return df_money_mean
    

7. 个股区间最大跌幅中位数

  • 下面的图是沪深300的成分股最大回撤中位数数据,可以看到,在2008年创下了最高纪录73%,与原文提到的74.44%相当接近,2014年牛市启动之前曾达到58%,最近的一次高点,也就是在2016年2月股灾2.0时,该数据达到了54.48%,而现在该值在54%左右徘徊,已经符合该底部特征的条件。
    7.png
      #个股区间最大跌幅中位数
      def f7(self,date_list):
          date = date_list[-1]
          #all_stock = list(get_all_securities(types='stock',date=date).index)
          all_stock = get_index_stocks('000300.XSHG')
          df_temp = get_price(all_stock,start_date='2005-4-1',end_date=date,fields=['close'])['close']
          se_l = []
          for i in date_list:
              df_temp_1 = df_temp[df_temp.index<i]
              #回撤
              se = 1-df_temp_1[-1:]/df_temp_1.max()
              #格式为series
              se_l.append(se.T.quantile(0.5))
          return pd.concat(se_l)
    

8. 次新股的破发率

  • 次新股,一般是指上市一年以内的股票,可以通过以下代码获取近一年上市的所有股票,共计241只,占全市场股票6.8%,取出全市场换手率最高的前100只股票,其中次新股却有57只,对广大股民来讲,次新确实有着绝对的人气。

    import datetime
    #获取所有的股票信息
    df = get_all_securities()
    #筛选出近一年的股票
    df[df['start_date']>datetime.date(2017,7,20)]
    
  • 下面是次新股和全市场股票的PE中位数的数据,就最近一次的牛市行情来看,次新是不一样的,在2015股灾之后,依然走出了一波行情,直到2016年年底才开始跳水,这与IPO加速都有着直接的关系。数据往前推几年,牛熊交替的过程中我们看到,市场好的时候,大家各有各的花样,市场不好的时候,看起来都是一个样。最低点时次新股与全市场估值接近,就是所谓通杀。就目前来看,次新还是有着自己的想法。
    8.png

    #获取次新股和全市场股票的PE中位数
      def f8(self,date_list):
          sec_new_pe = []
          pe = []
          p_ratio_l = []
          all_stock = get_all_securities(types='stock',date=date_list[-1])
          all_stock['fir_open'] = [get_price(stock,end_date=all_stock.loc[stock]['start_date'],count=1,fields=['open'])['open'].values[0] for stock in all_stock.index]
          for d in date_list:
              df_temp = get_price('000001.XSHG',end_date=d,count=252)
              year_1,month_1,day_1 = int(str(df_temp.index[0])[:4]), int(str(df_temp.index[0])[5:7]), int(str(df_temp.index[0])[8:10])
              year,month,day = int(str(df_temp.index[-1])[:4]), int(str(df_temp.index[-1])[5:7]), int(str(df_temp.index[-1])[8:10])
              sec_new_stock_df = all_stock[(all_stock['start_date']>datetime.date(year_1,month_1,day_1)) &amp; (all_stock['start_date']<datetime.date(year,month,day))]
              sec_new_stock = sec_new_stock_df.index
              df_temp = get_fundamentals(query(valuation.code,valuation.pe_ratio).filter(valuation.code.in_(sec_new_stock)),date=d)
              df_temp_1 = get_fundamentals(query(valuation.code,valuation.pe_ratio),date=d)
              pe_sec = df_temp['pe_ratio'].quantile(0.5)
              pe_all = df_temp_1['pe_ratio'].quantile(0.5)
              sec_new_pe.append(pe_sec)
              pe.append(pe_all)
              #获取次新股当前价格
              sec_new_price = get_price(list(sec_new_stock),end_date=d,fields=['close'],count=1)['close'].T
              sec_new_price.columns=['fir_open']
              p_ratio = sec_new_price['fir_open']/all_stock.loc[sec_new_price.index,:]['fir_open']
              po_ratio = len(p_ratio[p_ratio<1])/len(p_ratio)
              p_ratio_l.append(po_ratio)
          df_pe = pd.DataFrame(sec_new_pe,index=date_list,columns=['sec_pe'])
          df_pe['pe'] = pe
          df_pe['p_ratio'] = p_ratio_l
          return df_pe
    

9. 市场大底,行业一片惨淡,无一例外

  • 关于股票估值有很多的说法,就结果而言,至少到目前为止并没有一个可靠的办法,都是试图无限接近真实价值,但是结果本身甚至都不具收敛性,只能是挖掘相对好一点的方法。
  • 比较常见的方法会以每股收益为基础,估计价格,以股票当前的价格比上每股收益,得出市盈率,其中每股收益是公司本身决定的,是个确定的值,而股票价格,就是参与者来决定的随机值,根据经验,我们可以找出历史的PE值在牛熊市、特定行业中的表现,pe = p/e转换为p=pe*e,从而得到估计的值,对当前价格进行指导。
  • 在熊市的时候,大部分行业集中低估,行业估值的80%分位数,和全市场估值水平差不多。这一特征,这里并没有进行详细的数据演示,下面展示的是不同市值、不同板块的指数成分股50%分位数的时间序列,行业的话可以参考前面的代码,把股票池更换成行业成分股即可,调整下中位数刻度,进行对比验证了。
    a = f()
    #由于部分指数上市较晚,这里开始时间从2015年开始
    date_list = a.get_tradeday_list('2015-7-17','2018-7-17')
    df9 = a.f9(date_list)
    df9 = df9.sort_index(ascending=1)
    df9.plot(figsize=(10,7))
    
    9.png
      #市场大底,行业一片惨淡,无一例外
      #行业PE估值
      def f9(self,date_list):
          #指数用成分股,pe值做市值加权处理
          index_list = ['000001.XSHG','000300.XSHG','000016.XSHG','000905.XSHG','000852.XSHG','399006.XSHE','399678.XSHE','399005.XSHE'] 
          index_name = ['上证','沪深300','上证50','中证500','中证1000','创业板','次新股','中小板']
          pe_fin = []
          for i in date_list:
              pe_index = []
              for j in index_list:
                  stock_list = get_index_stocks(j,i)
                  df_temp = get_fundamentals(query(valuation.code,valuation.pe_ratio).filter(valuation.code.in_(stock_list)),date=i)
                  pe = df_temp['pe_ratio'].quantile(0.5)
                  pe_index.append(pe)
              pe_fin.append(pe_index)
          pe_df = pd.DataFrame(pe_fin,index=date_list,columns=index_name)
          return pe_df
    

总结

  • 整个做完之后,熊市底部特征指标,与之前的大熊市相比还是有些差距,但是,市场前段时间也毕竟不是大牛市与之匹配。以上内容对市场底部特征的一些现象描述,仅是同步指标的话,只能是当做验证、防御的手段,最希望的还是能够从中挖掘出一些领先市场的指标方法,可以当做主动出击的武器。毕竟个人时间能力有限,还没有较为仔细验证哪些具备预测的功能。大家有兴趣可以提供思路或者意见,社区多多分享交流了,附上原文链接:https://mp.weixin.qq.com/s/sXGUJ3DXk_iIlsiVjXQ3Fg
    多谢华创金工团队分享的文章及思路,大家共同学习了。整个过程获取数据和进行图表展示是基础,应该更多的关注目的和应用的方法,值得庆幸的是所有关于市场的宝贵经验,都能通过恰当的方式在聚宽平台上得以验证。
#导入各种包
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot')
#方法
#获取交易日期列表
#时间序列函数
class f():
    date_now = '2018-7-17'
    all_stock_info = get_all_securities(types='stock',date=date_now)
    all_stock = list(all_stock_info.index)
    #df = get_price(list(all_stock.index),start_date='2008-01-01',end_date=date,fields=['close','money','volume'])['close']
    #交易日期列表
    def get_tradeday_list(self,s='2017-1-1',e=date_now,count=None):
        if count != None:
            df = get_price('000001.XSHG',end_date=e,count=count)
            return df.index
        else:
            df = get_price('000001.XSHG',start_date=s,end_date=e)
            return df.index
    #股票个数序列
    def all_stock_num(s,e):
        get_all_securities(t)

    
    #返回股价低于2元的股票个数占比
    def f1(self,date_list):
        bei = len(date_list)//13
        se_price_2 = []
        for i in range(1,13):
            e = date_list[i*bei]
            s = date_list[(i-1)*bei]
            if i == 0:
                s = date_list[0]
            elif i == 12:
                e = date_list[-1]
            all_stock = list(get_all_securities(types='stock',date=e).index)
            def f1_1(x):
                x=x.dropna(axis=0)
                return sum(x)
            df = get_price(all_stock,start_date=s,end_date=e,fields=['close'],fq=None)['close']
            df_1 = df<=2*(1.04)**i
            #print(2*(1.04)**i)
            se1 = df_1.apply(f1_1,axis=1)
            l2 = [len(get_all_securities(types='stock',date=i)) for i in se1.index ]
            se2 = pd.Series(l2,index=se1.index)
            #se2 = df_1.apply(f1_1[1],axis=1)
            se_price_2.append(se1/se2)
        return pd.concat(se_price_2)
    
    #返回破净股比例
    def f2(self,date_list):     
        pb = []
        for d in date_list:
            df_temp = get_fundamentals(query(valuation.code,valuation.pb_ratio,valuation.circulating_market_cap,valuation.pe_ratio),date=d)
            a = len(df_temp)
            b = len(df_temp[df_temp['pb_ratio']<=1])
            #b = len(df_temp[(df_temp['pb_ratio']<=1)&(df_temp['pb_ratio']>=0)])
            pb.append(b/a)
        df_2 = pd.DataFrame(pb,index=date_list,columns=['pb_ratio'])
        return df_2['pb_ratio']
        
    #M2/总市值中位数
    def f3(self,date_list):
        M2_date = pd.read_excel('M2.xls')
        M2_date = M2_date[(M2_date['time']>date_list[0]) & (M2_date['time']<date_list[-1])]
        M2_date.index = M2_date['time'].values
        date_list_new = M2_date.time
        market = []
        for d in date_list_new:
            df_temp = get_fundamentals(query(valuation.code,valuation.circulating_market_cap),date=d)
            c = df_temp['circulating_market_cap'].quantile(0.5)
            market.append(c)
        df_3 = pd.DataFrame(market,index=date_list_new,columns=['market_50%'])
        df_3['m2'] = M2_date['M2']
        df_3['M2/总市值中位数'] = df_3['m2']/df_3['market_50%']
        df_3 = df_3.sort_index(ascending=1)
        return df_3#['M2/总市值中位数']
        #M2/总市值中位数
        
    def f3(self,date_list):
        M2_date = pd.read_excel('M2.xls')
        M2_date = M2_date[(M2_date['time']>date_list[0]) & (M2_date['time']<date_list[-1])]
        M2_date.index = M2_date['time'].values
        date_list_new = M2_date.time
        market = []
        for d in date_list_new:
            df_temp = get_fundamentals(query(valuation.code,valuation.circulating_market_cap),date=d)
            c = df_temp['circulating_market_cap'].quantile(0.5)
            market.append(c)
        df_3 = pd.DataFrame(market,index=date_list_new,columns=['market_50%'])
        df_3['m2'] = M2_date['M2']
        df_3['M2/总市值中位数'] = df_3['m2']/df_3['market_50%']
        df_3 = df_3.sort_index(ascending=1)
        return df_3#['M2/总市值中位数']
    
    def f3_1(self,date_list):
        M2_date = pd.read_excel('M2.xls')
        M2_date = M2_date[(M2_date['time']>date_list[0]) & (M2_date['time']<date_list[-1])]
        M2_date.index = M2_date['time'].values
        date_list_new = M2_date.time
        market = []
        for d in date_list_new:
            df_temp = get_fundamentals(query(valuation.code,valuation.circulating_market_cap),date=d)
            c = df_temp['circulating_market_cap'].quantile(0.5)
            market.append(c)
        df_3 = pd.DataFrame(market,index=date_list_new,columns=['market_50%'])
        df_3['m2'] = M2_date['M2']
        df_3['M2/总市值中位数'] = df_3['m2']/df_3['market_50%']
        df_3 = df_3.sort_index(ascending=1)
        return df_3#['M2/总市值中位数']
    
    #PE中位数和十年国债收益率倒数的比较
    def f4(self,date_list):
        deb_date = pd.read_excel('10年国债.xls')
        deb_date = deb_date[(deb_date['time']>date_list[0]) & (deb_date['time']<date_list[-1])]
        deb_date.index = deb_date['time'].values
        date_list_new = deb_date.time
        pe = []
        cir_market_ratio = []
        for d in date_list_new:
            df_temp = get_fundamentals(query(valuation.code,valuation.pe_ratio,valuation.circulating_market_cap),date=d)
            a = len(df_temp)
            b = len(df_temp[df_temp['circulating_market_cap']<45])
            #print(df_temp['circulating_market_cap'].quantile(0.5))
            c = df_temp['pe_ratio'].quantile(0.5)
            cir_market_ratio.append(b/a)
            pe.append(c)
        df_4 = pd.DataFrame(pe,index=date_list_new,columns=['pe_50%'])
        df_4['returns'] = deb_date['returns']
        df_4['1/returns'] = 100/deb_date['returns']
        df_4['cir_market_ratio'] = cir_market_ratio
        #df_4['pe中位数/10年国债收益倒数'] = df_4['pe_50%']/df_4['1/returns']
        return df_4[['pe_50%','1/returns','cir_market_ratio']]
    
    #PE中位数和十年国债收益率倒数的比较
    def f4_1(self,date_list):
        deb_date = pd.read_excel('10年国债数据.xls')
        deb_date = deb_date[(deb_date['time']>date_list[0]) & (deb_date['time']<date_list[-1])]
        deb_date.index = deb_date['time'].values
        date_list_new = deb_date.time
        pe = []
        cir_market_ratio = []
        for d in date_list_new:
            df_temp = get_fundamentals(query(valuation.code,valuation.pe_ratio,valuation.circulating_market_cap),date=d)
            a = len(df_temp)
            b = len(df_temp[df_temp['circulating_market_cap']<45])
            #print(df_temp['circulating_market_cap'].quantile(0.5))
            c = df_temp['pe_ratio'].quantile(0.5)
            cir_market_ratio.append(b/a)
            pe.append(c)
        df_4 = pd.DataFrame(pe,index=date_list_new,columns=['pe_50%'])
        df_4['returns'] = deb_date['returns']
        df_4['1/returns'] = 100/deb_date['returns']
        df_4['cir_market_ratio'] = cir_market_ratio
        #df_4['pe中位数/10年国债收益倒数'] = df_4['pe_50%']/df_4['1/returns']
        return df_4[['pe_50%','1/returns','cir_market_ratio']]
    
    
    #全市场成交额
    #输出两个市场成交额数据变化
    def f5(self,date_list):
        s,e = date_list[0],date_list[-1]
        pl = get_price(['399001.XSHE','000001.XSHG'],start_date=s,end_date=e,fields=['money'])['money']
        pl['money'] = pl['399001.XSHE']+pl['000001.XSHG']
        return pl['money']
    
    #个股成交的冷淡
    #返回个股成交金额
    def f6(self,date_list):
        l_money_mean = []
        for i in date_list:
            all_stock = list(get_all_securities(types='stock',date=i).index)
            df_money = get_price(all_stock,end_date=i,count=1)['money']
            df_money = df_money.dropna(axis=1)
            money_mean = sum(df_money.T)/df_money.shape[1]
            l_money_mean.append(money_mean.values)
        df_money_mean = pd.DataFrame(l_money_mean,index=date_list,columns=['money_mean'])
        return df_money_mean
    
    #个股区间最大跌幅中位数
    def f7(self,date_list):
        date = date_list[-1]
        #all_stock = list(get_all_securities(types='stock',date=date).index)
        all_stock = get_index_stocks('000300.XSHG')
        df_temp = get_price(all_stock,start_date='2005-4-1',end_date=date,fields=['close'])['close']
        se_l = []
        for i in date_list:
            df_temp_1 = df_temp[df_temp.index<i]
            #回撤
            se = 1-df_temp_1[-1:]/df_temp_1.max()
            #格式为series
            se_l.append(se.T.quantile(0.5))
        return pd.concat(se_l) 
    
    #次新股的破发率
    #获取次新股和全市场股票的PE中位数
    def f8(self,date_list):
        sec_new_pe = []
        pe = []
        p_ratio_l = []
        all_stock = get_all_securities(types='stock',date=date_list[-1])
        all_stock['fir_open'] = [get_price(stock,end_date=all_stock.loc[stock]['start_date'],count=1,fields=['open'])['open'].values[0] for stock in all_stock.index]
        for d in date_list:
            df_temp = get_price('000001.XSHG',end_date=d,count=252)
            year_1,month_1,day_1 = int(str(df_temp.index[0])[:4]), int(str(df_temp.index[0])[5:7]), int(str(df_temp.index[0])[8:10])
            year,month,day = int(str(df_temp.index[-1])[:4]), int(str(df_temp.index[-1])[5:7]), int(str(df_temp.index[-1])[8:10])
            sec_new_stock_df = all_stock[(all_stock['start_date']>datetime.date(year_1,month_1,day_1)) & (all_stock['start_date']<datetime.date(year,month,day))]
            sec_new_stock = sec_new_stock_df.index
            df_temp = get_fundamentals(query(valuation.code,valuation.pe_ratio).filter(valuation.code.in_(sec_new_stock)),date=d)
            df_temp_1 = get_fundamentals(query(valuation.code,valuation.pe_ratio),date=d)
            pe_sec = df_temp['pe_ratio'].quantile(0.5)
            pe_all = df_temp_1['pe_ratio'].quantile(0.5)
            sec_new_pe.append(pe_sec)
            pe.append(pe_all)
            #获取次新股当前价格
            sec_new_price = get_price(list(sec_new_stock),end_date=d,fields=['close'],count=1)['close'].T
            sec_new_price.columns=['fir_open']
            p_ratio = sec_new_price['fir_open']/all_stock.loc[sec_new_price.index,:]['fir_open']
            po_ratio = len(p_ratio[p_ratio<1])/len(p_ratio)
            p_ratio_l.append(po_ratio)
        df_pe = pd.DataFrame(sec_new_pe,index=date_list,columns=['sec_pe'])
        df_pe['pe'] = pe
        df_pe['p_ratio'] = p_ratio_l
        return df_pe
        
    #市场大底,行业一片惨淡,无一例外
    #行业PE估值
    def f9(self,date_list):
        #指数用成分股,pe值做市值加权处理
        index_list = ['000001.XSHG','000300.XSHG','000016.XSHG','000905.XSHG','000852.XSHG','399006.XSHE','399678.XSHE','399005.XSHE'] 
        index_name = ['上证','沪深300','上证50','中证500','中证1000','创业板','次新股','中小板']
        pe_fin = []
        for i in date_list:
            pe_index = []
            for j in index_list:
                stock_list = get_index_stocks(j,i)
                df_temp = get_fundamentals(query(valuation.code,valuation.pe_ratio).filter(valuation.code.in_(stock_list)),date=i)
                pe = df_temp['pe_ratio'].quantile(0.5)
                pe_index.append(pe)
            pe_fin.append(pe_index)
        pe_df = pd.DataFrame(pe_fin,index=date_list,columns=index_name)
        return pe_df
a = f()
date_list = a.get_tradeday_list('2005-7-17','2018-7-17')
df1 = a.f1(date_list)
df1.plot(figsize=(10,7))
<matplotlib.axes._subplots.AxesSubplot at 0x7f67db8ce668>
df2 = a.f2(date_list)
df2.plot(figsize=(10,7))
<matplotlib.axes._subplots.AxesSubplot at 0x7f67f80112b0>
df3 = a.f3(date_list)
#df3.plot(figsize=(10,7))
df3['market_50'] = df3['market_50%']*10**3
df3[['market_50','M2/总市值中位数']].plot(figsize=(10,7))
<matplotlib.axes._subplots.AxesSubplot at 0x7f67e2c38908>
df4 = a.f4_1(date_list)
df4.plot(figsize=(10,7))
<matplotlib.axes._subplots.AxesSubplot at 0x7f67e6a24780>
df4[['pe_50%','1/returns']].plot(figsize=(10,7))
<matplotlib.axes._subplots.AxesSubplot at 0x7f6805a19898>
df7 = a.f7(date_list)
df7.plot(figsize=(10,7))
<matplotlib.axes._subplots.AxesSubplot at 0x7f67ddb6db38>

全部回复

0/140

量化课程

    移动端课程