Metadata-Version: 2.5
Name: vikron-nautilus
Version: 0.1.1
Summary: Read Vikron Catalog data with NautilusTrader Python
Project-URL: Repository, https://gitee.com/vikron-data/vikron-nautilus
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.12
Requires-Dist: packaging>=24
Requires-Dist: pyarrow<27,>=21
Provides-Extra: v1
Requires-Dist: nautilus-trader<2.0.0,>=1.226.0; extra == 'v1'
Provides-Extra: v2
Requires-Dist: nautilus-trader<2.1.0,>=2.0.0rc6; extra == 'v2'
Description-Content-Type: text/markdown

# vikron-nautilus

在 Python 或 Rust 中读取 Vikron Downloader 生成的 Nautilus Catalog 数据，用于行情分析及 NautilusTrader 策略开发。

本项目提供 Python 包和 Rust crate，按使用语言安装其中一个即可。

## 使用范围

先在 Vikron Downloader 中选择对应的 Catalog 输出格式，再使用本库读取下载后的目录。

| 输出格式 | 数据目录 | Python：NautilusTrader 支持范围 | Rust：Nautilus 支持范围 |
| --- | --- | --- | --- |
| Catalog v1 | `vikron/catalog-v1` | `>=1.226.0, <2.0.0` | `>=0.64.0, <0.65.0`（`0.64.x`） |
| Catalog v2 | `vikron/catalog-v2` | `>=2.0.0rc6, <2.1.0` | `>=0.65.0, <0.66.0`（`0.65.x`） |

这里的 Python 1.x / 2.x 指 NautilusTrader 包版本，不是 Python 解释器版本。

支持读取的数据：

| 数据 | 类型归属 | 类型名称（Python / Rust） | 数据来源 | 主要源字段 |
| --- | --- | --- | --- | --- |
| 报价 | Nautilus 原生 | `QuoteTick` | `book_ticker` | `bid_price`、`ask_price`、`bid_amount`、`ask_amount` |
| 成交 | Nautilus 原生 | `TradeTick` | `trades` | `id`、`side`、`price`、`amount` |
| 订单簿增量 | Nautilus 原生 | `OrderBookDelta` | `incremental_book_L2` | `is_snapshot`、`side`、`price`、`amount` |
| 标记价格 | Nautilus 原生 | `MarkPriceUpdate` | `derivative_ticker` | `mark_price` |
| 指数价格 | Nautilus 原生 | `IndexPriceUpdate` | `derivative_ticker` | `index_price` |
| 资金费率 | Nautilus 原生 | `FundingRateUpdate` | `derivative_ticker` | `funding_rate`、`funding_timestamp` |
| 强平 | Vikron 自定义 | `Liquidation` | `liquidations` | `id`、`side`、`price`、`amount` |
| 持仓量 | Vikron 自定义 | `OpenInterestUpdate` | `derivative_ticker` | `open_interest` |
| 最新价格 | Vikron 自定义 | `LastPriceUpdate` | `derivative_ticker` | `last_price` |
| 预测资金费率 | Vikron 自定义 | `PredictedFundingRateUpdate` | `derivative_ticker` | `predicted_funding_rate`、`funding_timestamp` |

“数据来源”对应 Vikron Downloader 创建任务时选择的数据类型；“主要源字段”为原始数据中的业务字段，不含各类数据共用的时间字段。

具体可用的数据取决于 Downloader 的输出。本库不下载行情、不转换 CSV，也不创建或补全交易品种的 `Instrument` 信息。

## Python 使用方法

### 安装

需要 Python 3.12 或以上版本，同时满足对应 NautilusTrader 版本的平台要求。建议为两个版本分别创建虚拟环境，不要混装。

使用 Catalog v1：

```sh
python -m pip install "vikron-nautilus[v1]==0.1.1"
```

使用 Catalog v2：

```sh
python -m pip install "vikron-nautilus[v2]==0.1.1"
```

### 读取数据

下面以 Catalog v2 的强平数据为例。路径指向 Catalog 根目录，不是其中的 `data` 子目录；将路径和品种替换成自己的数据。

```python
from vikron_nautilus import Catalog, Liquidation

catalog = Catalog("./data/vikron/catalog-v2", version=2)
events = catalog.query(
    Liquidation,
    identifiers=["ETHUSDT-PERP.BINANCE"],
)
for event in events:
    print(event.instrument_id, event.price, event.size, event.ts_init)
```

使用 v1 时，将路径改成 `./data/vikron/catalog-v1`，并设置 `version=1`。

读取原生行情类型时，替换查询类型即可。例如，v2 的报价数据：

```python
from nautilus_trader.model import QuoteTick

quotes = catalog.query(QuoteTick, identifiers=["ETHUSDT-PERP.BINANCE"])
```

v1 的原生行情类型从 `nautilus_trader.model.data` 导入：

```python
from nautilus_trader.model.data import QuoteTick
```

### 限定查询范围

`identifiers` 使用完整的 Nautilus `InstrumentId`。`start` 和 `end` 是 Unix 纳秒时间戳，按 `ts_init` 筛选，包含起止边界；省略参数表示不限制该条件。

```python
events = catalog.query(
    Liquidation,
    identifiers=["ETHUSDT-PERP.BINANCE"],
    start=1788220800000000000,  # 2026-09-01 00:00:00 UTC
    end=1788307199999999999,    # 2026-09-01 当天结束（UTC）
)
```

查询返回对象列表，空数据返回空列表。较大的历史范围建议按日期和品种分批读取。

### 使用自定义数据

本库的 `Catalog` 会自动注册上表中的四种自定义数据。使用官方接口时，Python 和 Rust 的 v1、v2 都通过 `prepare_catalog(path)` 初始化，返回绝对路径，无需再单独注册类型。Python 按已安装的 NautilusTrader 版本选择适配方式，Rust 按启用的 Catalog feature 选择。

`prepare_catalog` 从 `0.1.1` 起提供。

Python v2 初始化示例：

```python
from vikron_nautilus import prepare_catalog
from nautilus_trader.persistence import ParquetDataCatalog

path = prepare_catalog("./data/vikron/catalog-v2")
catalog = ParquetDataCatalog(path)
```

Python 1.x 也可以按下面的方法使用官方 Catalog 和 BacktestNode。

### Python v1：使用官方 Catalog 和 BacktestNode

安装：

```sh
python -m pip install "vikron-nautilus[v1]==0.1.1"
```

每次运行程序时，先初始化目录，再使用官方接口：

```python
from vikron_nautilus import prepare_catalog, Liquidation
from nautilus_trader.model.data import QuoteTick
from nautilus_trader.persistence.catalog import ParquetDataCatalog

path = prepare_catalog("./data/vikron/catalog-v1")
catalog = ParquetDataCatalog(path)
quotes = catalog.query(QuoteTick, identifiers=["ETHUSDT-PERP.BINANCE"])
liquidations = catalog.query(Liquidation, identifiers=["ETHUSDT-PERP.BINANCE"])
for event in liquidations:
    print(event.data.instrument_id, event.data.price, event.data.size)
```

官方查询返回的自定义事件为 `CustomData`，通过 `.data` 访问具体数据。原生行情直接返回对应对象。

初始化需要本地 Catalog 目录的写权限和创建目录符号链接的权限；Windows 可启用开发者模式或使用管理员终端。新增数据类型后再次初始化目录即可。

使用 BacktestNode 前，将自行准备的 `Instrument` 写入同一 Catalog。其价格和数量精度需匹配数据；Downloader 的 Catalog 数据使用 16 位小数精度。

```python
from nautilus_trader.backtest.config import (
    BacktestDataConfig, BacktestEngineConfig, BacktestRunConfig, BacktestVenueConfig,
)
from nautilus_trader.backtest.node import BacktestNode

# instruments 为你自行准备的 Instrument 对象列表。
catalog.write_data(instruments)
symbol = "ETHUSDT-PERP.BINANCE"
config = BacktestRunConfig(
    venues=[BacktestVenueConfig(
        name="BINANCE", oms_type="NETTING", account_type="MARGIN",
        starting_balances=["100000 USDT"],
    )],
    data=[
        BacktestDataConfig(
            catalog_path=path, data_cls="nautilus_trader.model.data:QuoteTick",
            instrument_ids=[symbol],
        ),
        BacktestDataConfig(
            catalog_path=path, data_cls="vikron_nautilus:Liquidation",
            instrument_ids=[symbol], client_id="VIKRON",
            metadata={"instrument_id": symbol},
        ),
    ],
    engine=BacktestEngineConfig(),  # 在此配置自己的策略。
    chunk_size=10000,              # 设置为 None 时一次性加载。
    raise_exception=True,
)
node = BacktestNode(configs=[config])
try:
    results = node.run()
finally:
    node.dispose()
```

策略中订阅自定义数据时，使用与配置一致的 metadata，例如 `DataType(Liquidation, {"instrument_id": symbol})`，并设置 `client_id=ClientId("VIKRON")`。多个品种的自定义数据可分别配置。

## Rust 使用方法

### 添加依赖

需要 Rust 1.98.1 或以上版本。在项目的 `Cargo.toml` 中添加以下依赖。

Catalog v2（默认）：

```toml
[dependencies]
anyhow = "1"
vikron-nautilus = "0.1.1"
nautilus-model = { version = "0.65", features = ["high-precision"] }
nautilus-persistence = { version = "0.65", features = ["high-precision"] }
```

Catalog v1：

```toml
[dependencies]
anyhow = "1"
vikron-nautilus = { version = "0.1.1", default-features = false, features = ["catalog-v1"] }
nautilus-model = { version = "0.64", features = ["high-precision"] }
nautilus-persistence = { version = "0.64", features = ["high-precision"] }
```

`catalog-v1` 和 `catalog-v2` 必须二选一，不要同时启用。

### 读取自定义数据

以下为 v2 示例：

```rust
use nautilus_model::data::Data;
use nautilus_persistence::backend::parquet::catalog::ParquetDataCatalog;
use vikron_nautilus::{Liquidation, prepare_catalog};

fn main() -> anyhow::Result<()> {
    let path = prepare_catalog("./data/vikron/catalog-v2")?;
    let mut catalog = ParquetDataCatalog::new(&path, None, None, None, None);
    let identifiers = vec!["ETHUSDT-PERP.BINANCE".to_string()];
    let events = catalog.query_custom_data_dynamic(
        "VikronLiquidation", Some(&identifiers), None, None, None, None, false,
    )?;

    for event in events {
        if let Data::Custom(custom) = event {
            if let Some(value) = custom.data.as_any().downcast_ref::<Liquidation>() {
                println!("{} {} {}", value.instrument_id, value.price, value.size);
            }
        }
    }
    Ok(())
}
```

使用 v1 时，将目录改为 `catalog-v1`，并将 `ParquetDataCatalog` 的导入改为：

```rust
use nautilus_persistence::backend::catalog::ParquetDataCatalog;
```

自定义数据的查询名称为类型名前加 `Vikron`，例如 `VikronOpenInterestUpdate`，读取后转换为对应 Rust 类型即可。Python 使用 `Catalog.query(Liquidation)` 等类型查询，无需手动添加前缀。已有 Catalog 文件无需修改。报价、成交等原生数据使用对应版本的 Nautilus 官方查询接口。

## 使用注意事项

- 不要混用 v1 与 v2 数据目录，选择与 Nautilus 版本匹配的输出格式。
- Python 自定义数据中的价格、数量和费率使用 `Decimal`，需要精确保留数值时避免转成 `float`。
- 回测或交易所需的 `Instrument` 信息需要自行提供。本库的自定义数据是行情观察事件，不会自动触发撮合或资金费结算。

## 许可证

本库采用 [MIT 许可证](LICENSE)。该许可不改变 Vikron Downloader 及依赖的许可证，也不授予行情数据的访问或再分发权利。
