将1分钟的OHLCV蜡烛数据重新采样为5分钟的OHLCV蜡烛数据。

huangapple go评论53阅读模式
英文:

PostgreSQL resample 1 minute OHLCV candle data into 5 minute OHLCV candle data

问题

我有一个包含以下列的postgreSQL数据库:

timestamp <bigint> - 以毫秒为单位的Unix时间戳
open <float> - 第一个交易价格
high <float> - 最高交易价格
low <float> - 最低交易价格
close <float> - 最后的交易价格
volume <float> - 在该时间段内交易的总成交量


有时我会查询跨越30+天(43.2k行)的数据。这些查询需要很长时间,因此我想每当我有超过30天的数据时,我将获取5分钟的蜡烛图,这将减少行数约5倍。

基本上,我正在寻找一个执行以下操作的函数(伪代码):

SELECT
first_value(timestamp),
first_value(open),
max(high),
min(low),
last_value(close),
sum(volume)
WHERE timestamp > {过去某个时间戳} AND timestamp < {当前时间}
GROUP BY floor((timestamp / 1000) / (60*5)) * 5
ORDER BY timestamp


非常感谢任何帮助,已经卡在这个问题上有一段时间了
英文:

I have a postgreSQL database with the following columns:

timestamp &lt;bigint&gt; - Unix timestamp in milliseconds
open      &lt;float&gt;  - The first traded price
high      &lt;float&gt;  - The highest traded price
low       &lt;float&gt;  - THe lowest traded price
close     &lt;float&gt;  - The last traded price
volume    &lt;float&gt;  - The total volumed transacted during the time period

Sometimes I'll query data that spans 30+ days (43.2k rows). These queries take a really long time, so I thought whenever I have >30 days of data I'll fetch 5 minute candles instead which would cut down the row count by 5x.

Basically I'm looking for a function that does this (pseudocode):

SELECT 
first_value(timestamp),
first_value(open),
max(high),
min(low),
last_value(close),
sum(volume)
WHERE timestamp &gt; {some timestamp in the past} AND timestamp &lt; {current time}
GROUP BY floor((timestamp / 1000) / (60*5)) * 5
ORDER BY timestamp

Any help would be greatly appreciated, been stuck on this one for a while

答案1

得分: 2

使用了一个子查询来获取列:minute5。在它上面进行了分组和排序。要获取第一个值,使用array_agg进行排序,并通过方括号取值。对于'close'也是同样的方式,但是方向相反。

以下是代码的翻译:

SELECT 
min(timestamp) AS 时间戳, 
(array_agg(open ORDER BY timestamp))[1] AS 开盘价, 
max(high) AS 最高价, 
min(low) AS 最低价,  
(array_agg(close ORDER BY timestamp DESC))[1] AS 收盘价, 
sum(volume) 成交量
FROM
(SELECT *, floor((timestamp/1000) / (60*5)) * 5 AS minute5
FROM stock
ORDER BY timestamp
) t
GROUP BY
minute5
ORDER BY
minute5
;

这是链接,创建表格并获取数据(添加了一个dt列,用于可视化查看每行的日期和时间)。

英文:

Used a subquery to get the column: minute5. On it made grouping and sorting. To get the first value, &#39;open&#39; use array_agg with sorting and took the value through square brackets. The same with &#39;close&#39;, but in the other direction.

SELECT 
min(timestamp) AS timestamp, 
(array_agg(open ORDER BY timestamp))[1] AS open, 
max(high) AS high, 
min(low) AS low,  
(array_agg(close ORDER BY timestamp DESC))[1] AS close, 
sum(volume) volume
FROM
(SELECT*, floor((timestamp/1000) / (60*5)) * 5 AS minute5
FROM stock
ORDER BY timestamp
) t
GROUP BY
minute5
ORDER BY
minute5
;

Here's the link: creating a table and getting data (added a dt column with a type to visually see what date and time for each row).

huangapple
  • 本文由 发表于 2023年3月20日 23:14:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75792066.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定