Как я могу суммировать в зависимости от входа sql? Финансовые технические показатели - PullRequest
0 голосов
/ 07 мая 2020

Я пытаюсь построить какие-то кастомные функции технических индикаторов в postgresql, и у меня возникла пара сомнений. Первый - если это какая-либо библиотека или плагин, в которых уже есть эти индикаторы (обычные, такие как скользящие средние, RSI, MACD, RSI, MFI и т. Д. c).

Мой второй вопрос касается индикатор того, что я пытаюсь кодировать. Индикатор MFI (Money Flow Index) определяется следующим образом:

  • Расчет типичной цены: (максимум + минимум + закрытие) / 3
  • Расчет исходного денежного потока: типичная цена x объем
  • Рассчитайте коэффициент денежного потока: (14-периодный положительный денежный поток) / (14-периодный отрицательный денежный поток) (**)
  • Рассчитайте MFI: 100 - 100 / ( 1 + коэффициент денежного потока)

Я уже сделал следующее:

with actual_close as (
    select 
    date, 
    (high+low+close)/3*1000 v_ty_price,  --This is the typical price x volume, since in this case is always 1000
    close actual_close
    from eurusd_ohlc
), 
prev_close as(
                select date,
                      v_ty_price,
                      actual_close,
                      lag(actual_close,1) over(order by date) prev_close 
                      from actual_close), 
totals as (
    select date,
           v_ty_price, 
           actual_close, 
           prev_close, 
           actual_close-prev_close close_dif 
           from prev_close
)

select date, sum(close_dif) over(rows between 14 preceding and current row) from totals 

Что дает следующий результат:

-------------------------------------------------------
|          date             |         sum             |
|2020-02-20 03:27:35.140751 |         NULL            |
|2020-02-20 04:19:17.088462 |   -6.000000000017103e-05|
|2020-02-20 05:54:44.060929 |           0             |
|2020-02-20 06:41:32.916934 |   -0.0006200000000000649|

Этот результат что следует использовать в (**). Эта часть будет выглядеть так:

  • Захватите последние 14 строк
  • Сложите все положительные числа вместе и все отрицательные числа вместе
  • Разделите сумму всех положительных чисел на все отрицательные.

Итак, предположим, что последние 14 строк выглядят следующим образом:

sum
-0.1
-0.6
1.2
0.1
1.5
-1
1
-0.2
0
-1
1
1.5
1.1
-1.1

Таким образом, каждая сумма будет:

pos_sum = 1.2 + 0.1 + 1.5 + 1 + 0 + 1 + 1.5 + 1.1

neg_sum = 0.1 + 0.6 + 1 + 0.2 + 1 + 1.1

Тогда соотношение денежного потока рассчитывается как pos_sum / neg_sum (OBS: MFI - индикатор с ограничением от 0 до 100, если neg_sum = 0, то коэффициент денежного потока равен 100).

Затем, наконец, MFI рассчитывается путем выполнения 100 - 100 / (1 + соотношение денежных потоков).

Часть, где у меня возникают проблемы, - это вычисление pos_sum и neg_sum. Как я могу рассчитать эти сроки и сделать это постоянно? (или движущееся окно)

Заранее спасибо! Любое предложение приветствуется :)

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Если у вас уже есть 14 строк, выбранных в качестве таблицы, вы можете получить сумму положительных и отрицательных значений как

Я переименовал столбец сумма в sum_col

WITH SUM_TABLE AS (
SELECT
SUM(CASE WHEN sum_col>=0 THEN sum_col ELSE 0 END) AS POS_SUM,
SUM(CASE WHEN sum_col<0 THEN sum_col ELSE 0 END) AS NEG_SUM
FROM table)
SELECT
CASE WHEN NEG_SUM=0 THEN 100 ELSE POS_SUM/NEG_SUM END AS MFR,
CASE WHEN NEG_SUM=0 THEN 100-100/(1+100) ELSE 100-100/(1 + (POS_SUM/NEG_SUM)) END AS MFI
FROM SUM_TABLE

РЕДАКТИРОВАТЬ Поскольку вы используете Postre SQL, если ваша таблица имеет более 14 строк и вам нужно выполнить скользящие вычисления, вы можете использовать функцию OVER для сделайте как group by для каждого из них.

WITH SUM_TABLE AS (
SELECT
date,
SUM(CASE WHEN sum_col>=0 THEN sum_col ELSE 0 END) OVER(ORDER BY date ROWS BETWEEN 13 PRECEDING AND CURRENT ROW) AS POS_SUM,
SUM(CASE WHEN sum_col<0 THEN sum_col ELSE 0 END) OVER(ORDER BY date ROWS BETWEEN 13 PRECEDING AND CURRENT ROW) AS NEG_SUM
FROM table)
SELECT
date,
CASE WHEN NEG_SUM=0 THEN 100 ELSE POS_SUM/NEG_SUM END AS MFR,
CASE WHEN NEG_SUM=0 THEN 100-100/(1+100) ELSE 100-100/(1 + (POS_SUM/NEG_SUM)) END AS MFI
FROM SUM_TABLE

0 голосов
/ 07 мая 2020

Мне сложно понять ваш вопрос. Но сосредоточимся на этой части:

Этот вывод должен использоваться в (**). Эта часть будет выглядеть так:

  • Захватите последние 14 строк
  • Сложите все положительные числа вместе и все отрицательные числа вместе
  • Разделите сумму всех положительных чисел на все отрицательные.

Если вам нужна текущая сумма, используйте оконные функции:

select t.*,
       (sum(number) filter (where number > 0) over w /
        sum(number) filter (where number < 0) over w
       )
from t
window w as (order by number rows between 13 preceding and current row)

Я немного озадачен тем, как применить это к запросу в вашем вопросе. Это намного сложнее, чем вопрос, который вы задаете.

...