在influxdb中合并不同粒度的时间序列
Merging different granularity time series in influxdb
我想在 InfluxDB 中存储交易以及最好的 ask/bid 数据,其中后者的更新速度比前者快得多。
如果可能,我想使用允许我查询的架构:"for each trade on market X, find the best ask/bid on market Y whose timestamp is <= the timestamp of the trade"。
(我将使用任何版本的 Influx。)
例如,交易可能如下所示:
Time Price Volume Direction Market
00:01.000 100 5 1 foo-bar
00:03.000 99 50 0 bar-baz
00:03.050 99 25 0 foo-bar
00:04.000 101 15 1 bar-baz
报价数据可能看起来更像这样:
Time Ask Bid Market
00:00.763 100 99 bar-baz
00:01.010 101 99 foo-bar
00:01.012 101 98 bar-baz
00:01.012 101 99 foo-bar
00:01:238 100 99 bar-baz
...
00:03:021 101 98 bar-baz
我希望能够以某种方式加入某个市场的每笔交易,例如foo-bar,仅包含其他市场的最新 ask/bid 数据点,例如bar-baz,得到如下结果:
Time Trade Price Ask Bid
00:01.000 100 100 99
00:03.050 99 101 98
这样我就可以计算出市场交易价格 foo-bar 和市场上最近报价的卖价或买价 bar-baz。
现在,我将交易存储在一个时间序列中,将 ask/bid 数据点存储在另一个时间序列中,并在客户端合并它们,逻辑如下:
function merge(trades, quotes, data_points)
next_trade, more_trades = first(trades), rest(trades)
quotes = drop-while (quote.timestamp < next_trade.timestamp) quotes
data_point = join(next_trade, first(quotes))
if more_trades
return merge(more_trades, quotes, data_points + data_point)
return data_points + data_point
问题是客户端必须丢弃大量 ask/bid 数据点,因为它们更新如此频繁,并且只有交易前的最新更新是相关的。
有数十个市场的最近 ask/bid 我可能想与交易进行比较,否则我只是将最近的 ask/bid 存储在与交易相同的系列中。
是否可以用 Influx 或其他时间序列数据库做我想做的事情?产生较低质量结果的另一种解决方案是按某个时间间隔(比如 250 毫秒)对 ask/bid 数据进行分组,并从每个间隔中取最后一个,以至少对客户必须的报价数量施加上限在找到最接近下一笔交易的交易之前下跌。
注意。只是对 InfluxDB 术语的澄清。您可能以不同的测量方式存储交易和报价数据(类似于 table)。系列是基于标签值的测量的细分。例如
Time Ask Bid Market
00:00.763 100 99 bar-baz
是一个系列
Time Ask Bid Market
00:01.010 101 99 foo-bar
是另一个系列(假设您将市场 name/id 存储为标签而不是字段)
回答
- InfluxQL https://docs.influxdata.com/influxdb/v1.7/query_language/spec/ - 我想不出一种方法来使用 InfluxQL(Influx 查询语言)实现您的需求,因为它不支持连接。
也许您可以在客户端做的不是请求一段时间内的所有报价数据并丢弃其中的大部分数据,而是针对每个交易和市场发出请求以准确获取(关于交易的最新数据)ask/bid 你需要的数据点。类似于:
function merge(trades, market)
points = <empty list>
for next_trade in trades
quote = db.query("select last(ask), last(bid) from tick_data where time<=next_trade.timestamp and Market=market and time>next_trade.timestamp - 1m")
// or to get a list per market with one query
// quote_per_market = db.query("select last(ask), last(bid) from tick_data where time<=next_trade.timestamp group by Market")
points = points + join(next_trade, quote)
return points
当然,您会有更频繁地查询数据库的开销,但根据交易数量和您的资源限制,它可能会更有效率。注意。这里的一个潜在陷阱是,以这种方式检索到的 ask
和 bid
不是成对检索的,而是独立检索的,当它们成对返回时,它们可能具有不同的时间戳。如果出于某种原因,由于某些时间戳,您只有 ask
或 bid
价格,您可能 运行 会遇到此问题。但是,只要您将它们成对写入并且没有丢失数据,就应该没问题。
Flux https://www.influxdata.com/products/flux/ - Flux 是一种更复杂的查询语言,它是 Influxdb 1.7 和 2 的一部分,允许您跨不同的测量进行连接和操作。我还不能给你任何例子,但值得一看。
您可以查看的其他(关系)时间序列数据库也是 CrateDB https://crate.io/ or Postgres + TimescaleDB https://www.timescale.com/products
我想在 InfluxDB 中存储交易以及最好的 ask/bid 数据,其中后者的更新速度比前者快得多。
如果可能,我想使用允许我查询的架构:"for each trade on market X, find the best ask/bid on market Y whose timestamp is <= the timestamp of the trade"。
(我将使用任何版本的 Influx。)
例如,交易可能如下所示:
Time Price Volume Direction Market
00:01.000 100 5 1 foo-bar
00:03.000 99 50 0 bar-baz
00:03.050 99 25 0 foo-bar
00:04.000 101 15 1 bar-baz
报价数据可能看起来更像这样:
Time Ask Bid Market
00:00.763 100 99 bar-baz
00:01.010 101 99 foo-bar
00:01.012 101 98 bar-baz
00:01.012 101 99 foo-bar
00:01:238 100 99 bar-baz
...
00:03:021 101 98 bar-baz
我希望能够以某种方式加入某个市场的每笔交易,例如foo-bar,仅包含其他市场的最新 ask/bid 数据点,例如bar-baz,得到如下结果:
Time Trade Price Ask Bid
00:01.000 100 100 99
00:03.050 99 101 98
这样我就可以计算出市场交易价格 foo-bar 和市场上最近报价的卖价或买价 bar-baz。
现在,我将交易存储在一个时间序列中,将 ask/bid 数据点存储在另一个时间序列中,并在客户端合并它们,逻辑如下:
function merge(trades, quotes, data_points)
next_trade, more_trades = first(trades), rest(trades)
quotes = drop-while (quote.timestamp < next_trade.timestamp) quotes
data_point = join(next_trade, first(quotes))
if more_trades
return merge(more_trades, quotes, data_points + data_point)
return data_points + data_point
问题是客户端必须丢弃大量 ask/bid 数据点,因为它们更新如此频繁,并且只有交易前的最新更新是相关的。
有数十个市场的最近 ask/bid 我可能想与交易进行比较,否则我只是将最近的 ask/bid 存储在与交易相同的系列中。
是否可以用 Influx 或其他时间序列数据库做我想做的事情?产生较低质量结果的另一种解决方案是按某个时间间隔(比如 250 毫秒)对 ask/bid 数据进行分组,并从每个间隔中取最后一个,以至少对客户必须的报价数量施加上限在找到最接近下一笔交易的交易之前下跌。
注意。只是对 InfluxDB 术语的澄清。您可能以不同的测量方式存储交易和报价数据(类似于 table)。系列是基于标签值的测量的细分。例如
Time Ask Bid Market
00:00.763 100 99 bar-baz
是一个系列
Time Ask Bid Market
00:01.010 101 99 foo-bar
是另一个系列(假设您将市场 name/id 存储为标签而不是字段)
回答
- InfluxQL https://docs.influxdata.com/influxdb/v1.7/query_language/spec/ - 我想不出一种方法来使用 InfluxQL(Influx 查询语言)实现您的需求,因为它不支持连接。 也许您可以在客户端做的不是请求一段时间内的所有报价数据并丢弃其中的大部分数据,而是针对每个交易和市场发出请求以准确获取(关于交易的最新数据)ask/bid 你需要的数据点。类似于:
function merge(trades, market)
points = <empty list>
for next_trade in trades
quote = db.query("select last(ask), last(bid) from tick_data where time<=next_trade.timestamp and Market=market and time>next_trade.timestamp - 1m")
// or to get a list per market with one query
// quote_per_market = db.query("select last(ask), last(bid) from tick_data where time<=next_trade.timestamp group by Market")
points = points + join(next_trade, quote)
return points
当然,您会有更频繁地查询数据库的开销,但根据交易数量和您的资源限制,它可能会更有效率。注意。这里的一个潜在陷阱是,以这种方式检索到的 ask
和 bid
不是成对检索的,而是独立检索的,当它们成对返回时,它们可能具有不同的时间戳。如果出于某种原因,由于某些时间戳,您只有 ask
或 bid
价格,您可能 运行 会遇到此问题。但是,只要您将它们成对写入并且没有丢失数据,就应该没问题。
Flux https://www.influxdata.com/products/flux/ - Flux 是一种更复杂的查询语言,它是 Influxdb 1.7 和 2 的一部分,允许您跨不同的测量进行连接和操作。我还不能给你任何例子,但值得一看。
您可以查看的其他(关系)时间序列数据库也是 CrateDB https://crate.io/ or Postgres + TimescaleDB https://www.timescale.com/products