如何在 DolphinDB 中计算 OHLC 条

博客介绍了使用DolphinDB进行OHLC柱计算的方法。包括批量计算,如不指定、指定启动时间,处理重叠窗口、按交易量确定窗口,还可用MapReduce加速;也提及实时计算,即通过API接收市场数据,用内置时序引擎计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们将解释如何在以下场景中使用批量计算来计算 OHLC 柱:

  • 需要指定 OHLC 窗口的启动时间;
  • 一天中有多个交易时段,包括隔夜时段;
  • 重叠 OHLC 窗口;
  • OHLC 窗口根据交易量划分。

如果数据量非常大,需要将结果写入数据库,我们可以使用 DolphinDB 内置的 Map-Reduce 功能进行并行计算。

  • 有实时数据

使用 API 实时接收市场数据,并使用 DolphinDB 内置的时序引擎进行实时计算。

1.用历史数据计算(批量计算)

要使用历史数据计算 OHLC 柱,您可以使用 DolphinDB 的内置函数bar, dailyAlignedBar

1.1 不指定 OHLC Windows 的启动时间

函数bar一般用于根据指定的区间对数据进行分组。

date = 09:32m 09:33m 09:45m 09:49m 09:56m 09:56m;
bar(date, 5);

结果是: 

[09:30m,09:30m,09:45m,09:45m,09:55m,09:55m]

示例 1: 

n = 1000000
date = take(2019.11.07 2019.11.08, n)
time = (09:30:00.000 + rand(int(6.5*60*60*1000), n)).sort!()
timestamp = concatDateTime(date, time)
price = 100+cumsum(rand(0.02, n)-0.01)
volume = rand(1000, n)
symbol = rand(`AAPL`FB`AMZN`MSFT, n)
trade = table(symbol, date, time, timestamp, price, volume).sortBy!(`symbol`timestamp)
undef(`date`time`timestamp`price`volume`symbol);

计算 5 分钟 OHLC 柱: 

barMinutes = 5m
OHLC = select first(price) as open, max(price) as high, min(price) as low, last(price) as close, sum(volume) as volume from trade group by symbol, date, bar(time, barMinutes) as barStart

函数参数intervalbar支持DURATION类型。这里的“5m”表示5分钟。

1.2 需要指定OHLC窗口的启动时间

使用函数dailyAlignedBar指定 OHLC 窗口的开始时间。此功能可以容纳每天多个交易时段以及隔夜时段。

请注意,对于 function dailyAlignedBar,时间列的数据类型可以是 SECOND、TIME、NANOTIME、DATETIME、TIMESTAMP 和 NANOTIMESTAMP。指定每个交易时段开始时间的参数timeOffset必须具有相应的数据类型:分别为 SECOND、TIME 或 NANOTIME。

示例 2(每天一个交易时段):使用示例 1 中的相同表格“交易”计算 7 分钟 OHLC 柱。

barMinutes = 7m
OHLC = select first(price) as open, max(price) as high, min(price) as low, last(price) as close, sum(volume) as volume from trade group by symbol, dailyAlignedBar(timestamp, 09:30:00.000, barMinutes) as barStart

例3(每天两个交易时段):中国股市每天有两个交易时段,上午9:30-11:30,下午13:00-15:00。

使用以下脚本生成模拟数据:

n = 1000000
date = take(2019.11.07 2019.11.08, n)
time = (09:30:00.000 + rand(2*60*60*1000, n/2)).sort!() join (13:00:00.000 + rand(2*60*60*1000, n/2)).sort!()
timestamp = concatDateTime(date, time)
price = 100+cumsum(rand(0.02, n)-0.01)
volume = rand(1000, n)
symbol = rand(`600519`000001`600000`601766, n)
trade = table(symbol, timestamp, price, volume).sortBy!(`symbol`timestamp)
undef(`date`time`timestamp`price`volume`symbol)

计算 7 分钟 OHLC 柱: 

barMinutes = 7m
sessionsStart=09:30:00.000 13:00:00.000
sessionsEnd=11:30:00.000 15:00:00.000
OHLC = select first(price) as open, max(price) as high, min(price) as low, last(price) as close, sum(volume) as volume from trade group by symbol, dailyAlignedBar(timestamp, sessionsStart, barMinutes, sessionsEnd) as barStart

示例 4(每天两个交易时段,隔夜时段):一些期货每天有多个交易时段,包括隔夜时段。在这个例子中,第一个交易时段是从上午 8:45 到下午 13:45,另一个时段是从下午 15:00 到第二天凌晨 05:00 的隔夜时段。

使用以下脚本生成模拟数据:

daySession =  08:45:00.000 : 13:45:00.000
nightSession = 15:00:00.000 : 05:00:00.000
n = 1000000
timestamp = rand(concatDateTime(2019.11.06, daySession[0]) .. concatDateTime(2019.11.08, nightSession[1]), n).sort!()
price = 100+cumsum(rand(0.02, n)-0.01)
volume = rand(1000, n)
symbol = rand(`A120001`A120002`A120003`A120004, n)
trade = select * from table(symbol, timestamp, price, volume) where timestamp.time() between daySession or timestamp.time()>=nightSession[0] or timestamp.time()<nightSession[1] order by symbol, timestamp
undef(`timestamp`price`volume`symbol);

计算 7 分钟 OHLC 柱: 

barMinutes = 7
sessionsStart = [daySession[0], nightSession[0]]
OHLC = select first(price) as open, max(price) as high, min(price) as low, last(price) as close, sum(volume) as volume from trade group by symbol, dailyAlignedBar(timestamp, sessionsStart, barMinutes*60*1000) as barStart;

1.3 重叠 OHLC 窗口

在上述示例中,OHLC 窗口不重叠。要计算重叠的 OHLC 窗口,我们可以使用函数wj (窗口连接)。使用该wj函数,左表的每一行对应右表的一个窗口,可以在这个窗口上进行计算。

示例 5: 每天两个交易时段,OHLC 窗口重叠

模拟中国股市数据,每 5 分钟计算一个 30 分钟 OHLC 柱。

n = 1000000
sampleDate = 2019.11.07
symbols = `600519`000001`600000`601766
trade = table(take(sampleDate, n) as date, 
	(09:30:00.000 + rand(7200000, n/2)).sort!() join (13:00:00.000 + rand(7200000, n/2)).sort!() as time, 
	rand(symbols, n) as symbol, 
	100+cumsum(rand(0.02, n)-0.01) as price, 
	rand(1000, n) as volume)

首先生成 OHLC 窗口,然后使用函数cj(交叉连接)生成股票代码和 OHLC 窗口的组合。 

barWindows = table(symbols as symbol).cj(table((09:30:00.000 + 0..23 * 300000).join(13:00:00.000 + 0..23 * 300000) as time))

然后使用函数wj计算具有重叠窗口的 OHLC 条: 

OHLC = wj(barWindows, trade, 0:(30*60*1000), 
		<[first(price) as open, max(price) as high, min(price) as low, last(price) as close, sum(volume) as volume]>, `symbol`time)

1.4 根据交易量确定窗口

上述所有示例中的窗口都是随时间确定的。您还可以希望使用其他变量(例如交易量)作为确定窗口的基础。

示例 6:每次交易量增加 1,000,000 时计算 OHLC 柱。

n = 1000000
sampleDate = 2019.11.07
symbols = `600519`000001`600000`601766
trade = table(take(sampleDate, n) as date, 
	(09:30:00.000 + rand(7200000, n/2)).sort!() join (13:00:00.000 + rand(7200000, n/2)).sort!() as time, 
	rand(symbols, n) as symbol, 
	100+cumsum(rand(0.02, n)-0.01) as price, 
	rand(1000, n) as volume)
	
volThreshold = 1000000
t = select first(time) as barStart, first(price) as open, max(price) as high, min(price) as low, last(price) as close, last(cumvol) as cumvol 
from (select symbol, time, price, cumsum(volume) as cumvol from trade context by symbol)
group by symbol, bar(cumvol, volThreshold) as volBar;

1.5 使用 MapReduce 加速计算

如果您需要从数据库中提取大规模的历史数据,计算出OHLC柱,然后将它们保存到数据库中,您可以使用内置的MapReduce函数mr进行并行加载和计算。这种方法可以显着提高速度。

此示例使用美国股市交易数据。原始数据存储在数据库“dfs://TAQ”中的“trades”表中,具有复合分区:基于交易日期的值分区和基于股票代码的范围分区。

(1) 将磁盘上表的元数据加载到内存中:

login(`admin, `123456)
db = database("dfs://TAQ")
trades = db.loadTable("trades")

(2) 创建一个模板表'model',然后根据模板表的schema在数据库“dfs://TAQ”中创建一个空表'OHLC'来存储结果: 

model=select top 1 Symbol, Date, Time.second() as bar, PRICE as open, PRICE as high, PRICE as low, PRICE as close, SIZE as volume from trades where Date=2007.08.01, Symbol=`EBAY
if(existsTable("dfs://TAQ", "OHLC"))
	db.dropTable("OHLC")
db.createPartitionedTable(model, `OHLC, `Date`Symbol)

(3) 使用函数mr计算 OHLC 柱并将结果写入表 'OHLC': 

  • 'ds' 是函数生成的一系列数据源sqlDS。每个数据源代表一个分区中的数据。
  • FunctioncalcOHLC是 MapReduce 中的映射函数。它从每个数据源计算 OHLC 柱,将结果写入数据库并返回写入数据库的行数。
  • “+”是 MapReduce 中的 reduce 函数。它将所有映射函数的结果(写入数据库的行数)相加,以返回写入数据库的总行数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wouderw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值