本文是一个由多局部组成的系列文章的第一篇,展现了FlinkSQL利用于市场数据的弱小性能和可表白性。该系列的代码和数据可在github上取得。它由量化建模负责人Simudyne和Krishnen Vytelingum合着。
速度在金融市场上至关重要。无论指标是最大化alpha还是最大水平地缩小危险,金融技术人员都会投入大量资金,以获取无关市场情况以及行情的最新见解。事件驱动和流式解决体系结构可在事件产生时对事件进行简单的解决,使其很天然地适宜金融市场利用。

Flink SQL是一种数据处理语言,可用于事件驱动和流应用程序的疾速原型设计和开发。Flink SQL将SQL的简略性和可拜访性与Apache Flink(一种风行的分布式流媒体平台)的性能和可伸缩性联合在一起。借助Flink SQL,业务剖析人员、开发人员和量化人员都能够疾速建设流传输管道,以实时执行简单的数据分析。

在本文中,咱们将应用Simudyne开发的基于代理的模型(ABM)生成的综合市场数据。ABM并不是自上而下的办法,而是在简单零碎中对自主参与者(或代理)进行建模,例如:金融市场中的各种买卖双方。能够捕捉这些交互,并能够针对许多应用程序剖析生成的综合数据集,例如用于检测紧急欺诈行为的训练模型,或摸索风险管理的“假如”场景。ABM生成的综合数据在历史数据有余或不可用的状况下很有用。

1 流式VWAP

咱们从一个简略的示例开始,该示例从一系列交易事件中计算成交量加权平均价格(VWAP)。VWAP是交易中用来掂量证券的市场价格和将来方向的通用基准。在这里,咱们有一个CSV格局的数据集,该数据集显示了一个交易日(2020年10月22日)的虚构证券(SIMUI)的交易事件。

sym,prc,vol,bid_id,ask_id,buyer_id,seller_id,step,timeSIMUl,149.86,2300,P|63-m-1,P|66-l-0,P|63,P|66,380,22-Oct-2020 08:00:07.600SIMUl,149.86,1935,P|63-m-1,P|25-l-0,P|63,P|25,380,22-Oct-2020 08:00:07.600SIMUl,149.74,582,P|18-l-0,P|98-m-0,P|18,P|98,428,22-Oct-2020 08:00:08.560SIMUl,149.76,2475,P|27-l-0,P|42-m-1,P|27,P|42,1021,22-Oct-2020 08:00:20.420SIMUl,149.84,21,P|5-m-0,P|42-l-0,P|5,P|42,1078,22-Oct-2020 08:00:21.560SIMUl,149.76,2709,P|24-l-1,P|92-m-0,P|24,P|92,1200,22-Oct-2020 08:00:24.000SIMUl,149.84,1653,P|8-m-1,P|24-l-0,P|8,P|24,1513,22-Oct-2020 08:00:30.260SIMUl,149.84,400,P|19-m-0,P|24-l-0,P|19,P|24,1577,22-Oct-2020 08:00:31.540

这些列是:交易种类,价格,数量,出价ID,要价ID,买方ID,卖方ID,步骤和工夫戳。步骤列是离散步骤ABM市场模仿的伪像,出于咱们的目标能够疏忽;其余各栏不言自明。

要解决此数据,咱们须要通过收回CREATE TABLE语句来申明Flink SQL表。咱们的示例数据是基于文件系统的,然而能够轻松更改连接器类型以从其余起源(例如Kafka主题)读取数据。请留神,event_time是派生的列,也用于水印。通过加水印,Flink能够限度期待提早达到和故障事件的工夫,以便能够获得停顿。在这里,咱们申明,达到event_time超过水印一分钟以上的记录将被疏忽。

CREATE TABLE trades (    symbol         STRING,    price          DOUBLE,    vol            INT,    bid_id         STRING,    ask_id         STRING,    buyer_id       STRING,    seller_id      STRING,    step           INT,    ts_str         STRING,    event_time     AS TO_TIMESTAMP (ts_str, 'dd-MMM-yyyy HH:mm:ss.SSS'),    WATERMARK FOR event_time AS event_time - INTERVAL '1' MINUTE) WITH (    'connector' = 'filesystem',    'path' = '/path/to/varstream/data/trades_raw',    'format' = 'csv'); 

VWAP的公式很简略:对于指定时间段内的每笔交易,将价格乘以交易股份数即可。将其总和除以该时间段内已交易的股票总数。上面的流查问将显示以后的VWAP,它将随着新交易事件的到来而更新:

SELECT  symbol,  SUM (vol)                     AS cumulative_volume,  SUM (price * vol)             AS cumulative_pv,  SUM (price * vol) / SUM (vol) AS vwapFROM  tradesGROUP BY  symbol;

2 实时播放

因为CSV文件中一个符号中只有一天的数据价值,因而后果更新可能产生得太快了,您简直没有留神到。从源读取事件的速度比实时产生的速度要快。有时须要在准实时回放历史数据,就如同Flink当初正在接管历史事件数据(例如,用于演示或原型设计和开发过程中)。

为了解决这个问题,咱们提供了一个简略的UDTF(用户定义的表函数),该数据以从行工夫戳派生的人工提早播放历史数据。UDTF有两个参数:第二个参数指定行工夫戳(在咱们的示例中为event_time),而第一个参数指定第一个行工夫戳之后的分钟持续时间(以分钟为单位),以开始利用提早。以下代码段显示了如何注册UDTF并在处理事件的前120分钟后将其用于视图中以利用提早。请留神LATERAL TABLE联接的应用,该联接将函数利用于主表中的每一行。

-- Register UDTFCREATE FUNCTION replay_after AS 'varstream.ReplayAfterFunction' LANGUAGE JAVA ;-- Create a viewCREATE VIEW trades_replay AS (    SELECT * FROM trades    LEFT JOIN LATERAL TABLE (replay_after (120, trades.event_time)) ON TRUE) ;

您能够通过收回一个简略的查问来验证事件的重播形式:
SELECT * FROM trades_replay
应用此视图,咱们当初能够收回雷同的VWAP聚合查问,并察看对VWAP的流更新,就如同它们是实时产生的一样:

  symbol,  SUM (vol)                     AS cumulative_volume,  SUM (price * vol)             AS cumulative_pv,  SUM (price * vol) / SUM (vol) AS vwapFROM  trades_replayGROUP BY  symbol;

只管此UDTF在进行原型制作时十分有用,但从根本上没有打算把它用于生产用处。咱们在这里应用它只是为了演示FlinkSQL如何在事件以模仿实时达到时更新聚合后果。

3 Group Windows

后面的示例显示了如何计算当天的流式VWAP。假如您要以每隔1分钟的工夫建设一个带有蜡烛图的交易仪表板。您可能须要计算每分钟的VWAP、高价、高价和总体积。Flink SQL通过组窗口使此操作变得容易,组窗口能够在GROUP BY工夫距离上利用聚合函数。

上面显示了如何获取每分钟的VWAP:

CREATE VIEW vwap_1m AS (    SELECT        symbol,        TUMBLE_START (event_time, INTERVAL '1' MINUTES) AS start_time,        TUMBLE_ROWTIME (event_time, INTERVAL '1' MINUTES) AS row_time,        MAX (price)          AS max_price,        MIN (price)          AS min_price,        SUM (price * vol)    AS total_price,        SUM (vol)            AS total_vol,        SUM (price * vol) / SUM (vol) AS vwap    FROM        trades    GROUP BY        TUMBLE (event_time, INTERVAL '1' MINUTES), symbol);SELECT symbol, start_time, total_price, total_vol, vwap FROM vwap_1m ;

后面的操作为每分钟内产生的交易计算了VWAP。如果要在几分钟内计算挪动的VWAP(MVWAP),则Flink SQL提供了一个跳跃的组窗口。上面显示了5分钟的挪动VWAP,步长为1分钟。

CREATE VIEW vwap_5m AS (    SELECT        symbol,        HOP_START (event_time, INTERVAL '1' MINUTES, INTERVAL '5' MINUTES) AS start_time,        HOP_ROWTIME (event_time, INTERVAL '1' MINUTES, INTERVAL '5' MINUTES) AS row_time,        MAX (price)          AS max_price,        MIN (price)          AS min_price,        SUM (price * vol)    AS total_price,        SUM (vol)            AS total_vol,        SUM (price * vol) / SUM (vol) AS vwap    FROM        trades    GROUP BY        HOP (event_time, INTERVAL '1' MINUTES, INTERVAL '5' MINUTES), symbol);SELECT symbol, start_time, total_price, total_vol, vwap FROM vwap_5m ;

4 论断

Flink SQL能够极大地简化和放慢流数据流的开发。在本文中,咱们摸索了SQL GROUP BY子句的不同用法,以依据市场数据流计算VWAP的变动。在下一部分中,咱们将向您展现如何从市场数据中提取每分钟的流式采样,以计算日内危险价值(IVaR)。咱们心愿本系列文章能激励您尝试将Flink SQL用于流式市场数据应用程序。

原文作者:Patrick Angeles& Krishnen Vytelingum

原文链接:https://blog.cloudera.com/streaming-market-data-with-flink-sql-part-i-streaming-vwap/

关注微信公共号理解更多信息:

本文由mdnice多平台公布