8 个版本
0.2.3 | 2022年3月4日 |
---|---|
0.2.2 | 2022年3月4日 |
0.2.1 | 2021年12月2日 |
0.1.3 | 2021年9月15日 |
0.1.2 | 2021年8月30日 |
#3 in #trade
每月 38 次下载
100KB
3K SLoC
由 SIGDEV 提供 Quotick
嵌入式 tick 市场数据(交易、报价等)数据库存储,针对数十亿数据点进行优化。
$ cargo add quotick
使用说明
use serde_derive::{Deserialize, Serialize};
use quotick::quotick::Quotick;
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
struct Trade {
size: u32,
price: u32,
}
impl quotick::tick::Tick for Trade {
fn epoch(&self) -> u64 {
// one day
self.time / 86_400_000_000_000
}
}
fn main() {
let trade1 =
(
10, // time
Trade {
size: 1,
price: 2,
},
);
let trade2 =
(
11, // time
Trade {
size: 2,
price: 3,
},
);
let trade3 =
(
12,
Trade {
size: 3,
price: 4,
},
);
let quotick =
Quotick::<Trade>::new(
"SYMBL",
"./db",
);
qt.insert(&Frame::new(trade1.0, trade1.1));
qt.insert(&Frame::new(trade2.0, trade2.1));
qt.insert(&Frame::new(trade3.0, trade3.1));
qt.persist();
// iterate over all epochs
quotick
.epochs()
.for_each(
|mut epoch| {
// iterate over all frames
// in a given epoch
epoch
.frames()
.for_each(
|frame| {
frame.time(); // u64 time
frame.tick(); // your tick
},
);
}
);
// obtain the frame with the lowest
// time value of the first epoch (10)
dbg!(quotick.oldest_frame());
// obtain the frame with the highest
// time value of the last epoch (12)
dbg!(quotick.newest_frame());
}
架构
Quotick 可以包含无限数量的符号。每个符号使用一个内部数据库,每个符号存储在单独的目录中。
tick 使用 epoch 分隔。epoch 用于分离和加速对单个时间窗口(例如一天)内包含的 tick 的查找。
epoch 索引是基数 trie,并存储在一个以 epochs.qti
识别的文件中。
当查找 epoch、tick 或插入 tick 时,基数 trie 将被完全加载到内存中。它在 quotick 超出范围并被丢弃,或者程序运行期间保持内存中。
当 epoch 在 epoch 索引中找到时,如果不在此处,它将被添加到索引中,epoch 的 tick-index 将从 frameset/[epoch].qti
加载,如果不存在,则初始化。它是一个基数 trie,包含所有通过其纳秒级时间戳标识的 tick。
时间戳必须以纳秒级精度。Quotick 未设计为存储通过任意标识符标识的 tick,并依赖于 tick 的时间戳必须是可排序的事实。
tick 数据存储在一个从 frameset/[epoch].qtf
加载的文件中,称为 frameset。内部,每个 tick 代表一个帧。
当 tick 被插入到 epoch 中时,它被追加到文件的末尾,并将 tick 的偏移量存储为(u64 时间戳,u64 偏移量)元组,在相应 epoch 的 tick-index 基数 trie 中。
当迭代 epoch 的 tick-index 时,按需从 frameset 文件加载返回的 tick。frameset 将跳转到支持文件的所需偏移量,读取相应数量的字节,并尝试将它们反序列化为帧。
如果您以随机顺序插入 tick,则必须对 epoch 进行碎片整理以防止在 HDD 上出现显著的读头跳跃。强烈建议使用 NVMe 存储空间为 Quotick。
注意
存储在Quotick内部的Tick必须实现quotick::tick::Tick
,它依赖于Default、Debug、Deserialize和Serialize。
请注意,Default
是必需的,以便能够确定结构体在由bincode
序列化时的尺寸。它与std::mem::size_of<T>()
不同,因此是强制性的。
Deserialize
和Serialize
是必需的,以便能够将Tick写入和读取到文件中。
许可证
如果您的组织年收入超过100万美元(或等值货币),您必须获得使用许可证。请联系[email protected]。
以下许可证适用
~~ 使用许可证 ~~
版权所有 (c) 2021 SIGDEV LLC 版权所有 (c) 2021 Kenan Sulayman
在此特此授予任何获得此软件及其相关文档副本(以下简称“软件”)的人士,在不受限制的情况下处理软件的权利,包括但不限于使用、复制、修改、合并、发布、分发和/或销售软件副本的权利,以及允许向软件提供的人士行使上述权利,但受以下条件约束:
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
如果组织的总收入或个人的总收入,或一组个人的总收入,如果此软件直接或间接使除原始用户以外的个人受益,每年超过100万美元(或等值货币),则本许可证不适用。
软件按“原样”提供,不提供任何形式的保证,无论是明示的、暗示的,包括但不限于适销性、特定目的适用性和非侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论该责任是基于合同、侵权或其他原因,以及与软件或软件的使用或其他处理相关的任何责任。
依赖项
~1.6–2.6MB
~50K SLoC