跳转到内容

研究图表与辅助工具

Load data into Rust 成功后,研究单元格即可使用这些辅助工具。它们是 AQS 提供的笔记本辅助工具,而不是额外的 AQE 策略 API。升级 AQS 后,重新加载数据,即可在现有会话中安装新的辅助工具。

data 是以已加载品种代码为键的 AqsData 集合。它包装一个 HashMap<String, DataFrame>,并通过解引用继续支持索引(data["BTCUSD"])、get、insert 和其他映射方法。它不是 HashMap 的类型别名。bars 仍是第一个已加载品种的工作副本。历史时间戳是 UTC Unix 毫秒数,存储在名为 timestamp 的 Int64 列中。

data.symbols() // Sorted symbol names
data.summary()?; // Table of symbols, row counts and columns
let mut btc = data.bars("BTCUSD")?;
let mut eth = data.bars("ETHUSD")?;

请使用与提供商完全一致的品种代码,例如 Yahoo 的 BTC-USD。找不到品种时会报错,并列出可用品种。每次调用 bars 都会返回独立的 Polars 工作副本:在 btc 上计算指标不会改变 data 或 eth。也可以使用等效的独立函数 aqs_symbols(&data) 和 aqs_bars(&data, "BTCUSD")?。

会话面板中的 Loaded symbols 选择器,可以为某个品种添加现成的表格和 K 线分析单元格。该操作只插入代码,不会执行。

aqs_table(&bars, 10)?;

aqs_table(frame: &DataFrame, limit: usize) 返回 Result<(), Box<dyn std::error::Error>>。它输出列名和格式化值,不修改 DataFrame。

辅助工具最多包含 100 行。查看器最多显示 50 列。预览限制不会截断可用于分析的 DataFrame。

aqs_plot(&bars, "close")?;
aqs_plot_many(&bars, &["close", "EMA_20", "EMA_50"])?;

aqs_plot(frame: &DataFrame, column: &str) 返回 Result<(), Box<dyn std::error::Error>>。所选列必须能转换为 Float64;timestamp 必须是以毫秒表示的 Int64。缺失列或不兼容类型会产生单元格错误。

每次调用创建一个图表;aqs_plot_many 将多条线放在同一价格轴上。指定列必须已经存在。同一单元格可以按调用顺序输出表格和图表:

aqs_table(&bars, 5)?;
aqs_plot(&bars, "close")?;
AQS 研究笔记本,展示 Rust 图表配置、BTCUSD K 线、EMA 20 和 EMA 50 叠加线,以及价格图下方独立的 Volume 和 ATR 窗格。AQS 研究笔记本,展示 Rust 图表配置、BTCUSD K 线、EMA 20 和 EMA 50 叠加线,以及价格图下方独立的 Volume 和 ATR 窗格。

研究图表配置及其输出:BTCUSD K 线叠加两条移动平均线,并在同步窗格中显示成交量柱状图和 ATR 折线。查看全尺寸截图查看全尺寸截图。

use aq_engine::core::indicators::{
Indicator, atr::AverageTrueRange, ema::ExponentialMovingAverage,
};
let mut btc = data.bars("BTCUSD")?;
let mut atr = AverageTrueRange::new(14);
atr.run(&mut btc)?;
let mut ema20 = ExponentialMovingAverage::new(20, "close");
ema20.run(&mut btc)?;
let mut ema50 = ExponentialMovingAverage::new(50, "close");
ema50.run(&mut btc)?;
aqs_chart(&btc)
.title("BTCUSD · trend and volatility")
.candles()
.line("EMA_20").label("EMA 20")
.line("EMA_50").label("EMA 50")
.pane("Volume", |p| p.histogram("volume"))
.pane("ATR", |p| p.line("ATRr_14"))
.height(650)
.max_points(1000)
.show()?;

AQE 指标直接处理普通 Polars DataFrame。请加载足够的历史数据,以覆盖最长指标周期及其预热需求。图表构建器只负责绘制已有列,不会因为你将指标名称传给 line 就自动计算指标。如果某列没有任何有限值,单元格会报错。

主图和窗格构建器支持 .line(column)、.area(column)、.histogram(column)、.candles() 和 .ohlc()。.label(text) 重命名该构建器中的最后一个序列。K 线和 OHLC 线需要 open、high、low 和 close 列。所有时间序列都需要 timestamp。

笔记本时间图支持缩放/平移、共享时间轴、悬停读数、自动序列颜色和可调整大小的窗格分隔线。每个窗格有自己的纵轴刻度;同一窗格中的叠加线共享该刻度。价格和成交量等不同单位应放入不同窗格。.height(pixels) 限制在 240–1200;默认高度随窗格数增加。最多支持六个窗格和总计十二个序列。

图表显示前会按时间戳排序,并将毫秒转换为秒。多行数据落在同一秒时,所有叠加线都会采用最后一条原始记录。空值或超出范围的时间戳会被排除;空值和非有限数值也会被排除,包括指标预热期间的无效值。图表不会生成新观测来填补缺口,但折线可能在视觉上连接缺口两侧的有效点。

大型时间序列图会在所有窗格中使用相同的分桶方式。每根聚合 K 线取桶内第一个有效开盘价、最高价的最大值、最低价的最小值,以及最后一个有效收盘价。柱状图对桶内数值求和,折线和面积图取最后一个有限值。每个桶显示在桶内最后一个时间戳处。这只是显示层面的聚合,不会改变源 DataFrame、研究计算或回测。OHLC 价格范围无效或发生溢出时会报错。

.max_points(n) 接受 2–2000,默认 1000,作为每个序列的目标点数。辅助工具会按需降低该目标,以将总输出控制在 4000 个点和 240 KiB 以内。说明文字报告源行数和分桶大小。检查单根 K 线时,应使用更窄的日期范围。

aqs_scatter(&btc, "volume", "ATRr_14")?;
aqs_histogram(&btc, "ATRr_14", 30)?;

aqs_scatter(frame, x_column, y_column) 将同一源行的值配对。它会移除包含缺失/非有限值的配对,并最多采样 2000 对用于显示。

aqs_histogram(frame, column, bins) 将所有有限观测值计入 2–100 个数值区间。常量列只生成一个区间。说明文字会报告因缺失或非有限值而排除的观测数量。这里绘制的是数值分布,与图表构建器按时间绘制数值的 .histogram("volume") 不同。

这两种图表使用数值轴和 SVG 工具提示,而不是时间图的缩放/平移控件。它们不需要时间戳列。

aqs_compare(&data, &["BTCUSD", "ETHUSD", "SOLUSD"], "close")?;
AQS 研究笔记本,展示 aqs_compare Rust 单元格,以及 BTCUSD、ETHUSD 和 SOLUSD 的归一化收盘价图,各品种在共同起始时间戳都以 100 为基准。AQS 研究笔记本,展示 aqs_compare Rust 单元格,以及 BTCUSD、ETHUSD 和 SOLUSD 的归一化收盘价图,各品种在共同起始时间戳都以 100 为基准。

以共同的 100 基准起点比较 BTCUSD、ETHUSD 和 SOLUSD 收盘价。折线表示相对价格变化,而非策略收益。查看全尺寸比较截图查看全尺寸比较截图。

选择 2–8 个不同的已加载品种。系统会找到所有品种在同一时间戳都有有限正值的第一个时点,将各条线在该时点的值设为 100。后续缺失的时间戳不会前向填充,每个序列保留自己的观测数据。如果找不到共同基准时点,辅助工具会报错。显示时,每个序列采样为约 400 个点,并保留首尾观测。

这是归一化后的价格比较,不是策略净值曲线、投资组合收益或相关性计算。它不会调整交易品种的成本、公司行动或计价货币。请根据研究需要,使用经过适当调整的输入数据。

aqs_emit(value: serde_json::Value) 输出一个结构化预览。图表应优先使用上述辅助工具。查看器也保留对旧版 table 和 line 的支持:

aqs_emit(serde_json::json!({
"kind": "table",
"columns": ["Metric", "Value"],
"rows": [["Observations", bars.height().to_string().as_str()]],
"totalRows": 1
}));
aqs_emit(serde_json::json!({
"kind": "line",
"label": "Example series",
"points": [
{"time": 1791241200, "value": 1.0},
{"time": 1791241260, "value": 1.2}
]
}));

自定义折线的时间戳使用 Unix 秒,而不是 DataFrame 使用的毫秒。表格列名和单元格值应为字符串。新的辅助工具按版本 1 的 chart、scatter、distribution 和 heatmap 格式输出。若只想检查构建器生成的数据而不显示图表,请使用 .build()?,而不是 .show()?。笔记本提供的 HTML 不会被渲染。

在 aqs_chart 上使用 .signals(&signals)?,叠加生成信号或入场成交。自定义信号数据帧需要 UTC 毫秒 timestamp、side(Buy 或 Sell)以及可选 label。

aqs_chart(&btc).candles().signals(&signals)?.show()?;
aqs_heatmap(&monthly, "month", "year", "return_pct")?;

热力图每个轴最多接受 50 个标签,总计最多 2,500 个单元格。缺失值保持空白,而不是零。重复坐标会产生错误:绘图前请显式聚合。颜色以零为中心。信号标记和热力图会同时保留在静态 AQI 研究文章快照和本地笔记本中。

有关读取已保存回测、比较净值与回撤、aqs_returns_heatmap、Alpha 回放和隔离节点图实验,请参阅策略复用与回测。

笔记本的 AQI paper 区域会打开完整文章编辑器,并插入包含代码及符合条件的已保存输出样本的笔记本块。你也可以使用文章编辑器中的 Add notebook,只选择部分单元格,或不包含输出。插入操作只修改本地内容;请审核后再主动保存或发表。文章中的时间序列图与研究笔记本使用相同的 TradingView Lightweight Charts 渲染器,支持叠加线、同步窗格、信号标记和 UTC 十字光标读数。读者可以缩放和平移已保存的样本,但图表不会加载实时数据。热力图、散点图和分布图使用研究功能的 SVG 渲染器;无 JavaScript 时仍可显示静态备用图。过时、失败或未经验证的结果会被排除。快照不会嵌入原始数据集,也不会在读者的机器上执行代码。有关审核和发布流程,请参阅分享研究。

文本输出和单个富内容预览的大小上限为 256 KiB。较大的输出应先缩减,或写入项目内的本地文件。查看器每次求值最多显示 20 个富内容预览。

编译和运行时诊断显示在对应单元格下方;stderr 也会停止 Run all 以供检查。输出保留在已保存笔记本中,并在编辑或重置后标记为过时。这些预览与实时 AQS 图表工作区相互独立。