FAQ > 金融建模 > 数据提取 > 基本面数据

Q:如何正确匹配到财务数据的公布日?    

【简述】场景概述:
天软财务数据的大多数来源于上市公司发布的定期报告,天软会从该公告中采集许多数据,并记录在不同的多个表中。
所以,对于这一类数据表的公布日,应该是一致的,而为了方便维护,并不是在每个数据表格中都有记录这个公布日,而是以某个指定表中的公布日字段为主要维护的对象,其它表需要公布日则可与此表进行匹配。
  • A:本文中主要解决:当天软的报告期相关的财务数据表格中无公布日时,如何快速得到公布日数据。

    相关数据简介:
    财务数据公布日的维护的主要表格:
       1、股票财报公布日的维护的表格:  股票.主要财务指标(表ID:42)
       2、基金的财报公布日的维护的表格:报告期的公布日为 基金.财务指标(表ID:358);季报的公布日是 基金.财务指标(季度)(表ID:310)
         其中,310表与358表中,一季报与三季报的公布日一致的,区别是310表记录的是二季报和四季报的公布日,358记录的是中报年报的公布日。
         基金公布日的特别说明:由于基金公司主要公布的是季度报告,另外还会公布一些数据的中报和年报数据,所以,季度更新的表格以310表的公布日为主(比如数据字典中频率写着“季度”更新的表),而按中报和年报更新的数据则需要对应358表中的公布日。
        
    相关范例:
    1、单个报告期对应的公布日的提取
    范例01:股票:取贵州茅台截止到2022-4-15日的最新的5年以上应收帐款指标及其公布日

         stockid:='SH600519';
         endt:=20220415T;
         setsysparam(pn_stock(),stockid);
         //得到股票最新报告期
         Rdate:=NewReportDateOfEndT2(endt);

         zb:=Report(90014,Rdate); //指标:5年以上应收帐款:该表中无公布日
         PubD:=Report(42001,Rdate);//当前报告期对应的公布日
         return array('报告期':Rdate,'5年以上应收帐款':zb,'公布日':PubD);

    返回:

    范例02:基金报告期:取华夏上证50ETF基金在2022-4-15日的最新的股票占净值比例(%)及其公布日

         stockid:='OF510050';
         endt:=20220415T;
         setsysparam(pn_stock(),stockid);
        //得到基金最新报告期-按季报 
         Rdate:=NewQuarterlyReportDateOfEndT_Fund(endt,1);

         zb:=Report(322003,Rdate); //指标:股票占净值比例(%):该表中无公布日
         PubD:=Report(358001,Rdate);//当前报告期对应的公布日
         return array('报告期':Rdate,'股票占净值比例(%)':zb,'公布日':PubD);

    返回:


    2、批量处理:在指定表格数据中新增公布日列
    过程分析:先找到匹配的公布日所在表,取出截止日与公布日的全集对照数据,并生成以截止日为下标,公布日为值的对照表,
    再取出目标数据,并按截止日进行新增对照的公布日数据,做到对应准确且高效。
    不同报告中的数据提取区别:找对匹配的公布日所在的表格。
    分别范例如下:
    范例03:表中无公布日字段  
    股票:取贵州茅台的应收帐款帐龄分析表格数据,并补上每一期的公布日

         stockid:='SH600519';
         setsysparam(pn_stock(),stockid);
         //取42表中的截止日与公布日并生成对照表
         t42:=InfoArray(42)[:,array('截止日','公布日')];
         t42:= NormalTabletoStrSubscript(t42,'截止日');//生成对照表
         //取90表的数据,将新增公布日列
         return select t42[['截止日']]['公布日'] as '公布日',* from infotable 90 of stockid end;

    返回:
    范例:表中有公布日字段  请参考范例04的实现逻辑


    3、不同更新类别的基金公布日的提取举例
    范例04:季度更新的表格补充公布日

    //基金.资产配置表,并补充对应的公布日(原表中有公布日字段但数据不全)
         stockid:='OF510050';
         endt:=20220415T;
         //季度公布的表格数据取310表中的公布日
         setsysparam(pn_stock(),stockid);
         t0:=InfoArray(310)[:,array('截止日','公布日')];
         t0:= NormalTabletoStrSubscript(t0,'截止日');
         //取资产配置表并补充公布日,用覆盖的方式
         return select *,
                ifthen(ifnil(t0[['截止日']]['公布日']),['公布日'],t0[['截止日']]['公布日']) as '公布日'
                from infotable 322 of stockid end;

    返回:

    范例05:中报年报更新的表格补充公布日

    //基金.资产负债表,并补充对应的公布日(原表中有公布日字段但数据全为0)
         stockid:='OF510050';
         endt:=20220415T;
         //中年报公布的表格数据取358表中的公布日
         setsysparam(pn_stock(),stockid);
         t0:=InfoArray(358)[:,array('截止日','公布日')];
         t0:= NormalTabletoStrSubscript(t0,'截止日');
         //取资产负债表并补充公布日
         return select *,
                ifthen(ifnil(t0[['截止日']]['公布日']),['公布日'],t0[['截止日']]['公布日']) as '公布日'
                from infotable 312 of stockid end;

    返回:

    范例06:季度、中报年报更新的表格补充公布日
    该类数据,当季的与中年报都公布并采集时,天软的处理是先录入季报,后中报覆盖二季报数据,年报覆盖四季报数据。所以,我们取公布日时,历史的数据可直接用358表中的公布日,而最新的数据则看中年报是否公布,若公布则用中年报公布日,否则用季报公布日。

    //基金.持股明细表,并补充对应的公布日(原表中有公布日字段但数据全为0)
         stockid:='OF510050';
         endt:=20220415T;
         //中年报公布的表格数据取358表中的公布日
         setsysparam(pn_stock(),stockid);
         t0:=InfoArray(358)[:,array('截止日','公布日')];
         t0:= NormalTabletoStrSubscript(t0,'截止日');
         //取持股明细表并用358表补充公布日
         t:= select *,
                ifthen(ifnil(t0[['截止日']]['公布日']),['公布日'],t0[['截止日']]['公布日']) as '公布日'
                from infotable 318 of stockid end;
         //对最新一期的公布日的处理
         if not t[length(t)-1,'公布日'] then
         begin
            LastR:=t[length(t)-1,'截止日'];
            JDR:=Report(310001,LastR);
            update t set ['公布日']=JDR where ['截止日']=LastR end;
         end
         return t;

    返回:


    范例07:如何提取指定日最新公布的基金持股明细数据,模拟历史数据情况
    数据分析:根据数据特性“公布一季报、中报、三季报、年报数据,其中,季报(一季报、二季报、三季报、四季报)公布的是十大持股数据,中报和年报公布所有明细数据”
    则,可以判断指定日最新公布的是季报还是中年报,再通过历史数据判断是否取前十。
    实现案例如下:

    //基金:最近一期的持股明细,并补充对应的公布日
         stockid:='OF510050';
         endt:=20220215T; //指定日:取的是四季报, endt:=20220415T; 取的是年报
         setsysparam(pn_stock(),stockid);
         //得到最近报告期(包括季报与中年报报告期)
         Rdate:=NewQuarterlyReportDateOfEndT_Fund(endt,0);
         dEndt:=datetoint(endt);
         //报告期对应的公布日
         PubD:=Report(358001,Rdate);
         //季度报告期对应的公布日
         QD:=Report(310001,Rdate);
         if PubD>QD and dEndt>=PubD then isQ:='中年报';
         else isQ:='季度';

         //取指定报告期的所有持股明细数据,并且将公布日赋初值为中年报的公布日
         t:= select *,PubD as '公布日' from infotable 318 of DefaultStockID() where ['截止日']=Rdate end;
         if isQ='季度' then //取前十,并将公布日设置为季度公布日
            t:=select *,QD as '公布日' from t where ['市值排名']<=10 end;
         return t;

    返回:返回前十大,且公布日为四季报的公布日