FAQ > 金融建模 > 数据提取 > 行情数据

Q:如何通过交易明细数据统计周期内的主买主卖量/金额?    

简述
描述:天软的行情中,主买与主卖是通过规则判断的,具体如下(也可参考:):
买卖标识(zmm):按下面的前后逻辑优先判定
 没有成交 -> 0
 当前成交价 > 上一笔买一价 -> 主买 1
 当前成交价 < 上一笔卖一价 -> 主卖 2
 否则 -> 3 (一般是集合竞价、涨停、跌停)
主买:买卖标识为1的+(买卖标识为3的/2)
主卖:买卖标识为2的+(买卖标识为3的/2)
通过该算法,我们要得到各周期的主买与主卖数据,可通过以下途经:
1、根据买卖标识,统计出交易明细每笔的主买成交量/主买成交金额与主卖成交量/主卖成交金额(下面简称‘主买主卖’)
2、通过交易明细,则可统计日内高频周期内的主买主卖,比如高频1分钟线,30分钟线,日线等。
3、通过日线可计算出低频的主买主卖,比如周线,月线等。
注:能计算出来的前提是该票在指定日有交易明细,且成交量或成交金额数据正常。
  • A:天软行情数据说明请参考:FAQ:Q:高频、超高频数据说明
    具体实现参考,封装三个函数
    封装函数,即将下列函数新建为用户函数进行调用,新建函数的操作请参考:FAQ:Q:如何新建函数
    三个函数的说明:
    1、函数返回在原行情数据基础上新增计算的主卖与主卖。
    主买成交量/主买成交金额与主卖成交量/主卖成交金额分别对应字段js_buy_vol/js_sale_amount与js_sale_vol/js_sale_amount
    2、函数支持指定日(即一个日线完整周期)的提取,其它维度的数据可在此基础上按需求进行提取。
    3、函数只支持单个票的计算,多个票的请写循环进行调用。
    注:此种方式用于当主买主卖数据有异常时进行计算得到,一般情况下用户可直接使用天软行情中提供的数据。
    封装函数getTradeZMM(Stockid,endt):交易明细每笔记录的主买主卖统计

    function getTradeZMM(Stockid,endt); //交易明细主买与主卖
    begin
      ov:=BackupSystemParameters2();
      setsysparam(pn_cycle(),cy_day());
      lastD:=MarketLastTradeDay(endt);
      Trade:=select * from tradetable
          datekey lastD+18/24 to endt+18/24
          of stockid end;
      update Trade set ['js_buy_vol']=['zmm']=1?['vol']:(['zmm']=3?['vol']/2:0),
          ['js_buy_amount']=['zmm']=1?['amount']:(['zmm']=3?['amount']/2:0),
          ['js_sale_vol']=['zmm']=2?['vol']:(['zmm']=3?['vol']/2:0),
          ['js_sale_amount']=['zmm']=2?['amount']:(['zmm']=3?['amount']/2:0)
      end;
      return Trade;
    end

    封装函数getCycleZMM (Stockid,endt,cycle):统日内(包括日线)高频周期内的主买与主卖

    function getHighCycleZMM(Stockid,endt,cycle); //高频周期线主买主卖的统计
    begin
      Files:=array('date','js_buy_vol','js_buy_amount',
          'js_sale_vol','js_sale_amount');
      ov:=BackupSystemParameters2();
      Trade:=getTradeZMM(Stockid,endt)[:,Files];
      setsysparam(pn_cycle(),cy_day());
      lastD:=MarketLastTradeDay(endt);
    //取当日分钟线行情后合并计算的主买与主卖
      setsysparam(pn_cycle(),cycle);
      lastD_:=MarketLastTradeDay(endt);
      if lastD_<=lastD then lastD:=endt;//低频只取当日
      Tmin:=select * from Markettable datekey lastD+18/24 to endt+18/24
         of stockid end;
      len:=length(Tmin)-1;
      for i:=0 to len do
      begin
       Tmin[i,'js_buy_vol']:=Tmin[i,'js_buy_amount']:=Tmin[i,'js_sale_vol']:=Tmin[i,'js_sale_amount']:=0;
       if len=0 then TradeTmp:=Trade;
       else if i=0 then
         TradeTmp:=select * from Trade where ['date']<=Tmin[i,'date'] end;
       else if i=len then
         TradeTmp:=select * from Trade where ['date']>Tmin[i-1,'date'] end;
       else TradeTmp:=select * from Trade
          where ['date']>Tmin[i-1,'date'] and ['date']<=Tmin[i,'date'] end;
       if istable(TradeTmp) then
       begin
         Tmin[i,'js_buy_vol']:=sum(TradeTmp[:,'js_buy_vol']);
         Tmin[i,'js_buy_amount']:=sum(TradeTmp[:,'js_buy_amount']);
         Tmin[i,'js_sale_vol']:=sum(TradeTmp[:,'js_buy_vol']);
         Tmin[i,'js_sale_amount']:=sum(TradeTmp[:,'js_buy_amount']);
       end
      end
      return Tmin;
    end

    封装函数getLowCycleZMM(Stockid,endt,cycle):统低频周期内的主买与主卖-指定日所在周期

    function getLowCycleZMM(Stockid,endt,cycle);//低频主买主卖的统计-指定日所在周期
    begin
      Files:=array('js_buy_vol','js_buy_amount',
          'js_sale_vol','js_sale_amount');
      ov:=BackupSystemParameters2();
      setsysparam(pn_cycle(),cycle);
      spD:=spec(specdate(sp_time(),endt),'SH000001'); //取完整周期
      lastD:=MarketLastTradeDay(spD)+1;
      cyD:=select * from Markettable datekey lastD to spD of stockid end;
      setsysparam(pn_cycle(),cy_day()); //按日线统计
      Tarr:=MarketTradeDayQk(lastD,spD);
      ret:=array();
      for i:=0 to length(Tarr)-1 do
      begin
        ret&=getHighCycleZMM(Stockid,Tarr[i],cy_day())[:,Files];
      end
      sret:= select selectopt(16) sumof( * ) from ret end;
      return cyD|sret;
    end;


    应用实现案例
    范例01:取带夜盘的高频
    获取豆粕(M,有夜盘)在2021-1-27日的1分钟线主买主卖数据,包括其它所有行情字段

      endt:=20210127T;
      stockid:='ZL000018';
      return getHighCycleZMM(Stockid,endt,cy_1m());
    //返回结果
    StockID StockName    date...buy_vol...js_buy_voljs_buy_amountjs_sale_voljs_sale_amount
    ZL000018连豆粕主力线2021-01-26 21:01:00...11,179...11,179386,817,81011,179386,817,810
    ZL000018连豆粕主力线2021-01-26 21:02:00...2,871...2,907100,479,9702,907100,479,970
    ZL000018连豆粕主力线2021-01-26 21:03:00...6,384...6,348219,696,0506,348219,696,050
    ZL000018连豆粕主力线2021-01-26 21:04:00...5,502...5,502190,436,3605,502190,436,360
    ZL000018连豆粕主力线2021-01-26 21:05:00...3,801...3,817131,973,6603,817131,973,660
    ...
    ZL000018连豆粕主力线2021-01-27 14:56:00...2,314...2,26379,728,6902,26379,728,690
    ZL000018连豆粕主力线2021-01-27 14:57:00...1,574...1,57555,501,5801,57555,501,580
    ZL000018连豆粕主力线2021-01-27 14:58:00...2,039...2,02271,252,5902,02271,252,590
    ZL000018连豆粕主力线2021-01-27 14:59:00...1,190...1,19041,926,5101,19041,926,510
    ZL000018连豆粕主力线2021-01-27 15:00:00...5,558...5,558195,626,6505,558195,626,650



    范例02:取日线
    获取万科A在2021-1-27日的日线主买主卖,并且只保留源如主买主卖与计算的主买主卖等数据(可进行对验证)

      endt:=20210127T;
      stockid:='SZ000002';
      t:= getHighCycleZMM(Stockid,endt,cy_day());
      Files:=array('StockID','date','buy_vol','buy_amount','sale_vol','sale_amount',
          'js_buy_vol','js_buy_amount','js_sale_vol','js_sale_amount');
      t:=t[:,Files]; //取部分字段
      t[:,'date']:=datetimetostr(t[:,'date']);//时间可读
      return t;
    //返回结果:
    StockID  datebuy_volbuy_amountsale_volsale_amountjs_buy_voljs_buy_amountjs_sale_voljs_sale_amount
    SZ0000022021-01-2735,606,6631,055,797,59936,823,6121,090,974,88135,606,6631,055,797,59935,606,6631,055,797,599


    范例03:取周线
    获取万科A在2021-1-15日所在周的周线主买主卖

      endt:=20210115T;
      stockid:='SZ000002';
      return getLowCycleZMM(Stockid,endt,cy_week());
    //返回结果:
    StockID StockName  date...buy_vol...js_buy_voljs_buy_amountjs_sale_voljs_sale_amount
    SZ000002万 科A2021-01-15...293,922,476...293,922,4768,811,153,031293,922,4768,811,153,031


    范例04:截面数据,指定周期下指定时间点的主买成交量

    //计算万科A在2021-1-28日在10:30:00的30分钟线的主买成交量
      endt:=20210128.1030T;
      stockid:='SZ000002';
    //取30分钟线
      t:=getHighCycleZMM(Stockid,dateof(endt),cy_30m());
      return vselect ['js_buy_vol'] from t where ['date']=endt end;
    //返回:6364420
    //还可以通用取交易明细按时间范围进行加总得到,这种方式用户可自己实现。