金融市场的"语言"
K 线不是图表,它是市场在说话——理解为什么 Kronos 把价格当文字读
为什么金融需要"基础模型"?
在 NLP 领域,GPT、Claude 等基础模型已经证明了一个关键理念:一个通用模型,经过海量数据预训练后,可以用少量数据快速适应各种下游任务。Kronos 把这个理念带到了金融时间序列领域。
NLP: 互联网文本 → 预训练 → 翻译/摘要/对话
金融: 全球K线数据 → 预训练 → 预测/分类/异常检测
共同点:
- 输入都是序列(文字序列 vs K线序列)
- 核心都是"预测下一个"(下一个词 vs 下一根K线)
- 预训练后都能用少量数据微调到新任务
NLP 的"基础模型"概念同样适用于金融数据
文字序列和 K 线序列在数学上是同构的
输入 → 序列,任务 → 预测序列的下一部分
预训练学到通用规律,微调适应特定场景
将金融市场数据重新定义为一种「语言」,是 Kronos 最根本的洞察。一旦你接受了「K 线序列 = 语言序列」这个类比,所有 LLM 的技术(Tokenization、Transformer、自回归预测、温度采样)都可以直接搬过来用。这不是简单的技术迁移,而是一个全新的问题框架。
每根 K 线都是一个单词
你打开交易软件,看到的那根根红绿柱子,叫做K 线。每根 K 线包含四个维度的信息:开(Open)、高(High)、低(Low)、收(Close),有时还包括成交量(Volume)。
Kronos 的核心洞察是:K 线序列就像句子,每根 K 线就像一个单词。既然 GPT 能通过"预测下一个词"学会人类语言,那为什么不能通过"预测下一根 K 线"来学会市场规律?
传统量化方法:人工设计因子(如 RSI、MACD),然后对这些因子建模。Kronos 方法:让模型自己从海量 K 线历史中"读懂"市场规律,就像 LLM 读书学语言一样。
训练数据:45 个全球交易所,覆盖全球市场
Kronos 的预训练数据集横跨 45 个全球交易所,包含数十年的 K 线历史。就像 LLM 需要读遍互联网上的文字才能理解语言,Kronos 需要读遍全球市场的历史才能理解价格走势。
美股市场
NYSE、NASDAQ 等主要交易所的历史数据
A 股市场
沪深两市的 A 股历史数据,含微调示例
加密货币
BTC/ETH 等主流加密资产,提供实时 Demo
其他市场
欧洲、亚洲、商品期货等多元市场
传统时间序列模型 vs Kronos:根本区别
| 能力 | ARIMA/LSTM | Kronos |
|----------------|-------------|--------------|
多市场迁移 ❌ ✅ 预训练+微调
多任务学习 ❌ ✅ 预测/分类/异常
少量数据适应 ❌ ✅ few-shot
长程依赖 有限 ✅ 512+ K线
概率分布输出 部分 ✅ 多次采样
特征工程 大量手动 ❌ 自动学习
传统模型只能在一个市场上工作,换市场要重新训练
Kronos 预训练一次,微调即可适应新市场
一个 Kronos 模型可以同时做预测和异常检测
Transformer 的注意力机制可以捕捉 512 根以上的长程依赖
Kronos 通过采样可以输出价格的概率分布,而非单一点估计
传统时间序列模型 vs Kronos:根本区别
针对单一任务设计;需要大量特征工程;不同市场需要不同模型;无法迁移学到的知识
一个模型,多种任务(预测、分类、异常检测);跨市场迁移学习;可以用少量数据微调适应新市场
Kronos 于 2025 年 8 月发表在 arXiv,并于 2025 年 11 月被 AAAI 2026 接受。这是首个专注于金融 K 线序列的开源基础模型。
金融基础模型的实际应用场景
Kronos 不只是一个研究项目——它的设计目标是从第一天起就能解决真实的金融问题。以下是几个核心应用方向:
价格趋势预测
输入历史 K 线,输出未来 N 根 K 线的预测。不是给出一个确定值,而是通过采样生成多条可能的走势路径,帮助交易员评估风险和机会。
异常模式检测
当模型预测的下一根 K 线与实际发生的价格偏差极大时,说明市场出现了「异常」——可能是闪崩、操纵或重大新闻事件。这种异常检测比固定阈值更灵活。
跨市场迁移
在美股上预训练的模型,用少量 A 股数据微调后就能适应中国市场的规律。这种迁移能力是传统单市场模型无法实现的。
Kronos 是学术研究工具,不是交易信号生成器。金融市场极其复杂,历史表现不代表未来收益。任何基于 Kronos 的交易决策都需要结合风险管理、仓位控制和基本面分析,不能仅依赖模型预测。
知识检验:金融语言模型基础
你想用 Kronos 来预测印度股市(Nifty 50),但 Kronos 的预训练数据主要是美股。你应该怎么做?
Kronos 架构与预训练
两阶段设计:先把价格"翻译"成 Token,再让 Transformer 学习
两阶段:先翻译,后学习
Kronos 采用两阶段框架,就像一个翻译官学习外语:第一步,学习把外语(K 线数值)翻译成符号(离散 Token);第二步,用这套符号语言来理解和预测。
为什么金融时间序列需要专门的 Tokenizer?
NLP 的 Tokenizer 把文字切成词,很好理解。但金融数据的 Tokenizer 要解决一个更难的问题——连续数值的离散化。
NLP 的离散性
文字天然是离散的——"涨"和"跌"是两个不同的词,中间没有过渡。Tokenizer 只需要决定在哪里切分。
金融的连续性
价格是连续的——100.00 和 100.01 之间有无数个值。Tokenizer 必须决定如何把这些连续值"桶化"成离散类别,同时不丢失关键信息。
BSQ 的巧妙解决方案
二进制球形量化在超球面上做离散化——保持角度信息(方向)的同时用二进制编码表示距离。这样既保留了市场的"方向感",又让模型可以像处理文字 Token 一样处理价格数据。
传统量化方法用 RSI、MACD 等人工特征来表示市场状态。Kronos 的 Tokenizer 让模型自己学习如何表示市场状态——不需要人类专家预先定义哪些特征重要。模型从数据中自动发现有效的表示方式。
KronosTokenizer:把价格变成"词"
KronosTokenizer 的工作是:将连续的 OHLCV 数值(比如 0.123, 0.456...)转换成离散的整数 Token(比如 42, 137...)。这个过程叫做向量量化。
class KronosTokenizer(nn.Module):
def __init__(self, d_in, d_model,
s1_bits, s2_bits, ...):
self.embed = nn.Linear(d_in, d_model)
self.encoder = nn.ModuleList([...])
self.tokenizer = BSQuantizer(
s1_bits, s2_bits, ...)
self.decoder = nn.ModuleList([...])
KronosTokenizer 是一个神经网络模块
d_in:输入维度(OHLCV = 6 个数)
d_model:内部工作维度(如 512)
s1_bits + s2_bits:分层量化的精度设置
embed:把 6 个数映射到 512 维的"理解空间"
encoder:Transformer 编码器,提取模式
BSQuantizer:核心量化器,产生离散 Token
decoder:从 Token 重建原始数值(训练时用)
分层 Token:s1 + s2 的聪明设计
Kronos 采用了一个独特的分层量化策略,叫做 BSQ(Binary Spherical Quantization):
s1 Token(粗粒度)
捕捉 K 线的"大方向":涨还是跌?幅度大还是小?就像音乐的主旋律。
s2 Token(细粒度)
在 s1 确定方向后,捕捉具体细节:影线长短、开收关系。就像音乐的和声细节。
为什么这样设计?因为预测"大方向"比预测"精确数值"容易得多,且更可靠。先让模型确定方向,再精化细节——与人类交易员的思考方式一致。
直接预测浮点数非常困难——微小的误差在实际交易中影响巨大。将连续值转换成离散 Token,让问题从"回归"(预测精确数值)变成"分类"(预测哪个 Token),更适合 Transformer 架构。
Transformer 主干:Kronos 怎么"预测下一根 K 线"
Kronos 的核心是一个自回归 Transformer,和 GPT 系列使用相同的基本原理。它的前向传播逻辑展示了分层预测的实现:
def forward(self, s1_ids, s2_ids,
stamp=None, ...):
x = self.embedding([s1_ids, s2_ids])
if stamp is not None:
x = x + self.time_emb(stamp)
for layer in self.transformer:
x = layer(x)
s1_logits = self.head(x)
x2 = self.dep_layer(x, sibling)
s2_logits = self.head.cond_forward(x2)
return s1_logits, s2_logits
接收历史 K 线的 s1 和 s2 Token 序列作为输入
把 Token 转换为高维向量(Embedding)
如果有时间戳,加入时间位置信息(了解是周一还是收盘前)
通过多层 Transformer 提取时序模式
先预测 s1(大方向),得到粗粒度预测分数
dep_layer:依赖感知层,让 s2 的预测依赖于 s1
再预测 s2(细节),得到细粒度预测分数
返回两级预测结果
BSQ 的核心思想是把连续空间中的数据点映射到超球面上的离散位置。想象一下:所有可能的 K 线形态分布在一个高维空间中,BSQ 在这个空间里画了一条「经纬网」——s1 是「纬度」(大方向),s2 是「经度」(细节)。每根 K 线都被这个网格捕获到一个确定的位置,误差由网格密度决定。网格越密,精度越高,但计算成本也越大。
Kronos 的训练损失是 s1 损失和 s2 损失的加权和。s1 的权重更大,因为「方向对」比「细节准」更重要。这与交易直觉一致——判断对趋势方向是第一位的,精确入场点是第二位的。
金融市场有强烈的周期性——日内波动、周末效应、月末资金面。Kronos 通过时间嵌入(time_emb)让 Transformer 知道当前处于什么时间周期,帮助模型区分「周五收盘前的波动」和「周一开盘的波动」。
Kronos 为什么使用分层 Token(s1 + s2)而不是单层量化?
K 线数据到 Token 流水线
数据如何从 CSV 变成模型能理解的格式
就像食品加工厂:原料进去,产品出来
你有一份 CSV 文件,里面是 BTC/USDT 的 5 分钟 K 线历史数据。Kronos 的 KronosPredictor 负责整个"加工"流程:从原始 OHLCV 数据到最终的预测价格。
用 pandas 读取 CSV,确保包含 open/high/low/close 列,时间戳解析为 datetime
归一化将绝对价格转为相对变动,消除不同资产价格量纲差异
KronosTokenizer 将 OHLCV 数值序列转换为 s1+s2 离散 Token 序列
Kronos 模型接收 Token 序列,自回归生成未来 K 线的预测 Token
将预测 Token 转换回 OHLCV 数值,然后恢复实际价格尺度
KronosPredictor:一站式预测接口
所有上述步骤都被封装在 KronosPredictor 类中,让使用者只需要三个输入就能得到预测结果:
predictor = KronosPredictor(
model, tokenizer, max_context=512)
pred_df = predictor.predict(
df=x_df,
x_timestamp=x_timestamp,
y_timestamp=y_timestamp,
pred_len=120,
T=1.0,
top_p=0.9,
)
创建预测器,传入模型、分词器和最大上下文长度
max_context=512:最多看过去 512 根 K 线来预测
调用 predict() 方法,传入三类参数:
df:历史 K 线 DataFrame(过去的数据)
x_timestamp:历史数据的时间戳序列
y_timestamp:要预测的未来时间点
pred_len=120:预测未来 120 根 K 线
T=1.0, top_p=0.9:控制预测随机性(类似 LLM 的 temperature)
组件之间的对话:预测请求的流转
温度参数 T 和 top_p:控制预测的"想象力"
Kronos 的采样参数和 LLM 的 temperature/top_p 概念一致,但在金融场景下的含义略有不同:
温度 T
T 越高,预测越「大胆」——生成的价格路径波动更大,覆盖更多极端场景。T 越低,预测越「保守」——更贴近历史平均走势。金融场景建议 T=0.5~1.5,用于生成概率分布。
top_p(核采样)
只从概率累计前 top_p 的 Token 中采样。top_p=0.9 意味着忽略那些概率最低的 10% Token——过滤掉模型认为「不太可能」的极端预测,提高预测的合理性。
不要只跑一次 predict()——用不同的随机种子跑 50~100 次,然后用统计方法(均值、分位数、VaR)从这些采样路径中提取概率分布。这就是金融中的蒙特卡洛方法,而 Kronos 让这个过程变得极其简单:一个循环 + 几行代码就能生成完整的价格概率分布。
批量预测:同时预测多个资产
Kronos 提供了 predict_batch() 方法,可以并行处理多个时间序列,充分利用 GPU 并行能力:
df_list
多个资产的历史数据列表(如 [BTC_df, ETH_df, SOL_df])
x_timestamp_list
对应的历史时间戳列表,所有序列历史长度必须相同
y_timestamp_list
要预测的未来时间点,所有序列预测长度必须相同
verbose=True
显示进度条,方便监控批量预测的进度
在使用 KronosPredictor 时,数据预处理是最容易出错的环节。常见问题:(1) 时间戳格式不对——Kronos 需要标准 datetime 格式,如果传入字符串会报错;(2) OHLC 顺序不对——必须是 open, high, low, close 的顺序;(3) 数据有缺失值——NaN 会导致量化器崩溃,需要提前填充或删除;(4) 归一化泄漏——用未来数据做归一化会导致回测结果虚高,必须只用历史窗口内的数据。
import pandas as pd
# 1. 加载数据
df = pd.read_csv("btc_5min.csv")
# 2. 检查缺失值
assert df.isnull().sum().sum() == 0
# 3. 确保列顺序正确
df = df[["open","high","low","close"]]
# 4. 解析时间戳
timestamps = pd.to_datetime(df["timestamp"])
用 pandas 读取 CSV 格式的 K 线数据
检查并处理任何缺失值——NaN 会导致模型崩溃
确保列顺序是 OHLC,不要打乱
时间戳必须转为 datetime 对象