Lean 是 QuantConnect 开源的一款非常强大的开源量化交易平台,可以回测或运行Python或者C#写的策略,并内置了上百个C#和Python写的策略算法在代码仓库中。
这个开源算法交易引擎,专为轻松地进行策略研究、回测和实时交易而构建。它集成了常见的数据提供商和券商,因此可以快速部署算法交易策略。
LEAN Engine 的核心是用 C# 编写的;但它可以在 Linux、Mac 和 Windows 操作系统上无缝运行。它支持用 Python 3.6 或 C# 编写的算法。
引擎分为许多模块化部分,可以在不接触其他文件的情况下对某个模块进行扩展。
最重要的几个模块是:
- 结果处理(IResultHandler)处理来自算法交易引擎的所有消息。决定应该发送什么,以及消息应该去哪里。结果处理系统可以将消息发送到本地 GUI 或 Web 界面。
- 数据源(IDataFeed)连接并下载算法交易引擎所需的数据。从磁盘文件中读取文件进行回测;实时交易则连接到一个流并生成数据对象。
- 事务处理(ITransactionHandler)处理新的订单请求;要么使用算法提供的模拟模型,要么使用实际券商。
- 实时事件管理(IRealtimeHandler)生成实时事件 – 例如一天结束的事件。触发对实时事件处理程序的回调。
- 算法状态设置(ISetupHandler)配置算法资金、投资组合和请求的数据。初始化所需的所有状态参数。
这些都可以从 Launcher 项目中的 config.json 文件进行配置。
1. Leon 安装教程
由于Leon是基于C#开发的,因此我推荐使用Visual Studio进行开发。
1、克隆项目。从 https://github.com/QuantConnect/Lean 克隆项目到本地(如果你网络不通可在公众号后台回复 Lean 下载)。
2、使用 Visual Studio 打开项目中的 QuantConnect.Lean.sln
3、点击 生成 – 生成解决方案
4、点击 F5 则可以运行程序。
如果你在生成解决方案的过程中遇到了类似于如下的错误:
请在工具 – NuGet包管理器 – 程序包管理器设置 中 添加如下的源, 名字任取,链接对了就行: https://api.nuget.org/v3/index.json
2. 回测 Lean 内置的C#策略
Lean 中比较有意思的一点是,其所有C#策略算法都位于 QuantConnect.Algorithm.CSharp 中,所有的Python策略算法都位于 QuantConnect.Algorithm.Python 中:
如果你想回测C#的策略,你只需要修改 QuantConnect.Lean.Launcher 中的 config.json,将 QuantConnect.Algorithm.CSharp 中对应策略名称,修改到 algorithm-type-name 字段对应的值中,如图所示:
然后按 F5 运行程序,回测开始,此时会弹出一个cmd窗口,里面有本次回测的统计数据:
3. 回测 Lean 内置的 Python策略
如果你想要回测内置的Python策略,我们需要先指定Lean使用的Python环境位置:
1.打开系统变量(我的电脑-右键属性-高级系统设置->环境变量->系统变量)
2.点击新建变量,name为 PYTHONNET_PYDLL;value则为你的Python环境的dll文件所在文件夹,如我的为 G:\Anaconda3\python36.dll
3.在此Python环境中安装Lean的依赖:
pip install pandas pip install wrapt==1.11.2
然后在项目的 config.json 中需要多改几个配置:
然后按F5进行回测,效果如下:
这些统计指标令人眼花缭乱,对于股票的回测我们只要重点关注这些即可:
- Total Trades: 总交易量
- Average Win: 平均盈利率
- Average Loss: 平均亏损率
- Compounding Annual Return: 复合年回报率
- Drawdown: 最大回撤率
- Expectancy: 期望值
- Net Profit: 净利润
- Sharpe Ratio: 夏普比率
- Probabilistic Sharpe Ratio: 概率性夏普比率
- Loss Rate: 失败率
- Win Rate: 胜率
- Profit-Loss Ratio: 盈亏比
- Alpha: Alpha值
- Beta: Beta值
- Total Fees: 总手续费
其他的,按需关注即可。
4. Lean 策略是怎么写的?
开始之前,让我们先学习下 Lean 内置策略的写法:
from AlgorithmImports import * class MACDTrendAlgorithm(QCAlgorithm): def Initialize(self): '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.''' self.SetStartDate(2004, 1, 1) #Set Start Date self.SetEndDate(2015, 1, 1) #Set End Date self.SetCash(100000) #Set Strategy Cash # Find more symbols here: http://quantconnect.com/data self.AddEquity("SPY", Resolution.Daily) # define our daily macd(12,26) with a 9 day signal self.__macd = self.MACD("SPY", 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily) self.__previous = datetime.min self.PlotIndicator("MACD", True, self.__macd, self.__macd.Signal) self.PlotIndicator("SPY", self.__macd.Fast, self.__macd.Slow) def OnData(self, data): '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.''' # wait for our macd to fully initialize if not self.__macd.IsReady: return # only once per day if self.__previous.date() == self.Time.date(): return # define a small tolerance on our checks to avoid bouncing tolerance = 0.0025 holdings = self.Portfolio["SPY"].Quantity signalDeltaPercent = (self.__macd.Current.Value - self.__macd.Signal.Current.Value)/self.__macd.Fast.Current.Value # if our macd is greater than our signal, then let's go long if holdings <= 0 and signalDeltaPercent > tolerance: # 0.01% # longterm says buy as well self.SetHoldings("SPY", 1.0) # of our macd is less than our signal, then let's go short elif holdings >= 0 and signalDeltaPercent < -tolerance: self.Liquidate("SPY") self.__previous = self.Time
可以看到,其实它和Backtrader的写法相差无几,Initialize 函数设置基本的回测参数,如:
- self.SetStartDate: 回测起始时间
- self.SetEndDate: 回测结束时间
- self.setCash: 回测资金
- self.AddEquity: 回测对象(Resolution.Daily 是指按日回测)
- self.PlotIndicator: 绘图时添加指标
而 onData 函数则会在每个数据点上做操作,如果是日线,则每天的数据都会流入到这个函数并运行一遍。因此 onData 就是算法分析的主逻辑。
在这里,你可以检查需要的指标是否已经准备完毕,因为可能存在一些滞后性指标在回测刚开始的时候并没有对应的值;此外,在日线的情况下,你还可以检测上一个数据点是不是和这个点在同一天上,如果是的话则不作任何操作返回:
if not self.__macd.IsReady: return if self.__previous.date() == self.Time.date(): return
然后就是核心的买入卖出逻辑:
tolerance = 0.0025 holdings = self.Portfolio["SPY"].Quantity signalDeltaPercent = (self.__macd.Current.Value - self.__macd.Signal.Current.Value)/self.__macd.Fast.Current.Value # if our macd is greater than our signal, then let's go long if holdings <= 0 and signalDeltaPercent > tolerance: # 0.01% # longterm says buy as well self.SetHoldings("SPY", 1.0) # of our macd is less than our signal, then let's go short elif holdings >= 0 and signalDeltaPercent < -tolerance: self.Liquidate("SPY") self.__previous = self.Time
如果我持仓的股数<=0, 且信号值大于我设定的阈值,则将我资产的1%买入这只股票。这里和backtrader最大的不同,买入是以资产的百分比为单位的动态买入。当然,你也可以使用限定数量的买入方式:
self.LimitOrder("IBM", 100, self.Securities["IBM"].Price)
如果持仓股市>=0, 且触发卖出信号,则进行清仓操作:
elif holdings >= 0 and signalDeltaPercent < -tolerance: self.Liquidate("SPY")
如果你不希望全部清仓,也可以使用 SetHoldings 来调整仓位。
可以看到,Lean相对于Backtrader有更灵活的仓位管理方式,甚至能够进行自动仓位调整、构建投资组合、实时交易等等。而且针对一些比较复杂的策略,你还可以用C#而不是Python来编写以提高运行速度。
综上所述,Lean是一个非常值得深入学习的量化交易平台,有兴趣的同学可以在他们官网学习到更多的内容:
https://www.quantconnect.com/docs
我们的文章到此就结束啦,如果你喜欢今天的 Python 教程,请持续关注Python实用宝典。
有任何问题,可以在公众号后台回复:加群,回答相应验证信息,进入互助群询问。
原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!
Python实用宝典 ( pythondict.com )
不只是一个宝典
欢迎关注公众号:Python实用宝典