【问题标题】:postgres + timescaledb + timebucket + marketdatapostgres + timescaledb + timebucket + 市场数据
【发布时间】:2023-01-20 02:04:56
【问题描述】:

你好吗?

我有一张股票价格表,其中有“stock_id”、“dt”(时间戳)、“open”、“high”、“low”、“close”和“volume”列,如下例所示:

enter image description here

请注意,“dt”字段的时间范围为 15m,市场时间从上午 10 点开始,到晚上 18 点结束。

我想在另一个时间范围内使用函数 time_bucket(或另一个可能满足我要求的函数)创建物化视图。比如4个小时:

SELECT stock_id, time_bucket(INTERVAL '4 hour', dt) AS "time", first(open, dt) as open, max(high) as high, min(low) as low, last(close, dt) as close, sum(volume) as volume FROM stock_prices where stock_id = 269 GROUP BY stock_id, "time" order by "time" DESC;

结果:

enter image description here

请注意,“dt”字段从上午 8 点开始,但我需要始终在上午 10 点开始并在晚上 18 点(市场时间)结束。

如果我使用其他时间范围,如 1 小时、2 小时,它工作正常。例子:

enter image description here

你可以帮帮我吗?

非常感谢!

我尝试使用 time_bucket_gapfill 但也没有用。

【问题讨论】:

  • 示例数据最好显示为 formatted text。有关如何创建漂亮表格的一些提示,请参阅here

标签: postgresql timescaledb


【解决方案1】:

您可以为此使用 continuous_aggregates。这是一个使用一些随机数据的完整示例:


CREATE TABLE "ticks" ("time" timestamp with time zone not null, "symbol" text, "price" decimal, "volume" float);

SELECT create_hypertable('ticks', 'time', chunk_time_interval => INTERVAL '1 day');

ALTER TABLE ticks SET (
  timescaledb.compress,
  timescaledb.compress_orderby = 'time',
  timescaledb.compress_segmentby = 'symbol'
);
CREATE MATERIALIZED VIEW candlestick_1m
WITH (timescaledb.continuous) AS
SELECT time_bucket('1m', time),
       "ticks"."symbol",
       toolkit_experimental.candlestick_agg(time, price, volume) as candlestick
FROM "ticks"
GROUP BY 1, 2
ORDER BY 1
WITH NO DATA;

CREATE MATERIALIZED VIEW candlestick_1h
WITH (timescaledb.continuous) AS
SELECT time_bucket('1 hour', "time_bucket"),
       symbol,
       toolkit_experimental.rollup(candlestick) as candlestick 
FROM "candlestick_1m"
GROUP BY 1, 2
WITH NO DATA;

CREATE MATERIALIZED VIEW candlestick_1d
WITH (timescaledb.continuous) AS
SELECT time_bucket('1 day', "time_bucket"),
       symbol,
       toolkit_experimental.rollup(candlestick) as candlestick
FROM "candlestick_1h"
GROUP BY 1, 2
WITH NO DATA;

    INSERT INTO ticks
    SELECT time, 'SYMBOL', 1 + (random()*30)::int, 100*(random()*10)::int
    FROM generate_series(TIMESTAMP '2022-01-01 00:00:00',
                    TIMESTAMP '2022-02-01 00:01:00',
                INTERVAL '15 min') AS time;

如果可以在较长的时间范围内使用 toolkit_experimental.rollup() 进行分组。

请注意,烛台对象需要通过每个属性的函数访问。


SELECT time_bucket,
  symbol,
  toolkit_experimental.open(candlestick),
  toolkit_experimental.high(candlestick),
  toolkit_experimental.low(candlestick),
  toolkit_experimental.close(candlestick),
  toolkit_experimental.volume(candlestick)
FROM candlestick_1d
WHERE time_bucket BETWEEN '2022-01-01' and '2022-01-07';

要构建 where 子句以仅按正确的日期进行过滤,您需要使用 extract(hour from...)

例子:

select extract(hour from TIMESTAMP '2022-01-19 10:00');
┌─────────┐
│ extract │
├─────────┤
│      10 │
└─────────┘

然后,对于您的情况,您可以在实体化视图中构建一个额外的 where 子句来组成这个所需的场景。

【讨论】:

    猜你喜欢
    • 2020-03-05
    • 1970-01-01
    • 2016-03-12
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2020-05-31
    相关资源
    最近更新 更多