EXPONENTIAL_MOVING_AVERAGE [analytic]

使用平滑系数 X 计算表达式 E 的指数移动平均线 (EMA)。EMA 与简单移动平均线不同,它提供了更稳定的图像,可显示数据随时间的变化。

通过将上一个 EMA 值添加到按照平滑系数成比例变化的当前数据点,可以计算 EMA 值,如以下公式所示:

EMA = EMA0 + (X * (E - EMA0))

其中:

  • E 是当前数据点

  • EMA0 是上一行的 EMA 值。

  • X 是平滑系数。

此函数也可以在行级别工作。例如,EMA 假设给定列中的数据是按照均匀间隔取样的。如果用户的数据点是按照不均匀间隔取样的,则应该在 EMA() 之前运行时间序列空白填充和插值 (GFI) 操作

行为类型

不可变

语法

EXPONENTIAL_MOVING_AVERAGE ( E, X ) OVER (
    [ window-partition-clause ]
    window-order-clause  )

参数

E
其平均值基于一组行计算得出的值。可以是 INTEGERFLOATNUMERIC 类型,并且必须是常数。
X
介于 0 和 1 之间的用作平滑系数的正 FLOAT 值。
OVER()
请参阅分析函数

示例

以下示例首先在子查询中使用时间序列空白填充和插值 (GFI),然后对子查询结果执行 EXPONENTIAL_MOVING_AVERAGE 操作。

创建一个简单的四列表:

=> CREATE TABLE ticker(
     time TIMESTAMP,
     symbol VARCHAR(8),
     bid1 FLOAT,
     bid2 FLOAT );

插入一些数据,包括 NULL,以便于 GFI 可以执行插值和空白填充:

=> INSERT INTO ticker VALUES ('2009-07-12 03:00:00', 'ABC', 60.45, 60.44);
=> INSERT INTO ticker VALUES ('2009-07-12 03:00:01', 'ABC', 60.49, 65.12);
=> INSERT INTO ticker VALUES ('2009-07-12 03:00:02', 'ABC', 57.78, 59.25);
=> INSERT INTO ticker VALUES ('2009-07-12 03:00:03', 'ABC', null, 65.12);
=> INSERT INTO ticker VALUES ('2009-07-12 03:00:04', 'ABC', 67.88, null);
=> INSERT INTO ticker VALUES ('2009-07-12 03:00:00', 'XYZ', 47.55, 40.15);
=> INSERT INTO ticker VALUES ('2009-07-12 03:00:01', 'XYZ', 44.35, 46.78);
=> INSERT INTO ticker VALUES ('2009-07-12 03:00:02', 'XYZ', 71.56, 75.78);
=> INSERT INTO ticker VALUES ('2009-07-12 03:00:03', 'XYZ', 85.55, 70.21);
=> INSERT INTO ticker VALUES ('2009-07-12 03:00:04', 'XYZ', 45.55, 58.65);
=> COMMIT;

查询您刚创建的表,以便于看到输出:

=> SELECT * FROM ticker;
        time         | symbol | bid1  | bid2
---------------------+--------+-------+-------
 2009-07-12 03:00:00 | ABC    | 60.45 | 60.44
 2009-07-12 03:00:01 | ABC    | 60.49 | 65.12
 2009-07-12 03:00:02 | ABC    | 57.78 | 59.25
 2009-07-12 03:00:03 | ABC    |       | 65.12
 2009-07-12 03:00:04 | ABC    | 67.88 |
 2009-07-12 03:00:00 | XYZ    | 47.55 | 40.15
 2009-07-12 03:00:01 | XYZ    | 44.35 | 46.78
 2009-07-12 03:00:02 | XYZ    | 71.56 | 75.78
 2009-07-12 03:00:03 | XYZ    | 85.55 | 70.21
 2009-07-12 03:00:04 | XYZ    | 45.55 | 58.65
(10 rows)

以下查询处理表 trades 的列 a 中的每个 2 秒时间片所包含的第一个和最后一个值。查询然后使用平滑系数 50% 计算表达式 fv 和 lv 的指数移动平均线:

=> SELECT symbol, slice_time, fv, lv,
     EXPONENTIAL_MOVING_AVERAGE(fv, 0.5)
       OVER (PARTITION BY symbol ORDER BY slice_time) AS ema_first,
   EXPONENTIAL_MOVING_AVERAGE(lv, 0.5)
       OVER (PARTITION BY symbol ORDER BY slice_time) AS ema_last
   FROM (
     SELECT symbol, slice_time,
        TS_FIRST_VALUE(bid1 IGNORE NULLS) as fv,
        TS_LAST_VALUE(bid2 IGNORE NULLS) AS lv
      FROM ticker TIMESERIES slice_time AS '2 seconds'
      OVER (PARTITION BY symbol ORDER BY time) ) AS sq;


 symbol |     slice_time      |  fv   |  lv   | ema_first | ema_last
--------+---------------------+-------+-------+-----------+----------
 ABC    | 2009-07-12 03:00:00 | 60.45 | 65.12 |     60.45 |    65.12
 ABC    | 2009-07-12 03:00:02 | 57.78 | 65.12 |    59.115 |    65.12
 ABC    | 2009-07-12 03:00:04 | 67.88 | 65.12 |   63.4975 |    65.12
 XYZ    | 2009-07-12 03:00:00 | 47.55 | 46.78 |     47.55 |    46.78
 XYZ    | 2009-07-12 03:00:02 | 71.56 | 70.21 |    59.555 |   58.495
 XYZ    | 2009-07-12 03:00:04 | 45.55 | 58.65 |   52.5525 |  58.5725
(6 rows)

另请参阅