暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

日频、分钟频、快照、逐笔……不同频率因子开发实战

1282



在上一篇《以 Alpha 101 为例:量化因子的多范式计算方法》一文中,我们以 Alpha#1 和 Alpha#98 两个因子为例,为大家展示了 SQL 和面板两种便捷开发因子的模式,我们建议:

  • 对于日频等低频数据,推荐使用面板模式,结合 DolphinDB 的一系列优化函数,实现既直观、又高效的因子计算。
  • 对于分钟频、快照、逐笔等中高频数据,推荐使用 SQL 模式,结合 DolphinDB 的分区存储方案,高效实现库内并行计算。


在实际的因子计算中,要考虑数据的具体特点和计算需求,选择最合适自己的计算方式。

对于日频数据,通常是涉及多个截面的复杂计算,我们已经为大家展示了如何用更直观、方便的面板模式计算Alpha#1 和 Alpha#98因子。


👆点击查看《以 Alpha 101 为例:量化因子的多范式计算方法》

今天我们将针对分钟频、快照、逐笔数据的特点,分别举一些因子的例子,看看在 DolphinDB 中是怎么实现的~

数据集展示

以下是分钟频、快照和逐笔数据模拟的部分字段样例。其中,计算 Level 2 的多档快照数据,传统的方式是将多档量价数据存储成为多个列,再将多档挂单或者报价用 matrix 转换与权重做计算。

在 DolphinDB 中更推荐的做法是,将多档数据存储为 array vector。DolphinDB 中的数组向量 (array vector) 是一种特殊的向量,用于存储可变长度的二维数组,可将数据表中数据类型相同且含义相近的多列存为一列。这样做的好处是,计算代码中可以使用原来的自定义函数,同时提高数据压缩比,提升查询速度。

分钟频数据

快照行情数据

用 Array Vector 存储的快照数据

tick 逐笔数据

分钟频数据

下面的是日内收益率偏度的因子计算,对于这类只涉及表内字段的计算,通常使用 SQL 模式,配合 group by 语句将计算分组:
    defg dayReturnSkew(close){
    return skew(ratios(close))
    }


    minReturn = select `dayReturnSkew as factorname, dayReturnSkew(close) as val from loadTable("dfs://k_minute_level", "k_minute") where date(tradetime) between 2020.01.02 : 2020.01.31 group by date(tradetime) as tradetime, securityid

    结果如下所示:

    基于快照数据的有状态因子计算

    有状态的因子,意为当前表达式中包含其它计算的结果变量,如一般的滑动窗口计算、聚合计算等,都是有状态的因子计算。

    下例 flow 这个自定义函数中,参数为四个列字段,运用 mavg 滑动平均函数以及 iif 条件运算函数,可以直接在 SQL 中得到因子结果:

      @state
      def flow(buy_vol, sell_vol, askPrice1, bidPrice1){
      buy_vol_ma = round(mavg(buy_vol, 5*60), 5)
      sell_vol_ma = round(mavg(sell_vol, 5*60), 5)
      buy_prop = iif(abs(buy_vol_ma+sell_vol_ma) < 0, 0.5 , buy_vol_ma/ (buy_vol_ma+sell_vol_ma))
      spd = askPrice1 - bidPrice1
      spd = iif(spd < 0, 0, spd)
      spd_ma = round(mavg(spd, 5*60), 5)
      return iif(spd_ma == 0, 0, buy_prop spd_ma)
      }


      res_flow = select TradeTime, SecurityID, `flow as factorname, flow(BidOrderQty[1],OfferOrderQty[1], OfferPrice[1], BidPrice[1]) as val from loadTable("dfs://LEVEL2_Snapshot_ArrayVector","Snap") where date(TradeTime) <= 2020.01.30 and date(TradeTime) >= 2020.01.01 context by SecurityID

      果如下所示:

      快照数据的

      多档赋权无状态因子计算

      面的例子是计算多档报价的权重偏度因子,使用 array vector 后计算时间从4秒缩短到2秒。其中,使用 map 关键字后,SQL 语句会在每个分区内分别执行,然后输出每个分区的执行结果。
        def mathWghtCovar(x, y, w){
        v = (x - rowWavg(x, w)) * (y - rowWavg(y, w))
        return rowWavg(v, w)
        }


        @state
        def mathWghtSkew(x, w){
        x_var = mathWghtCovar(x, x, w)
        x_std = sqrt(x_var)
        x_1 = x - rowWavg(x, w)
        x_2 = x_1*x_1
        len = size(w)
        adj = sqrt((len - 1) * len) \ (len - 2)
        skew = rowWsum(x_2, x_1) \ (x_var * x_std) * adj \ len
        return iif(x_std==0, 0, skew)
        }


        //weights:
        w = 10 9 8 7 6 5 4 3 2 1


        //权重偏度因子:
        resWeight = select TradeTime, SecurityID, `mathWghtSkew as factorname, mathWghtSkew(BidPrice, w) as val from loadTable("dfs://LEVEL2_Snapshot_ArrayVector","Snap") where date(TradeTime) = 2020.01.02 map
        resWeight1 = select TradeTime, SecurityID, `mathWghtSkew as factorname, mathWghtSkew(matrix(BidPrice0,BidPrice1,BidPrice2,BidPrice3,BidPrice4,BidPrice5,BidPrice6,BidPrice7,BidPrice8,BidPrice9), w) as val from loadTable("dfs://snapshot_SH_L2_TSDB", "snapshot_SH_L2_TSDB") where date(TradeTime) = 2020.01.02 map

        输出的因子如下所示:

        基于快照数据的分钟聚合

        投研中经常需要基于快照数据聚合分钟线的 OHLC ,下例就是这一场景中的通用做法:
          //基于快照因子的分钟聚合OHLC,vwap
          tick_aggr = select first(LastPx) as open, max(LastPx) as high, min(LastPx) as low, last(LastPx) as close, sum(totalvolumetrade) as vol,sum(lastpx*totalvolumetrade) as val,wavg(lastpx, totalvolumetrade) as vwap from loadTable("dfs://LEVEL2_Snapshot_ArrayVector","Snap") where date(TradeTime) <= 2020.01.30 and date(TradeTime) >= 2020.01.01 group by SecurityID, bar(TradeTime,1m)

          逐笔数据

          逐笔数据量较大,一般会针对成交量等字段进行计算,下面的例子计算了每天主买成交量占全部成交量的比例,同样使用 SQL 模式,发挥库内并行计算的优势,并使用 csort 语句用来对组内数据按照时间顺序排序:
            @state
            def buyTradeRatio(buyNo, sellNo, tradeQty){
            return cumsum(iif(buyNo>sellNo, tradeQty, 0))\cumsum(tradeQty)
            }


            factor = select TradeTime, SecurityID, `buyTradeRatio as factorname, buyTradeRatio(BuyNo, SellNo, TradeQty) as val from loadTable("dfs://tick_SH_L2_TSDB","tick_SH_L2_TSDB") where date(TradeTime)<2020.01.31 and time(TradeTime)>=09:30:00.000 context by SecurityID, date(TradeTime) csort TradeTime

            结果展示:

            下期预告

            在生产环境中,DolphinDB 提供了实时流计算框架。在流计算框架下,用户在投研阶段封装好的基于批量数据开发的因子函数,可以无缝投入交易和投资方面的生产程序中,这就是通常所说的流批一体。使用流一体可以加速用户的开发和部署。

            主买成交量占比因子、大小单、复杂因子Alpha #1……这些因子的实时计算方法将在下一篇中介绍,欢迎关注~

            扫码获取因子开发方案👇👇


            点击阅读原文获取因子开发方案

            文章转载自DolphinDB智臾科技,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

            评论