作者:魔元
目录
量化策略主要是从历史数据统计或者发现规律然后应用于实盘交易。当然历史不是简单的重复,这就要求策略需要根据市场调整和优化参数。通过回测历史数据可以验证策略的有效性,了解策略的历史收益、最大回撤和回撤时长,对策略参数进行优化等等。CTA策略模块的主要回测目标是验证交易信号是否正确,仓位大小的问题在实盘中则由交易员来确定。
vnpy的回测引擎位于vnpy/trader/app/ctaStrategy/ctaBacktesting.py,此文件中主要包含以下几个类:
BacktestingEngine
TradingResult
这里面有一点注意是交易数量的正负代表开仓方向。以股指IF为例,3000点时开1手多单,3010点平仓,这时就会生成一个TradingResult实例,交易数量为1。若3000点时开1手空单,3010点平仓,这时生成的TradingResult实例的交易数量为-1。
代码如下:
```Python
self.entryPrice = entryPrice # 开仓价格
self.exitPrice = exitPrice # 平仓价格
self.entryDt = entryDt # 开仓时间datetime
self.exitDt = exitDt # 平仓时间
self.volume = volume # 交易数量(+/-代表方向)
self.turnover = (self.entryPrice+self.exitPrice)*size*abs(volume) # 成交金额
self.commission = self.turnover*rate # 手续费成本
self.slippage = slippage*2*size*abs(volume) # 滑点成本
self.pnl = ((self.exitPrice - self.entryPrice) * volume * size
- self.commission - self.slippage) # 净盈亏
```
OptimizationSetting
由于用户主要是调用本类的接口来回测策略,所以将对本类的接口做逐一介绍。一方面回测引擎类的接口跟实盘策略引擎保持一样,这方面的接口主要是被策略调用; 另一方面回测引擎类也要提供回测相关的接口,所以将回测引擎类的接口从功能性分成这几个方面介绍:
用户回测策略接口
配置相关接口
setBacktestingMode
设置回测模式,支持两种模式,一种是Tick模式,另一种是K线模式
参数 | 类型 | 说明 |
---|---|---|
mode | string | 回测模式,支持两种模式:BacktestingEngine.TICK_MODE和BacktestingEngine.BAR_MODE |
返回值:None
setStartDate
设置回测开始日期
参数 | 类型 | 说明 |
---|---|---|
startDate | string | 回测开始日期 |
initDays | int | 策略回测开始前需要准备多少日的数据。默认是10日。举个例子,假设策略是日K线回测,数据库里的数据是日K线,如果策略里需要5日均线,这里此参数设为4。假设策略是1分钟K线回测,数据库里的数据是1分钟K线,如果策略里需要5分钟均线,这里此参数则设为1。因为1日里的1分钟K线数据远远大于4,已经足够满足策略开始的准备数据了。 |
返回值:None
setEndDate
设置回测结束日期
参数 | 类型 | 说明 |
---|---|---|
endDate | string | 回测结束日期。默认是''。若使用默认参数,则是数据在数据库里的最近日期。 |
返回值:None
setDatabase
设置产品(合约)数据的数据库名及表名,这样回测引擎可以载入对应的数据。
参数 | 类型 | 说明 |
---|---|---|
dbName | string | 数据库名 |
symbol | string | 数据库表名 |
返回值:None
setSlippage
设置每一手产品(合约)的滑点,单位是产品(合约)的价格
参数 | 类型 | 说明 |
---|---|---|
slippage | float | 滑点数值 |
返回值:None
setRate
设置佣金比例,交易手续费=成交金额X佣金比例
参数 | 类型 | 说明 |
---|---|---|
rate | float | 佣金比例 |
返回值:None
setSize
设置产品(合约)大小,单位为元。成交金额=合约价格(面值)X合约大小
参数 | 类型 | 说明 |
---|---|---|
size | float | 合约大小 |
返回值:None
setPriceTick
设置产品(合约)的最小价格变动,单位是产品(合约)的价格
参数 | 类型 | 说明 |
---|---|---|
priceTick | float | 最小价格变动 |
返回值:None
回测相关接口
initStrategy
根据策略参数,实例化回测策略对象。
参数 | 类型 | 说明 |
---|---|---|
strategyClass | class | 策略类 |
setting | dict | 策略参数配置,若使用策略的默认参数则为None |
返回值:None
runBacktesting
运行回测。从数据库里载入数据,逐条推入策略做回测,同时模拟委托和成交,并保存回测过程的中间数据,以此可以计算回测结果并显示。
参数:无
返回值:None
calculateBacktestingResult
逐条匹配交易,并计算回测结果。由于回测策略是假设初始资金为0,这样交易后资金可能为负值。这里跟实盘有区别,实盘需要保证金,回测时只考虑每笔交易的盈亏。
参数:无
返回值:dict
键值 | 值的类型 | 说明 |
---|---|---|
capital | float | 当前资金,单位是元 |
maxCapital | float | 资金最高净值,单位是元 |
drawdown | float | 当前回撤,非正值,单位是元 |
totalResult | int | 总成交次数 |
totalTurnover | float | 总成交金额 |
totalCommission | float | 总手续费 |
totalSlippage | float | 所有交易产生的滑点费用,单位是元 |
timeList | list | 每笔交易的时间序列,时间为交易出场时间 |
pnlList | list | 每笔盈亏序列 |
capitalList | list | 每笔交易后的资金序列 |
drawdownList | list | 每笔交易后的回撤序列 |
winningRate | float | 胜率(%) |
averageWinning | float | 盈利交易平均值,单位是元 |
averageLosing | float | 亏损交易平均值,单位是元 |
profitLossRatio | float | 盈亏比 |
showBacktestingResult
计算回测结果,输出回测报告,并显示回测结果图:资金子图,回撤子图,每笔交易盈亏子图
参数:无
返回值:None
calculateDailyResult
按照逐日盯市的方式计算每日的交易盈亏和持仓盈亏,并汇总成最终按日统计的盈亏情况。
参数:无
返回值:dict
showDailyResult
显示按照逐日盯市方式统计的回测结果和资金曲线,提供Sharpe Ratio的统计结果。
参数:无
返回值:None
优化参数相关接口
runOptimization
运行普通模式的优化参数,也就是说python主进程循环回测每一个参数组合,并输出每个参数组合的优化结果。普通模式下只能使用CPU的一个核。
参数 | 类型 | 说明 |
---|---|---|
strategyClass | class | 策略类 |
optimizationSetting | class | OptimizationSetting对象,基于它生成优化参数组合,并获取优化目标 |
返回值:None
runParallelOptimization
运行多进程模式的优化参数,也就是说并行运行多个进程(等于CPU的核个数)回测每一个参数组合,并输出每个参数组合的优化结果。
参数 | 类型 | 说明 |
---|---|---|
strategyClass | class | 策略类 |
optimizationSetting | class | OptimizationSetting对象,基于它生成优化参数组合,并获取优化目标 |
返回值:None
策略相关接口
交易相关接口
非交易相关接口
内部接口
本节结合代码和流程图讲解如何使用回测引擎API。
回测过程流程图
下图为基于策略特定参数的回测过程
回测过程详解
# 创建回测引擎
engine = BacktestingEngine()
# 这里将项目中包含的股指日内分钟线csv导入MongoDB,作者电脑耗时大约3分钟
import os
loadMcCsv(os.path.join(os.path.dirname(__file__), 'IF0000_1min.csv'), MINUTE_DB_NAME, 'IF0000')
如果数据已经在数据库中,则运行下面的代码设置回测引擎的相关参数
# 设置引擎的回测模式为K线
engine.setBacktestingMode(engine.BAR_MODE)
# 设置回测用的数据起始日期和结束日期
engine.setStartDate('20110101')
engine.setEndDate('20161231')
# 设置使用的历史数据库
engine.setDatabase(MINUTE_DB_NAME, 'IF0000')
这里MINUTE_DB_NAME是
MINUTE_DB_NAME = 'VnTrader_1Min_Db'
# 设置产品相关参数
engine.setSlippage(0.2) # 股指1跳
engine.setRate(0.3/10000) # 万0.3
engine.setSize(300) # 股指合约大小
# 在引擎中创建策略对象
d = {'atrLength': 11}
engine.initStrategy(AtrRsiStrategy, d)
策略的默认参数如下:
# 策略参数
atrLength = 22 # 计算ATR指标的窗口数
atrMaLength = 10 # 计算ATR均线的窗口数
rsiLength = 5 # 计算RSI的窗口数
rsiEntry = 16 # RSI的开仓信号
trailingPercent = 0.8 # 百分比移动止损
initDays = 10 # 初始化数据所用的天数
fixedSize = 1 # 每次交易的数量
# 开始跑回测
engine.runBacktesting()
# 显示回测结果
# spyder或者ipython notebook中运行时,会弹出盈亏曲线图
# 直接在cmd中回测则只会打印一些回测数值
engine.showBacktestingResult()
回测过程中主要步骤的流程图
下面是回测过程主要步骤的流程图,这部分实现对用户回测策略来讲是黑盒,可以不关注。
跑回测主要流程图
显示回测结果主要流程图
计算回测结果主要流程图
计算回测结果是采用贪婪算法将成交单按时间顺序逐一做开平仓清算。下图只是给出主要的逻辑步骤,具体细节参考代码,即:
def calculateBacktestingResult(self):
"""
计算回测结果
"""
...
在IPython下运行AtrRsiStrategy策略的回测,示例中使用的是VS2013下的IPython环境。示例中的vnpy代码位于F:\vnpy。读者可自行调整为自己机器上的vnpy代码所在目录。
In [2]: import sys
...: sys.path.append('F:\\vnpy\\vn.trader')
...: sys.path.append('F:\\vnpy\\vn.trader\ctaAlgo')
...: from __future__ import division
...: from datetime import datetime, timedelta
...: from collections import OrderedDict
...: from itertools import product
...: import multiprocessing
...: import pymongo
...: from ctaBase import *
...: from ctaSetting import *
...: from vtConstant import *
...: from vtGateway import VtOrderData, VtTradeData
...: from vtFunction import loadMongoSetting
...: from ctaBacktesting import *
...: from strategyAtrRsi import *
...:
In [3]: # 创建回测引擎
...: engine = BacktestingEngine()
...:
In [4]: # 设置引擎的回测模式为K线
...: engine.setBacktestingMode(engine.BAR_MODE)
...:
...: # 设置回测用的数据起始日期和结束日期
...: engine.setStartDate('20110101')
...: engine.setEndDate('20161231')
...:
...: # 设置使用的历史数据库
...: engine.setDatabase(MINUTE_DB_NAME, 'IF0000')
...:
In [5]: # 设置产品相关参数
...: engine.setSlippage(0.2) # 股指1跳
...: engine.setRate(0.3/10000) # 万0.3
...: engine.setSize(300) # 股指合约大小
...:
In [6]: # 在引擎中创建策略对象
...: d = {'atrLength': 11}
...: engine.initStrategy(AtrRsiStrategy, d)
...:
In [7]: # 开始跑回测
...: engine.runBacktesting()
...:
2017-02-08 19:01:03.243000 开始载入数据
2017-02-08 19:01:03.383000 载入完成,数据量:341851
2017-02-08 19:01:03.383000 开始回测
2017-02-08 19:01:03.396000 策略初始化完成
2017-02-08 19:01:03.396000 策略启动完成
2017-02-08 19:01:03.396000 开始回放数据
2017-02-08 19:01:17.451000 数据回放结束
In [8]: # 显示回测结果
...: engine.showBacktestingResult()
...:
2017-02-08 19:01:24.706000 计算回测结果
2017-02-08 19:01:24.790000 ------------------------------
2017-02-08 19:01:24.790000 第一笔交易: 2011-01-11 13:19:00
2017-02-08 19:01:24.790000 最后一笔交易: 2016-04-01 13:17:00
2017-02-08 19:01:24.790000 总交易次数: 3,965.0
2017-02-08 19:01:24.790000 总盈亏: 695,298.02
2017-02-08 19:01:24.791000 最大回撤: -197,106.11
2017-02-08 19:01:24.791000 平均每笔盈利: 175.36
2017-02-08 19:01:24.791000 平均每笔滑点: 120.0
2017-02-08 19:01:24.791000 平均每笔佣金: 57.01
2017-02-08 19:01:24.791000 胜率 36.39%
2017-02-08 19:01:24.791000 盈利交易平均值 8,721.64
2017-02-08 19:01:24.791000 亏损交易平均值 -4,714.52
2017-02-08 19:01:24.791000 盈亏比: 1.85
首先先解释一下回测报告里的交易是什么意思:
计算回测结果字段说明
字段 | 说明 |
---|---|
第一笔交易 | 第一笔交易的平仓时间 |
最后一笔交易 | 最后一笔交易的平仓时间 |
总交易次数 | 整个回测的总交易次数 |
总盈亏 | 整个回测的总盈亏,由于回测时初始资金为0,总盈亏其实就是当前资金 |
最大回撤 | 每次交易后的回撤 = 每笔交易后的资金 - 回测中最大资金。由于回撤为非正值,所以最大回撤为所有交易后的回撤绝对值最大的 |
平均每笔盈利 | 总盈亏/总交易次数 |
平均每笔滑点 | 总滑点成本/总交易次数 |
平均每笔佣金 | 总佣金成本/总交易次数 |
胜率 | 盈利交易次数/总交易次数*100(%) |
盈利交易平均值 | 总盈利交易的盈利/总盈利交易次数 |
亏损交易平均值 | 总亏损交易的盈利/总亏损交易次数 |
盈亏比 | 盈利交易平均值/亏损交易平均值 |
计算回测结果图说明
图里的X轴没有采用交易时间刻度,而是将每笔交易按时间顺序从0开始标成0,1,2,3,4,...
子图名 | 说明 |
---|---|
capital | 每笔交易后的资金序列图 |
DD | dropdown,每笔交易后的回撤序列图 |
pnl | profit&loss,每笔交易的盈亏直方图(概率分布图) |
策略的参数优化是对指定的优化目标(比如胜率,总盈亏,盈亏比等),回测每个参数的网格组合,从而找到使优化目标最优的参数组合。比如AtrRsiStrategy策略,有七个参数:
# 策略参数
atrLength = 22 # 计算ATR指标的窗口数
atrMaLength = 10 # 计算ATR均线的窗口数
rsiLength = 5 # 计算RSI的窗口数
rsiEntry = 16 # RSI的开仓信号
trailingPercent = 0.8 # 百分比移动止损
initDays = 10 # 初始化数据所用的天数
fixedSize = 1 # 每次交易的数量
这里面'initDays'可以忽略。如果'atrLength'的取值范围是12-20,步长2;'atrMa'的取值范围是20-30,步长5。这样对于'atrLength'有5个取值[12,14,16,18,20],对于'atrMaLength'有3个取值[20,25,30],总共有5X3, 15个参数组合需要回测。如果设置更多的参数和更小的步长,由于参数的组合数量是幂次方,可想而知需要回测的参数组合的数量相当大,这样就要耗费大量的时间。 优化参数有两种模式:
本节主要讲解普通模式的参数优化。下图为普通模式的参数优化流程图:
下表为支持的优化目标键值:
键值 | 值的类型 | 说明 |
---|---|---|
capital | float | 当前资金,单位是元 |
maxCapital | float | 资金最高净值,单位是元 |
drawdown | float | 当前回撤,单位是元 |
totalResult | int | 总成交次数 |
totalTurnover | float | 总成交金额 |
totalCommission | float | 总手续费 |
totalSlippage | float | 所有交易产生的滑点费用,单位是元 |
winningRate | float | 胜率(%) |
averageWinning | float | 盈利交易平均值,单位是元 |
averageLosing | float | 亏损交易平均值,单位是元 |
profitLossRatio | float | 盈亏比 |
用户只需关注参数优化主流程,这里以AtrRsiStrategy策略为例,对每个步骤结合代码做以下详解:
# 创建回测引擎
engine = BacktestingEngine()
# 设置引擎的回测模式为K线
engine.setBacktestingMode(engine.BAR_MODE)
# 设置回测用的数据起始日期和结束日期
engine.setStartDate('20110101')
engine.setEndDate('20161231')
# 载入历史数据到引擎中
engine.setDatabase(MINUTE_DB_NAME, 'IF0000')
# 设置产品相关参数
engine.setSlippage(0.2) # 股指1跳
engine.setRate(0.3/10000) # 万0.3
engine.setSize(300) # 股指合约大小
# 创建优化参数设置实例
setting = OptimizationSetting() # 新建一个优化任务设置对象
setting.setOptimizeTarget('capital') # 设置优化排序的目标是策略净盈利
setting.addParameter('atrLength', 12, 20, 2) # 增加第一个优化参数atrLength,起始12,结束20,步进2
setting.addParameter('atrMaLength', 20, 30, 5) # 增加第二个优化参数atrMaLength,起始20,结束30,步进5
setting.addParameter('rsiLength', 5) # 增加一个固定数值的参数
## 运行单进程优化函数,自动输出结果
engine.runOptimization(AtrRsiStrategy, setting)
浮点数由于精度问题,可能会出现误差。由于参数组合是无序字典,所以可能参数组合的回测顺序跟笔者的不一样。笔者电脑上,单进程优化耗时约3分40秒。
In [12]: import sys
....: sys.path.append('F:\\vnpy\\vn.trader')
....: sys.path.append('F:\\vnpy\\vn.trader\ctaAlgo')
....: from __future__ import division
....: from datetime import datetime, timedelta
....: from collections import OrderedDict
....: from itertools import product
....: import multiprocessing
....: import pymongo
....: from ctaBase import *
....: from ctaSetting import *
....: from vtConstant import *
....: from vtGateway import VtOrderData, VtTradeData
....: from vtFunction import loadMongoSetting
....: from ctaBacktesting import *
....: from strategyAtrRsi import *
....:
In [13]: # 创建回测引擎
....: engine = BacktestingEngine()
....:
In [14]: # 设置引擎的回测模式为K线
....: engine.setBacktestingMode(engine.BAR_MODE)
....:
....: # 设置回测用的数据起始日期和结束日期
....: engine.setStartDate('20110101')
....: engine.setEndDate('20161231')
....:
....: # 载入历史数据到引擎中
....: engine.setDatabase(MINUTE_DB_NAME, 'IF0000')
....:
In [15]: # 设置产品相关参数
....: engine.setSlippage(0.2) # 股指1跳
....: engine.setRate(0.3/10000) # 万0.3
....: engine.setSize(300) # 股指合约大小
....:
In [16]: # 创建优化参数设置实例
....: setting = OptimizationSetting() # 新建一个优化任务设置对象
....:
In [17]: setting.setOptimizeTarget('capital') # 设置优化排序的目标是策略净盈利
....: setting.addParameter('atrLength', 12, 20, 2) # 增加第一个优化参数atrLength,起始12,结束20,步进2
....: setting.addParameter('atrMaLength', 20, 30, 5) # 增加第二个优化参数atrMaLength,起始20,结束30,步进5
....: setting.addParameter('rsiLength', 5) # 增加一个固定数值的参数
....:
In [18]: ## 运行单进程优化函数,自动输出结果
....: engine.runOptimization(AtrRsiStrategy, setting)
....:
2017-02-08 19:06:19.279000 ------------------------------
2017-02-08 19:06:19.280000 setting: {'atrMaLength': 20, 'rsiLength': 5, 'atrLength': 12}
2017-02-08 19:06:19.282000 开始载入数据
2017-02-08 19:06:21.034000 载入完成,数据量:341851
2017-02-08 19:06:21.034000 开始回测
2017-02-08 19:06:21.050000 策略初始化完成
2017-02-08 19:06:21.050000 策略启动完成
2017-02-08 19:06:21.050000 开始回放数据
2017-02-08 19:06:35.728000 数据回放结束
2017-02-08 19:06:35.728000 计算回测结果
2017-02-08 19:06:35.923000 ------------------------------
2017-02-08 19:06:35.924000 setting: {'atrMaLength': 25, 'rsiLength': 5, 'atrLength': 12}
2017-02-08 19:06:35.925000 开始载入数据
2017-02-08 19:06:36.015000 载入完成,数据量:341851
2017-02-08 19:06:36.015000 开始回测
2017-02-08 19:06:36.030000 策略初始化完成
2017-02-08 19:06:36.030000 策略启动完成
2017-02-08 19:06:36.030000 开始回放数据
2017-02-08 19:06:50.140000 数据回放结束
2017-02-08 19:06:50.140000 计算回测结果
...
2017-02-08 19:09:30.237000 ------------------------------
2017-02-08 19:09:30.237000 setting: {'atrMaLength': 25, 'rsiLength': 5, 'atrLength': 20}
2017-02-08 19:09:30.239000 开始载入数据
2017-02-08 19:09:30.330000 载入完成,数据量:341851
2017-02-08 19:09:30.330000 开始回测
2017-02-08 19:09:30.343000 策略初始化完成
2017-02-08 19:09:30.343000 策略启动完成
2017-02-08 19:09:30.343000 开始回放数据
2017-02-08 19:09:44.499000 数据回放结束
2017-02-08 19:09:44.499000 计算回测结果
2017-02-08 19:09:44.696000 ------------------------------
2017-02-08 19:09:44.696000 setting: {'atrMaLength': 30, 'rsiLength': 5, 'atrLength': 20}
2017-02-08 19:09:44.697000 开始载入数据
2017-02-08 19:09:44.787000 载入完成,数据量:341851
2017-02-08 19:09:44.787000 开始回测
2017-02-08 19:09:44.801000 策略初始化完成
2017-02-08 19:09:44.801000 策略启动完成
2017-02-08 19:09:44.801000 开始回放数据
2017-02-08 19:09:58.942000 数据回放结束
2017-02-08 19:09:58.942000 计算回测结果
2017-02-08 19:09:59.242000 ------------------------------
2017-02-08 19:09:59.242000 优化结果:
2017-02-08 19:09:59.242000 ["{'atrMaLength': 30, 'rsiLength': 5, 'atrLength': 20}"]: 1127713.85011
2017-02-08 19:09:59.242000 ["{'atrMaLength': 30, 'rsiLength': 5, 'atrLength': 18}"]: 1030743.75807
2017-02-08 19:09:59.242000 ["{'atrMaLength': 25, 'rsiLength': 5, 'atrLength': 16}"]: 983294.726285
2017-02-08 19:09:59.242000 ["{'atrMaLength': 20, 'rsiLength': 5, 'atrLength': 18}"]: 975329.10312
2017-02-08 19:09:59.242000 ["{'atrMaLength': 30, 'rsiLength': 5, 'atrLength': 12}"]: 949746.520421
2017-02-08 19:09:59.242000 ["{'atrMaLength': 25, 'rsiLength': 5, 'atrLength': 12}"]: 914875.145592
2017-02-08 19:09:59.243000 ["{'atrMaLength': 30, 'rsiLength': 5, 'atrLength': 16}"]: 899113.140024
2017-02-08 19:09:59.243000 ["{'atrMaLength': 20, 'rsiLength': 5, 'atrLength': 14}"]: 896378.557181
2017-02-08 19:09:59.243000 ["{'atrMaLength': 30, 'rsiLength': 5, 'atrLength': 14}"]: 893726.622984
2017-02-08 19:09:59.243000 ["{'atrMaLength': 20, 'rsiLength': 5, 'atrLength': 16}"]: 883947.771514
2017-02-08 19:09:59.243000 ["{'atrMaLength': 25, 'rsiLength': 5, 'atrLength': 14}"]: 873221.532605
2017-02-08 19:09:59.243000 ["{'atrMaLength': 20, 'rsiLength': 5, 'atrLength': 12}"]: 857260.355525
2017-02-08 19:09:59.243000 ["{'atrMaLength': 20, 'rsiLength': 5, 'atrLength': 20}"]: 852615.557093
2017-02-08 19:09:59.243000 ["{'atrMaLength': 25, 'rsiLength': 5, 'atrLength': 20}"]: 790618.233326
2017-02-08 19:09:59.243000 ["{'atrMaLength': 25, 'rsiLength': 5, 'atrLength': 18}"]: 726949.447939
优化结果的输出格式是:参数组合:优化目标值
本节主要讲解参数的优化的多进程模式。由于Python的GIL原因,多进程模式可以更好的利用CPU的多核,提高优化参数速度。由于vnpy已经提供RPC模块,所以可以基于RPC模块实现分布式参数优化。
多进程参数优化主流程图和优化函数流程图
用户只需关注多进程参数优化主流程,这里以AtrRsiStrategy策略为例,对每个步骤结合代码做以下详解。跟普通模式的参数优化的区别是最后调用多进程优化接口。笔者电脑上,示例中AtrRsiStrategy策略多进程回测的耗时约为52秒。
# 创建回测引擎
engine = BacktestingEngine()
# 设置引擎的回测模式为K线
engine.setBacktestingMode(engine.BAR_MODE)
# 设置回测用的数据起始日期和结束日期
engine.setStartDate('20110101')
engine.setEndDate('20161231')
# 载入历史数据到引擎中
engine.setDatabase(MINUTE_DB_NAME, 'IF0000')
# 设置产品相关参数
engine.setSlippage(0.2) # 股指1跳
engine.setRate(0.3/10000) # 万0.3
engine.setSize(300) # 股指合约大小
# 创建优化参数设置实例
setting = OptimizationSetting() # 新建一个优化任务设置对象
setting.setOptimizeTarget('capital') # 设置优化排序的目标是策略净盈利
setting.addParameter('atrLength', 12, 20, 2) # 增加第一个优化参数atrLength,起始12,结束20,步进2
setting.addParameter('atrMaLength', 20, 30, 5) # 增加第二个优化参数atrMaLength,起始20,结束30,步进5
setting.addParameter('rsiLength', 5) # 增加一个固定数值的参数
## 运行多进程优化函数,自动输出结果
engine.runParallelOptimization(AtrRsiStrategy, setting)