DuckDB 与 Polars¶
同一份 Parquet 湖可以按三种方式消费:load() 负责带语义的研究查询,DuckDB 负责跨数据集 SQL,Polars scan() 负责 LazyFrame 管道。选择入口,不要复制一份“调整后数据湖”。
准备¶
以下使用正式配置 configs/cnequity.toml,要求 daily_bars 和 adj_factors 已发布。用小湖体验时先运行 demo --research,并在各查询中明确传入 demo 配置或 data_root。
DuckDB:跨数据集聚合¶
cne query --config configs/cnequity.toml --sql "
SELECT symbol, max(trade_date) AS last_date, avg(adj_close) AS avg_hfq_close
FROM daily_bars_adj
WHERE trade_date >= DATE '2024-01-01'
AND adj_is_exact
GROUP BY symbol
ORDER BY avg_hfq_close DESC
LIMIT 20
"
daily_bars_adj 是只读视图,带 adj_* 与 adj_is_exact。cne query 只接受单条 SELECT,适合把 SQL 交给脚本或 MCP agent。
Polars:LazyFrame 特征管道¶
import polars as pl
from cnequity.query import load
bars = (
load(
"daily_bars",
start="2024-01-01",
end="2024-12-31",
symbols=["600519.SH", "000001.SZ"],
adjust="hfq",
strict_adj=True,
)
.lazy()
.sort(["symbol", "trade_date"])
.with_columns(
pl.col("adj_close").pct_change().over("symbol").alias("daily_return")
)
)
features = bars.select(
["symbol", "trade_date", "adj_close", "daily_return"]
).collect()
load() 先完成严格复权并物化结果,.lazy() 只延迟后面的特征计算。用日期和标的限制输入规模;它不是全程惰性读取。
如果只需原始行情,可直接惰性扫描:
from cnequity.query import scan
raw = scan("daily_bars", start="2024-01-01", end="2024-12-31",
symbols=["600519.SH", "000001.SZ"])
print(raw.select("symbol", "trade_date", "close").limit(10).collect())
scan() 不接受 adjust、strict_adj、universe 或 as_of,也不替你做相应研究校验。
连接到 AI agent¶
cne mcp --config /abs/path/to/cnequity.toml
MCP 服务只读,返回值会声明 origin、截断状态、复权与 PIT 口径。采集和维护由 cne CLI 执行;本机 cne serve 的操作页可以预览并启动同一白名单里的命令。其它 MCP 客户端可复用同一条 command / args 配置,完整工具契约见 MCP 参考。