在量化交易系统中,有两个最核心的变数:
-
数据(Data):来源多样(文件、API、Socket)、格式各异(CSV、JSON、二进制)、频率不同(Tick、分钟、日线)。
-
算法(Algorithm):语言不同(C# 或 Python)、逻辑各异。
Lean 引擎作为一个通用的框架,必须能够“无感”地处理这些差异。它通过在核心逻辑中大量应用工厂模式,成功地将复杂的对象创建过程封装起来,让引擎主体逻辑始终保持简洁和稳定。
1. 数据的“百变工厂”:SubscriptionDataSourceReader
在 Lean 中,每一份订阅的数据(如 AAPL 的股票价格)都需要一个“读取器”。由于数据可能存在于本地硬盘、S3 云端或者远程 REST API 中,引擎不能写死读取逻辑。
核心实现:ForSource 静态工厂
在 Lean.Engine.DataFeeds.SubscriptionDataSourceReader.cs 中,你会看到一个经典的工厂实现:
C#
public static ISubscriptionDataSourceReader ForSource(
SubscriptionDataSource source,
IDataCacheProvider dataCacheProvider,
SubscriptionDataConfig config,
DateTime date,
bool isLiveMode,
BaseData factory)
{
// 根据传输介质(TransportMedium)决定创建哪种读取器
switch (source.TransportMedium)
{
case SubscriptionTransportMedium.LocalFile:
return new LocalFileSubscriptionDataSourceReader(dataCacheProvider, config, date, isLiveMode);
case SubscriptionTransportMedium.Rest:
return new RestSubscriptionDataSourceReader(dataCacheProvider, config, date, isLiveMode);
// ... 其他介质类型
default:
throw new NotImplementedException("尚未实现的订阅工厂类型");
}
}
解耦的妙处:
引擎的主循环(DataFeed)只需要调用 ForSource 拿到一个 ISubscriptionDataSourceReader 接口对象,然后无脑调用 reader.GetTokens() 即可。至于数据是跨越网络下载的,还是从本地 Zip 包里解压出来的,主循环完全不需要关心。
2. 算法的“语言翻译工厂”:LeanAlgorithmFactory
Lean 最强大的特性之一是同时支持 C# 和 Python 编写策略。这种“跨语言”支持是如何在底层统一的呢?
当用户提交一个策略时,引擎收到的可能是一个 .dll 文件(C#)或一个 .py 文件(Python)。Lean 使用了一个算法工厂来抹平这种差异。
核心逻辑:从路径到实例
-
C# 算法:工厂使用
Assembly.Load加载 DLL,并通过反射实例化继承自IAlgorithm的类。 -
Python 算法:这是最有趣的部分。工厂会创建一个特殊的 Python 包装器(Wrapper)。它实例化一个 C# 对象,这个对象内部启动一个 Python 解释器(Python.NET),并将所有的算法调用(如
OnData,OnOrderEvent)转发给 Python 代码。
通过这种工厂模式,对于 AlgorithmManager 来说,它手里拿到的永远是一个实现了 IAlgorithm 接口的对象,它不需要知道这个对象背后运行的是哪种语言。
3. 为什么不直接 New?(工厂模式的深度思考)
在 Lean 的源码中,你很难看到直接 new 一个具体数据类或算法类的操作。这种坚持带来两个巨大的好处:
A. 极强的可扩展性 (Extensibility)
如果你想让 Lean 支持一种全新的数据格式(比如从 Kafka 读取),你只需要:
-
实现
ISubscriptionDataSourceReader接口。 -
在工厂类中增加一个新的
case。 -
不需要修改任何核心的数据分发逻辑。
B. 易于测试 (Testability)
量化系统最怕“硬编码”。通过工厂模式,在单元测试中,我们可以通过 Mock 工厂返回伪造的测试数据流,从而在不依赖真实市场数据的情况下,验证引擎的逻辑正确性。
4. 源码探索建议
如果你想亲手翻阅这部分代码,建议按以下顺序在 GitHub 仓库中搜索:
-
数据读取工厂:
Lean/Engine/DataFeeds/SubscriptionDataSourceReader.cs -
基础数据工厂(BaseData):
Lean/Common/Data/BaseData.cs—— 注意GetSource和Reader方法,这是每个具体数据类型(如 TradeBar)自带的微型工厂方法。 -
设置处理器:
Lean/Engine/Setup/ConsoleSetupHandler.cs—— 观察它是如何利用工厂创建算法实例并初始化环境的。
5. 总结
工厂模式在 Lean 中扮演了“隔离层”的角色。它将**“对象是什么”(具体实现)与“对象怎么用”**(接口调用)彻底分开。

4580

被折叠的 条评论
为什么被折叠?



