Общая формула для EMA:
EMA(x<sub>n</sub>) = α * x<sub>n</sub> + (1 - α) * EMA(x<sub>n-1</sub>)
Где:
x<sub>n</sub> = PRICE
α = 0.5 -- Given 3-day SMA
Следующая рекурсивная CTE выполняет свою работу:
WITH recursive
ewma_3 (DATE, PRICE, EMA_3, rn)
AS (
-- Anchor
-- Feed SMA_3 to recursive CTE
SELECT rows."DATE", rows."PRICE", sma.sma AS ewma, rows.rn
FROM (
SELECT "DATE", "PRICE", ROW_NUMBER() OVER(ORDER BY "DATE") rn
FROM PRICE_TBL
) rows
JOIN (
SELECT "DATE",
ROUND(AVG("PRICE"::numeric)
OVER(ORDER BY "DATE" ROWS BETWEEN 2 PRECEDING AND CURRENT ROW), 6) AS sma
FROM PRICE_TBL
) sma ON sma."DATE" = rows."DATE"
WHERE rows.rn = 3
UNION ALL
-- Recursive Member
SELECT rows."DATE", rows."PRICE"
-- Calculate EMA_3 below
,ROUND(((rows."PRICE"::numeric * 0.5) +
(ewma.EMA_3 * (1 - 0.5))), 6) AS ewma
, rows.rn
FROM ewma_3 ewma
JOIN (
SELECT "DATE", "PRICE", ROW_NUMBER() OVER(ORDER BY "DATE") rn
FROM PRICE_TBL
) rows ON ewma.rn + 1 = rows.rn
WHERE rows.rn > 3
)
SELECT ewma_3.rn AS "ID", DATE, PRICE, EMA_3
FROM ewma_3
;
Это довольно много вопрос эффективности и быстроты. Для набора образцов из 9852 строк требуется 11 s 631 ms
.
Я читал, что агрегатор сохраняет результат последнего вычисленного элемента, если так:
- Может ли кто-нибудь предоставить рабочий пример с использованием агрегатных функций?
Я также открыт для любых предложений по улучшению CTE, но я почему-то верю, что aggregates
будет быстрее. Я также знаю, что это старый топи c, но я немного новичок в posgres
, поэтому любая помощь очень ценится. Спасибо!
ОБНОВЛЕНИЕ
Пример данных:
Мой CTE на 7-дневный период возвращает (исключая DATE
):
ID PRICE EMA_7
--+----------+-----------
7 0.529018 0.4888393
8 0.551339 0.5044642
9 0.580357 0.5234374
10 0.633929 0.5510603
11 0.642857 0.5740095
12 0.627232 0.5873151
Хотя рекурсивный CTE, предоставленный @GordonLinoff, на долю секунды быстрее, агрегатор (агрегированное веселье c) будет оптимальным для скорости. Я пытался это , но получаю:
ОШИБКА: функция EMA (цифра c, цифра c) не существует
Видимо, ни одна функция не соответствует заданному имени и типу аргумента. Явный тип бросает? Бестолковые