基于Vision Transformer的K线图AI分析:从图像识别到量化交易新范式
1. 项目概述:当AI开始“咀嚼”K线图
最近在GitHub上冲浪,一个名为“Kronos”的项目彻底抓住了我的眼球。它以一种近乎“暴力美学”的方式,宣称自己是一个“专门吃K线图长大的AI”,并且凭借这个极具冲击力的概念,迅速斩获了超过25k的Star,登顶趋势榜。作为一个在量化交易和金融科技领域摸爬滚打了多年的从业者,我的第一反应是好奇,紧接着是震撼,最后是一种“恍然大明白”的顿悟感——它让我意识到,过去三年里,我可能一直在用一种近乎“裸奔”的方式看待市场数据。
这个项目究竟在做什么?简单来说,它试图用最前沿的深度学习模型,特别是视觉相关的架构(如Vision Transformer, ViT),去直接“理解”K线图这种特殊的时序图像。我们传统做量化,无论是技术指标、统计套利还是因子挖掘,本质上都是在将K线图所蕴含的原始信息(开盘、收盘、最高、最低、成交量)进行人工的、线性的、离散的加工和抽象。我们提取出MACD、RSI、布林带,然后把这些加工后的“特征”喂给模型。而Kronos的思路是反其道而行之:它把一整张K线图(比如过去100根、500根K线)直接当作一张“图片”输入给一个强大的图像识别AI,让AI自己去学习图中那些复杂的、非线性的、人类难以言表的模式——比如特定的形态组合、量价关系的微妙背离、支撑压力区域的集体行为等。
这就像以前我们研究一幅画,总是先去测量它的色彩分布、笔触长度、构图比例,然后用这些测量值去判断画作的艺术价值。而Kronos的做法是,直接把整幅画塞给一个受过无数名画训练的AI鉴赏家,让它凭“直觉”和“经验”给出判断。这种端到端(End-to-End)的“看图说话”能力,如果真能有效,无疑将是对传统量化方法论的一次降维打击。它跳过了我们人为设计特征时不可避免的信息损失和主观偏见,尝试从最原始的市场“视觉记忆”中挖掘阿尔法。当我深入研究了它的代码、论文(如果有的话)和社区讨论后,那种“之前都在裸奔”的感觉愈发强烈——我们可能过于沉迷于自己制造的“指标”铠甲,却忽略了市场本身最赤裸、最丰富的表达形式。
2. 核心思路拆解:为什么是“吃图”,而不是“算数”?
要理解Kronos的价值,我们必须先跳出传统量化交易的思维定式。在经典的金融工程框架里,价格序列被视为时间序列数据,我们应用统计学、信号处理和机器学习方法来寻找预测模式。但Kronos背后的核心哲学是:金融市场,尤其是由无数交易者集体行为形成的价格轨迹,其信息密度和结构复杂性,可能更接近于一种“视觉语言”或“模式图像”,而非纯粹的数字序列。
2.1 传统方法的“信息漏斗”困境
我们常用的方法存在一个固有的“信息漏斗”:
- 原始数据:OHLCV(开、高、低、收、量)数据,这是最丰富的一层,包含了每一时刻多空博弈的全部细节。
- 特征工程:人工设计指标,如移动平均线、波动率、动量等。这一步会丢失大量信息,比如K线实体与影线的具体比例、连续K线的排列组合形态(如早晨之星、乌云盖顶)、在关键价位的密集成交情况(通过量能分布间接体现)等微观结构。
- 模型输入:将筛选后的指标送入逻辑回归、随机森林、XGBoost甚至LSTM等模型。
问题在于,特征工程这一步既是艺术也是瓶颈。它高度依赖研究员的经验、领域知识,甚至是个人的市场直觉。我们可能因为不认识某种形态,或者认为某个细微的量价关系不重要,而主动丢弃了关键信号。更危险的是,我们精心设计的指标可能只是对历史数据的过度拟合,在新的市场环境中迅速失效。
2.2 Kronos的“全息摄入”策略
Kronos的思路是:尽可能绕过这个人工的“信息漏斗”,尝试让模型直接面对最原始、信息保留最完整的“数据形态”——K线图图像。它的优势在于:
- 信息无损(或低损):一张K线图完整保留了时间序列中所有的空间关系。两根K线之间的缺口、长上影线所代表的上冲回落压力、一组小实体K线形成的盘整区间,这些信息在图像中一目了然,但转化为数字序列后则难以被传统模型有效捕捉。
- 模式识别优势:人类的交易员很大程度上是“看图说话”的。深度学习在图像识别领域的巨大成功(如ResNet, ViT)证明,神经网络非常擅长从像素中提取层次化的特征,从边缘到纹理,再到复杂的物体和场景。将这套技术用于K线图,相当于雇佣了一个不知疲倦、能同时观察成千上万张图表并寻找统计规律的“超级图案识别员”。
- 端到端学习:从原始图像到预测信号(如涨跌、波动率、买卖点),整个过程由一个统一的模型完成。这允许模型自行发现哪些视觉模式对未来价格运动有预测性,这些模式可能远超人类已有的技术分析知识体系。
一个生动的类比:传统量化像是用听诊器、血压计、化验单等离散指标来诊断病人(市场)。而Kronos这类方法,是直接给病人拍一张全身的CT或MRI(K线图),然后让一个看过数百万病例的AI医生直接基于这张“全息影像”做出诊断。后者理论上能发现更多器官间关联的、细微的、甚至医生尚未总结出的病理特征。
当然,这个思路并非Kronos独创,学术界早有将CNN用于金融时间序列分类的研究。但Kronos项目之所以能引起轰动,在于它可能提供了一个工程上非常完整、可直接上手实验的框架,并且结合了最新的视觉Transformer架构,在社区生态、易用性上做得更好,让更多个人研究者和爱好者能够低成本地验证这一理念。
3. 技术架构深度剖析:如何教会AI“看”K线?
Kronos项目的核心,必然围绕着一套能将金融时间序列有效转化为模型可“理解”的图像,并利用强大视觉模型进行训练的 pipeline。下面我们来拆解其可能的技术栈和关键实现细节。
3.1 数据预处理:从数字到图像的“编码艺术”
这是第一步,也是至关重要的一步。如何将OHLCV数据变成一张有意义的“图片”?
K线图渲染:
- 基础渲染:使用
matplotlib、Plotly或专门的金融图表库(如mplfinance)生成标准的K线图。需要确定关键参数:- 时间窗口:一张图包含多少根K线?50根?200根?这决定了模型看到的“历史上下文”长度。
- 图表样式:是标准的红涨绿跌(或绿涨红跌)蜡烛图,还是美国线(OHLC Bar)?是否包含成交量副图?通常,包含成交量的上下布局图像信息更丰富。
- 图像规格:输出的图片尺寸(如224x224, ViT的常见输入尺寸)、DPI(分辨率)。图像不能太大(增加计算成本),也不能太小(丢失细节)。
- 高级编码:除了标准K线,可能会尝试加入更多视觉元素进行“特征增强”,例如:
- 叠加关键移动平均线(MA5, MA20, MA60),用不同颜色和线型表示。
- 在价格轴上标记出前期的重要高点和低点,作为支撑阻力位的视觉提示。
- 用背景色块标识不同的交易时段(如亚洲盘、欧洲盘、美洲盘)或宏观经济事件窗口。
- 标准化:为了消除绝对价格的影响,通常会对价格轴进行标准化处理。例如,将一张图内的价格序列归一化到[0, 1]区间,或者基于滚动窗口计算Z-Score。但需注意,标准化不能破坏K线之间的相对位置关系和形态。
- 基础渲染:使用
标签生成(监督学习的关键):
- 对于分类任务(如预测未来N根K线是涨是跌),需要为每一张生成的K线图“快照”打上标签。例如,用当前K线之后第5根的收盘价与当前收盘价比较,上涨超过阈值X%则为“1”(看涨),下跌超过Y%则为“0”(看跌),波动在中间则为“-1”(震荡或无信号)。阈值的选择需要根据市场波动率和交易成本仔细回测确定。
- 对于回归任务(如预测未来收益率或波动率),则直接使用未来的具体数值作为标签。
3.2 模型选型:为何Vision Transformer可能是关键
早期的研究多使用卷积神经网络(CNN),如ResNet、DenseNet。CNN通过卷积核在图像上滑动,能有效提取局部特征(如单根K线的形态、相邻K线的组合)。但Kronos项目能获得如此高的关注,很可能是因为它采用了或集成了更前沿的Vision Transformer (ViT)架构。
为什么ViT可能更适合K线图?
- 全局注意力机制:CNN的感受野是局部的,需要多层堆叠才能捕获全局信息。而Transformer的核心——自注意力机制(Self-Attention),允许模型在第一步就计算图像中任意两个“图像块”(patch)之间的关系。对于K线图而言,这意味着模型可以同时关注“图表开头的一个跳空缺口”和“图表末尾的一个长上影线”,并直接建模它们之间的远距离依赖关系。这种全局视角对于理解图表级别的形态(如头肩顶、三角形整理)至关重要。
- 对序列数据的天然亲和性:ViT将图像切分为一系列有序的patch,然后将其作为序列输入Transformer。这实际上是将二维图像转化为了一维序列进行处理。K线图本质上是时间序列的视觉化,其横轴就是时间。ViT的这种处理方式与时间序列的内在逻辑有相通之处,可能比CNN更能理解时间上的先后和因果关系。
- 强大的表征能力:在大规模数据集上预训练的ViT模型(如在ImageNet-21k上),已经学会了提取通用、强大的视觉特征。通过迁移学习,我们可以用金融K线图数据对这些预训练模型进行微调(Fine-tuning),从而有望用相对较少的数据量获得不错的性能,这对于数据有限的金融领域尤其有价值。
一个可能的Kronos模型Pipeline如下:
OHLCV时间序列 -> 滑动窗口切片 -> 渲染为K线图图像 -> 图像预处理(裁剪、归一化)-> 切分为Patch -> Patch线性嵌入 -> 加入位置编码 -> Transformer Encoder堆叠 -> MLP Head -> 输出(分类概率/回归值)3.3 训练策略与损失函数
- 数据划分:严禁使用未来数据!必须严格按照时间顺序划分训练集、验证集和测试集。通常采用“滚动窗口”或“扩展窗口”的方式进行回测,模拟实盘中的模型更新过程。
- 损失函数:
- 分类任务:常用交叉熵损失(Cross-Entropy Loss)。对于不平衡的数据集(大涨大跌的样本少),可能需要使用Focal Loss或对类别进行加权。
- 回归任务:常用均方误差(MSE)或平均绝对误差(MAE)。在金融预测中,有时更关注预测方向而非绝对数值,可以结合相关性损失。
- 过拟合应对:金融数据噪声极大,过拟合是头号敌人。必须采用强力的正则化组合:
- 数据增强:对K线图图像进行小幅度的、符合金融逻辑的增强。例如,在合理范围内随机缩放价格轴(模拟不同波动率)、轻微平移时间轴、添加微小的噪声像素(模拟报价毛刺)。但切记,不能使用翻转(K线图左右翻转会破坏时间顺序)、旋转等不符合金融常识的增强。
- 模型正则化:大量使用Dropout、Stochastic Depth、Weight Decay。
- 早停:在验证集性能不再提升时果断停止训练。
4. 从零搭建你的“K线图AI”实验环境
理解了原理,我们动手搭建一个最小可行性的实验环境。这里以Python为核心,展示关键步骤。
4.1 环境准备与依赖安装
首先创建一个干净的Python环境(推荐使用conda或venv),然后安装核心库。
# 创建并激活环境 conda create -n kronos_exp python=3.9 conda activate kronos_exp # 安装基础数据与计算库 pip install numpy pandas matplotlib scikit-learn # 安装深度学习框架(以PyTorch为例,请根据CUDA版本去官网获取对应命令) # 例如,对于CUDA 11.8 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 安装金融数据获取与图表渲染库 pip install yfinance mplfinance plotly pip install ta # 技术指标库,用于对比实验 # 安装Transformer模型库(以timm为例,它提供了丰富的预训练ViT模型) pip install timm # 安装实验管理工具(可选但推荐) pip install wandb # Weights & Biases,用于跟踪实验4.2 数据获取与K线图渲染
我们使用yfinance获取历史数据,并用mplfinance渲染成图像。
import yfinance as yf import mplfinance as mpf import pandas as pd import numpy as np from pathlib import Path import matplotlib.pyplot as plt def download_data(symbol='AAPL', start='2020-01-01', end='2023-12-31', interval='1d'): """ 下载股票或指数数据 """ ticker = yf.Ticker(symbol) df = ticker.history(start=start, end=end, interval=interval) # 确保索引是DatetimeIndex df.index = pd.to_datetime(df.index) # 重命名列以符合mplfinance要求 df = df.rename(columns={'Open':'open', 'High':'high', 'Low':'low', 'Close':'close', 'Volume':'volume'}) return df def create_candlestick_images(df, window_size=50, stride=5, save_dir='./chart_images'): """ 滑动窗口生成K线图并保存为图片 df: 包含OHLCV的DataFrame window_size: 每张图包含的K线数量 stride: 滑动步长 save_dir: 图片保存目录 """ Path(save_dir).mkdir(parents=True, exist_ok=True) image_paths = [] labels = [] # 这里需要根据你的标签定义来生成 num_samples = len(df) for i in range(0, num_samples - window_size - 1, stride): # 留出一根K线用于计算未来收益 window_df = df.iloc[i:i+window_size] # 定义未来收益作为标签示例(分类) current_close = window_df.iloc[-1]['close'] future_close = df.iloc[i+window_size]['close'] price_change_pct = (future_close - current_close) / current_close # 简单二分类:涨超0.5%为1,跌超0.5%为0,其余丢弃 if price_change_pct > 0.005: label = 1 elif price_change_pct < -0.005: label = 0 else: continue # 跳过震荡样本,或归为第三类 # 生成图表 fig, ax = mpf.plot(window_df, type='candle', volume=True, returnfig=True, style='charles', figsize=(2.24, 2.24)) # 224x224像素对应2.24英寸 # 移除坐标轴,让模型专注于图形本身 ax[0].set_axis_off() ax[2].set_axis_off() # 保存图像 img_path = f"{save_dir}/sample_{i:06d}_label_{label}.png" fig.savefig(img_path, bbox_inches='tight', pad_inches=0, dpi=100) # dpi=100, 2.24*100≈224 plt.close(fig) image_paths.append(img_path) labels.append(label) # 保存路径和标签的对应关系 pd.DataFrame({'image_path': image_paths, 'label': labels}).to_csv(f'{save_dir}/labels.csv', index=False) print(f"Generated {len(image_paths)} images.") return image_paths, labels # 使用示例 df = download_data('AAPL', start='2020-01-01', end='2022-12-31') image_paths, labels = create_candlestick_images(df, window_size=60, stride=3, save_dir='./aapl_charts')关键提示:这里为了简化,标签生成非常粗糙。在实际研究中,你需要仔细定义预测目标(方向、幅度、时间 horizon),并考虑交易成本、滑点等因素。图像保存时关闭坐标轴是为了让模型不依赖于具体的价格刻度,专注于相对形态。
4.3 构建PyTorch数据集与模型
接下来,我们构建一个PyTorch的Dataset来加载图像和标签,并定义一个基于预训练ViT的简单分类模型。
import torch from torch.utils.data import Dataset, DataLoader from torchvision import transforms from PIL import Image import timm import torch.nn as nn class CandlestickDataset(Dataset): def __init__(self, csv_file, transform=None): self.data_frame = pd.read_csv(csv_file) self.transform = transform def __len__(self): return len(self.data_frame) def __getitem__(self, idx): img_path = self.data_frame.iloc[idx, 0] label = self.data_frame.iloc[idx, 1] image = Image.open(img_path).convert('RGB') # 确保三通道 if self.transform: image = self.transform(image) return image, torch.tensor(label, dtype=torch.long) # 定义图像预处理变换(需匹配预训练模型的要求) # 以 timm 中的 vit_base_patch16_224 为例 from timm.data.constants import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD train_transform = transforms.Compose([ transforms.RandomHorizontalFlip(p=0.0), # 注意:K线图绝对不能水平翻转! transforms.ColorJitter(brightness=0.05, contrast=0.05, saturation=0.05, hue=0.01), # 轻微颜色抖动 transforms.RandomAffine(degrees=0, translate=(0.02, 0.02)), # 轻微平移 transforms.ToTensor(), transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD), ]) val_transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize(IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD), ]) # 创建数据集和数据加载器 train_dataset = CandlestickDataset('./aapl_charts/labels.csv', transform=train_transform) train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=4) # 定义模型 class KronosViT(nn.Module): def __init__(self, num_classes=2, pretrained=True): super().__init__() # 加载预训练的 Vision Transformer self.vit = timm.create_model('vit_base_patch16_224', pretrained=pretrained, num_classes=0) # num_classes=0 获取特征 self.feature_dim = self.vit.num_features # 替换分类头,适应我们的任务 self.classifier = nn.Sequential( nn.LayerNorm(self.feature_dim), nn.Linear(self.feature_dim, 512), nn.GELU(), nn.Dropout(0.5), nn.Linear(512, num_classes) ) def forward(self, x): features = self.vit(x) # 提取视觉特征 output = self.classifier(features) return output model = KronosViT(num_classes=2) device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') model.to(device)4.4 模型训练与评估循环
import torch.optim as optim from torch.optim.lr_scheduler import CosineAnnealingLR criterion = nn.CrossEntropyLoss() optimizer = optim.AdamW(model.parameters(), lr=1e-4, weight_decay=0.05) scheduler = CosineAnnealingLR(optimizer, T_max=10) # 简单调度 num_epochs = 20 for epoch in range(num_epochs): model.train() running_loss = 0.0 for images, labels in train_loader: images, labels = images.to(device), labels.to(device) optimizer.zero_grad() outputs = model(images) loss = criterion(outputs, labels) loss.backward() torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) # 梯度裁剪,防止爆炸 optimizer.step() running_loss += loss.item() * images.size(0) epoch_loss = running_loss / len(train_dataset) scheduler.step() print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {epoch_loss:.4f}') # 这里应添加验证集评估逻辑 # model.eval() # ... 计算准确率、精确率、召回率等核心要点:以上代码是一个高度简化的教学示例。真实项目需要严谨的数据划分(时间序列交叉验证)、更复杂的标签定义、更全面的评估指标(如夏普比率、最大回撤、胜率等,需在回测框架中计算),以及大量的超参数调优。
5. 实战中的挑战、陷阱与应对策略
将AI用于K线图预测听起来很美好,但一路坑洼。以下是我在类似项目实践中总结出的核心挑战和避坑指南。
5.1 数据层面的“魔鬼”
非平稳性与结构性变化:市场风格会切换(牛市、熊市、震荡市),宏观经济环境、交易规则也会变。一个在2008年金融危机数据上训练出的模型,在2020年流动性宽松的市场中可能完全失效。
- 应对:使用滚动时间窗口进行训练和验证。永远用最近过去的数据训练,并在一段未来的、未参与训练的数据上测试。定期(如每季度)重新训练或微调模型。
标签噪声极大:金融市场的未来走势充满随机性,尤其是短期。我们定义的“涨”“跌”标签本身就有很大的噪声。一个看涨形态后,价格可能因一个突发新闻而暴跌。
- 应对:
- 平滑标签:不要用下一根K线的涨跌,而是用未来一段时间(如5根、10根K线)的平均收益率或趋势作为标签,可以过滤部分噪声。
- 模糊分类:引入“中性”或“不确定”类别,只对信号强烈的样本进行高置信度标注。
- 关注风险调整后收益:模型目标不应只是预测准确率,更应是预测能带来正期望收益的交易信号。在损失函数中引入与最终收益相关的项(需通过强化学习或定制损失函数实现,难度较高)。
- 应对:
幸存者偏差与前视偏差:
- 幸存者偏差:如果你只用当前仍活跃的股票数据训练,模型学到的可能是“成功公司”的图表模式,忽略了那些已退市公司的失败模式。
- 前视偏差:在数据预处理中,严禁使用未来信息。例如,在标准化时,不能用整个时间序列的全局最大值最小值,只能用滚动窗口的历史数据来计算。
- 应对:使用完整的历史数据(包括已退市股票),并在数据处理的每一步都进行严格的时间点检查。
5.2 模型与训练的“深水区”
过拟合是常态,而非例外:金融数据信噪比极低,模型非常容易记住数据中的随机噪声而非普遍规律。在训练集上准确率高达90%,在测试集上接近50%(随机猜测)的情况屡见不鲜。
- 应对:采用极其严格的正则化组合,如上文所述。更重要的是,依赖样本外测试和前瞻性模拟交易作为最终评判标准,而不是验证集准确率。
计算成本与迭代速度:渲染高分辨率图像、训练大型ViT模型需要巨大的计算资源(GPU)。这可能会拖慢你的研究迭代周期。
- 应对:
- 从小图像尺寸(如112x112)开始实验。
- 使用更轻量级的模型(如
vit_tiny_patch16_224)。 - 考虑使用更高效的图像表示,如将OHLCV直接编码为多通道的“特征图”(例如,5个通道分别代表O, H, L, C, V的归一化值),而不是渲染成RGB图像,这样可以省去渲染步骤,直接输入CNN。
- 应对:
可解释性黑箱:ViT等复杂模型是典型的黑箱。即使它做出了成功的预测,你也很难理解它到底是基于“锤子线”还是“成交量异动”做出的决策。这在实盘交易中会带来信任危机和风险管理的困难。
- 应对:结合可解释性AI技术。例如,使用注意力可视化来观察模型在预测时最关注图表中的哪些区域(是最近的K线,还是某个历史高点?)。使用梯度加权类激活映射来生成热力图,显示对决策贡献最大的像素区域。这不仅能增加信心,还能帮助你发现模型可能学到的、你未曾意识到的新形态。
5.3 策略集成与风险控制
永远不要将单一AI模型的输出直接作为交易信号。
- 作为过滤器或增强器:将Kronos这类视觉AI模型视为一个“模式扫描器”。它的输出可以作为传统量化策略的一个过滤条件或置信度加权因子。例如,只有当传统信号(如均线金叉)和视觉AI的看涨信号同时出现时,才执行交易。
- 多模型融合:训练多个不同架构(如ViT, ResNet, EfficientNet)或不同时间窗口的模型,进行集成预测,可以降低单一模型失效的风险。
- 严格的风险管理:必须设定硬性的止损止盈规则、仓位管理规则。AI模型可能会在某种未知市场环境下突然失效,导致连续亏损。风险管理是你在市场“裸奔”时的最后一条底裤。
6. 超越预测:Kronos理念的更多可能性
Kronos项目的启发意义远不止于创建一个预测模型。它打开了一扇门,让我们重新思考如何利用AI处理金融数据。
市场状态聚类与模式挖掘:我们可以用无监督学习的方法(如自编码器、聚类算法)对海量K线图进行编码和聚类。模型可能会自动发现一些重复出现的、未被命名的图表“模式簇”。这些簇可能对应着特定的市场微观结构状态(如“低波动吸筹”、“高波动出货”、“趋势中继”等),为市场状态识别提供新的、数据驱动的视角。
另类数据可视化分析:不仅仅是价格K线图。我们可以将订单流数据、Level2数据、甚至新闻情感时间序列渲染成“图像”,然后用视觉模型进行分析。例如,将一天的逐笔交易数据渲染成“交易热力图”,或许能揭示做市商行为或大型机构的足迹。
强化学习中的状态表示:在基于强化学习的交易智能体中,当前的市场状态(State)通常用一堆指标向量表示。或许,一张K线图图像是更丰富、更直观的状态表示方式,能帮助智能体更好地感知市场环境。
这个项目让我意识到,过去三年我可能过于依赖那些被我精心加工过的、看似“安全”的指标数据,就像穿着自己编织的铠甲在战场上冲锋,却忽略了战场本身最原始的地形、天气和敌我态势。Kronos所代表的“原始数据视觉化+端到端学习”范式,是一次大胆的“裸奔”——直接让AI去感受市场最本真的脉搏。虽然前路必然充满陷阱,其最终实战效能也尚需大量严谨验证,但它无疑为我们提供了一把锋利的新武器,逼迫我们重新审视那些被视为金科玉律的传统方法。对于每一个量化从业者来说,即使不立刻全盘采用,也绝对有必要深入了解和实验这一思路,因为它很可能代表了未来阿尔法挖掘的一个重要演进方向。至少,它让我在下次面对图表时,多了一份敬畏和想象。
