# 回测
# Python 策略 Hello World
以下的策略是最简单的一个买入并持有平安银行(buy and hold)的展示,回测基本流程如下:
- 在创建策略之后,您需要指定回测的起止日期、初始资金以及回测频率。
- 在init方法中实现策略初始化逻辑,例如设置合约池、佣金率、保证金率等操作。
- 可以选择在before_trading进行一些每日开盘之前的操作,比如获取历史行情做一些数据预处理,获取当前账户资金等。
- 在handle_bar方法中实现策略具体逻辑,包括交易信号的产生、订单的创建等。handle_bar 内的逻辑会在每次 bar 数据更新的时候被触发。
- 回测完成后,在'回测结果'页面会展示回测的仓位、盈亏、交易、风险等信息。
您可以点击右上角的 clone 按钮复制到自己的策略列表中进行修改和测试,非常简单。
# 可以自己import我们平台支持的第三方python模块,比如pandas、numpy等。
# 在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。
def init(context):
context.s1 = "000001.XSHE"
# order是否被发送出去
context.fired = False
# 你选择的证券的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新
def handle_bar(context, bar_dict):
# 开始编写你的主要的算法逻辑
# bar_dict[order_book_id] 可以拿到某个证券的bar信息
# context.portfolio 可以拿到现在的投资组合信息
# 使用order_shares方法进行下单
# TODO: 开始编写你的算法吧!
if not context.fired:
# order_percent并且传入1代表买入该股票并且使其占有投资组合的100%
order_percent(context.s1, 1)
context.fired = True
# 代码策略
# 创建代码策略
您可以通过在'我的策略'下点击'创建新策略'来创建一个新的回测,如下图:
需要注意,您在首次创建策略的时候需要指定策略交易的品种(股票,期货,或者两者混合)。需要注意,一旦策略创建完毕,交易品种将不能变更。
# 运行回测
策略算法编辑页面是运行回测的入口,如下图所示:
您可以在策略编辑页面中进行以下参数的设置:
基础参数:
- 开始日期:回测期间的开始日期
- 结束日期:回测期间的结束日期 - 如果回测结束日期在今天之后,将会自动使用最后一天的历史数据
- 起始资金:回测的起始资金 - 您将使用多少钱去投资策略
- 回测频率:可以选择日回测、分钟回测以及 tick 级别回测
高阶设置:
- 基准合约:设置策略表现的对照基准
- 佣金倍率:设置策略佣金在默认佣金基础上的倍数
- 保证金倍率:设置策略保证金在默认保证金率基础上的倍数
- 撮合方式:在勾选日回测,可以选择'当前 bar 收盘';在勾选分钟回测时,可以选择'当前 bar 收盘'或'下一 bar 开盘';在勾选 tick 级别回测时,目前支持‘己方最优',‘对手方最优'和‘最新价成交'
- 滑点:交易中理想成交价和实际成交价的差异。在进行策略回测时,用户可以设置一个滑点参数,来提高买入价或降低卖出价,模拟实际交易中出现的滑点。目前支持的滑点类型有百分比和跳/手,百分比:按照成交价的一定比例进行恶化, 取值范围 [0, 1),例如,当股票市价为 10 元,参数设为 0.1,则回测时买入价为 10 + 10 * 0.1 = 11 元; 跳/手:按照最小价格变动单位对成交价进行恶化,例如,上例中设置值为 5, 最终成交价将变成 10.05
- 性能分析:勾选该选项之后,策略回测性能分析功能将被开启
- 分红再投资:勾选该选项之后,基金分红将按照当日净值折算成基金份额;股票分红将按照分红当日收盘价折算为仓位
- 允许买空:勾选该选项之后,回测中可以允许股票买空
- 限制成交量:勾选该选项之后,策略发单成交量将不能超过 bar 成交量的一定比例
- 成交百分比:与限制成交量联动,用户可以设置成交的比例
在设置完回测参数之后,您可以点击'编译策略'来对策略进行编译,发现其中是否有错误;或点击'运行回测'直接运行回测。两者的区别如下:
# 编译策略
点击"编译策略"将会使我们的后台实时编译您的算法策略来查询您的策略是否有编译错误并且可以获得一个策略收益的预览。编译策略会比完整的回测要快,因此您可以试用这个功能在完整回测前先验证下是否有简单的编译或者运行错误。
# 运行回测
点击"运行回测"将会带您进入完整的回测结果页面。如果您的策略有编译/运行错误,您将会被停留在改编辑页面以让您先解决问题。
# 自定义参数
您可以在编写策略时通过以下方式初始化设置自定义参数:
- 通过
define_parameter()
设置自定义参数的参数名、数据类型、参数值、备注信息等内容, 目前支持的数据类型包括int
、float
、str
、bool
- 设置完毕之后, 点击代码编辑器上方的【保存】按键, 点击右侧的【策略参数】按键即可以看到对应参数信息已经展示在参数表中
- 您可以在界面中设置对应参数值。该参数会覆盖默认参数传递至策略中。自定义参数可以通过
p
这一关键字获取到
define_parameter('param1', 'float', 1.3, 'comment1')
define_parameter('param2', 'int', 10, 'comment2')
define_parameter('param3', 'bool', True, 'comment3')
define_parameter('param4', 'str', 'test', 'comment4')
def init(context):
# 通过 p 这一关键字获取对应自定义参数
logger.info(p.param1)
logger.info(p.param2)
logger.info(p.param3)
logger.info(p.param4)
def before_trading(context):
pass
def handle_bar(context, bar_dict):
pass
def after_trading(context):
pass
# 复权机制
复权是用来消除由于除权除息造成的价格、指标的走势畸变。
举例来说, 平安银行最近两年的分红派息时间为:
除权除息日 | 复权因子 |
---|---|
2015-04-13 | 1.210683 |
2016-06-16 | 1.217847 |
平安银行的价格在 2015-04-10 为 19.80,在除权除息以后的 2015-04-13 价格变为 16.54,如果什么也不做,就会导致 K 线上的价格在 2015-04-13 突然降低,复权的作用就是为了让股价连续,消除价格和指标的走势畸变。
常见的复权机制有前复权和后复权。前复权就是保持现有的价格不变,将以前的价格缩减,在 K 线上的表现就是将除权除息日之前的 K 线向下移动;后复权就是保持先前的价格不变,将以后的价格提高,在 K 线上的表现就是将除权除息日之后的 K 线向上移动。
值得注意的是:无论是前复权还是后复权,它们都是以当前时间点复权因子进行数据的转变。这就会导致一个问题,假设我们需要回测 2016 年-2017 年的策略的表现,若使用前复权,数据会使用当前(2018 年)的复权因子,这样的数据会混杂未来数据(即 2018 年的复权因子),未来数据对于回测来说是致命的。
为了解决这一问题,米筐回测使用的数据采用了 “动态复权” 方式, 以策略回测当前日期为基准进行前复权。用同一个例子来说明:回测 2016 年-2017 年,数据会使用策略回测当前日期(即 2017 年)的复权因子进行前复权,这样就可以排除未来数据的干扰。更加直观的图像如下图所示:
目前米筐的 API 提供两种不同的获得历史数据的方式:history_bars()
;get_price()
。其中history_bars()
返回的是动态复权的数据;get_price()
返回的是前复权的数据,您可以根据自己的需求选择不同的方法。
# 基准合约
通过引入基准合约,您可以将策略的表现与基准进行对比,以衡量一定时间内策略的超额表现以及相关风险调整收益指标。
您可以在策略编辑页面"更多"选项下进行基准合约的设置,基准合约可以设置为空。在初次创建策略的时候,包含股票的策略默认基准合约都是沪深 300 指数 000300.XSHG;单独期货策略默认没有基准合约。
# 保证金倍率
在进行期货交易时,您可以通过设置保证金倍率来进行保证金的调整,这一倍率需大于 0。
调整依据基准是交易所规定的最低保证金比例,可以通过 instruments 这一方法查询到。您可以在策略编辑页面"更多"选项下进行保证金倍率设置。该设置在单一股票类型策略中不会出现。
# 交易费用
在新版策略框架中,原有通过 context.commission 设置佣金费率的方式已经被废弃,不再生效。您需要在策略参数高级设置界面中进行佣金倍率的设置,1 即代表为默认佣金费率的一倍。该倍率不会影响最低佣金以及印花税的收取标准。
中国 A 股交易费用
A 股市场交易费用主要由佣金和印花税两部分组成,佣金目前为双边收费,每笔委托最小收取标准为 5 元。默认佣金费率是成交额的万分之 8,即 0.0008。如果设置倍率为 10,则实际影响策略的佣金费率就变成了 0.008。该倍率并不会影响 5 元的最小佣金水平。印花税只对卖出方单边征收,对买入方不征税,目前按照成交金额的 0.1%收取。由于是强制征收,印花税已经默认加入到我们的收益计算中。中国期货交易费用
期货交易费用只包括佣金这一个组成部分。佣金收取方式比较复杂,收取方式有按照名义价值的一定比例收取和按照成交合约张数收取两种方式,同时个别合约区分平今仓费率。
我们也支持自定义期货佣金费用的设置,您可以从设置 config 设置项来指定每一个品种的交易费率、平今费率等。初始默认费率表如下请参考:
品种 交易所 佣金类型 回测佣金费率 回测平今费率 铝 AL 上期所 按成交量 3 0 锡 SN 上期所 按成交量 3 0 橡胶 RU 上期所 按成交额 0.00045 0.00045 线材 WR 上期所 按成交额 0.00004 0.00004 螺纹钢 RB 上期所 按成交额 0.000045 0 燃油 FU 上期所 按成交额 0.00002 0.00002 金 AU 上期所 按成交量 10 0 铜 CU 上期所 按成交额 0.000025 0 银 AG 上期所 按成交额 0.00005 0 铅 PB 上期所 按成交额 0.00004 0 镍 NI 上期所 按成交量 6 0 热轧卷板 HC 上期所 按成交额 0.00004 0 锌 ZN 上期所 按成交量 3 0 沥青 BU 上期所 按成交额 0.00005 0 纸浆 SP 上期所 按成交额 0.00005 0 不锈钢 SS 上期所 按成交额 0.00001 0 原油 SC 上海国际能源交易中心 按成交量 20 0 20 号胶 NR 上海国际能源交易中心 按成交量 10 10 棕榈油 P 大商所 按成交量 2.5 0 细木工板 BB 大商所 按成交额 0.0001 0.00005 鸡蛋 JD 大商所 按成交额 0.00015 0.00015 焦炭 J 大商所 按成交额 0.00006 0.00003 聚乙烯 L 大商所 按成交量 2 0 聚丙烯 PP 大商所 按成交额 0.00005 0.00025 铁矿石 I 大商所 按成交额 0.00006 0.00003 豆粕 M 大商所 按成交量 1.5 0 玉米 C 大商所 按成交量 1.2 0 焦煤 JM 大商所 按成交额 0.00006 0.00003 中密度纤维板 FB 大商所 按成交额 0.0001 0.00005 玉米淀粉 CS 大商所 按成交量 1.5 0 豆一 A 大商所 按成交量 2 0 豆二 B 大商所 按成交量 2 2 聚氯乙烯 V 大商所 按成交量 2 0 豆油 Y 大商所 按成交量 2.5 0 乙二醇 EG 大商所 按成交量 4 0 粳米 RR 大商所 按成交量 4 0 苯乙烯 EB 大商所 按成交量 6 0 锰硅 SM 郑商所 按成交量 3 0 白糖 SR 郑商所 按成交量 3 0 菜籽粕 RM 郑商所 按成交量 1.5 0 油菜籽 RS 郑商所 按成交量 2 0 早籼稻 RI(ER) 郑商所 按成交量 2.5 2.5 TA 郑商所 按成交量 3 3 动力煤 ZC(TC) 郑商所 按成交量 4 0 晚籼稻 LR 郑商所 按成交量 3 0 甲醇 MA(ME) 郑商所 按成交量 1.4 0 粳稻谷 JR 郑商所 按成交量 3 3 硅铁 SF 郑商所 按成交量 3 0 菜籽油 OI(RO) 郑商所 按成交量 2.5 0 棉花 CF 郑商所 按成交量 4.3 0 玻璃 FG 郑商所 按成交量 3 0 普麦 PM 郑商所 按成交量 5 5 强麦 WH(WS) 郑商所 按成交量 2.5 0 棉纱 CY 郑商所 按成交量 4 0 苹果 AP 郑商所 按成交量 1.5 0 红枣 CJ 郑商所 按成交量 3 0 尿素 UR 郑商所 按成交量 5 5 纯碱 SA 郑商所 按成交量 3.5 3.5 沪深 300IF 中金所 按成交额 0.000023 0.0023 中证 500IC 中金所 按成交额 0.000023 0.0023 上证 50IH 中金所 按成交额 0.000023 0.0023 5 年期国债 TF 中金所 按成交量 3 0 10 年期国债 T 中金所 按成交量 3 0 2 年期国债 TS 中金所 按成交量 8 0 生猪 LH 大商所 按成交额 0.0002 0.0004 花生 PK 郑商所 按成交量 4 4
备注
系统支持在策略代码中按照期货合约品种自定义佣金费率和平今费率(此设置在模拟交易中同样生效):
__config__ = {
"base": {
"future_info": {
# 期货品种
"SC": {
# 平仓费率
"close_commission_ratio": 0.0001,
# 开仓费率
"open_commission_ratio": 0.0002,
# 平今费率
"close_commission_today_ratio": 0,
# BY_MONEY 为按照名义价值收取, BY_VOLUME 为根据成交合约张数收取
"commission_type": "BY_MONEY",
}
}
}
}
- 中国期权交易费用
期权交易费用收取方式和期货类似,初始默认费率表如下请参考:
品种 交易所 佣金类型 回测佣金费率 回测平今费率 白砂糖 SR 郑商所 按成交量 3 0 棉花 CF 郑商所 按成交量 3 0 菜籽粕 RM 郑商所 按成交量 0.8 0 甲醇 MA 郑商所 按成交量 0.8 0 精对苯二甲酸 TA 郑商所 按成交量 1 0 铜 CU 上期所 按成交量 10 0 橡胶 RU 上期所 按成交量 6 0 黄金 AU 上期所 按成交量 4 0 豆粕 M 大商所 按成交量 2 1 黄玉米 C 大商所 按成交量 1.2 1.2 铁矿石 I 大商所 按成交量 4 4 液化石油气 PG 大商所 按成交量 1 1 上证 50ETF 上交所 按成交量 12 12 沪深 300ETF 上交所 按成交量 12 12 沪深 300ETF 深交所 按成交量 12 12 300 股指 IO 中金所 按成交量 18 18
- 上金所现货交易费用
交易费用参考上金所交易条款,初始默认费率,如下请参考:
合约代码 佣金类型 佣金费率 PT9995.SGEX 按成交额 0.04% IAU995.SGEX 按成交额 0.035% AU995.SGEX 按成交额 0.035% AU9995.SGEX 按成交额 0.035% IAU100G.SGEX 按成交额 0.035% IAU9999.SGEX 按成交额 0.035% AU100G.SGEX 按成交额 0.035% AU9999.SGEX 按成交额 0.035% PGC30G.SGEX 按成交额 0.035% AU50G.SGEX 按成交额 0.035% AG9999.SGEX 按成交额 0.02% AG999.SGEX 按成交额 0.02% AGTD.SGEX 按成交额 0.02% AUTN1.SGEX 按成交额 0.02% AUTD.SGEX 按成交额 0.02% AUTN2.SGEX 按成交额 0.02% MAUTD.SGEX 按成交额 0.02%
# 撮合机制
在最新的版本中,我们加入了允许用户自定义撮合机制的功能。您可以在策略编辑页面"更多"选项下选择不同的撮合机制。目前提供的撮合方式有以下三种:
1.当前收盘价。即当前 bar 发单,以当前 bar 收盘价作为参考价撮合。
2.下一开盘价。即当前 bar 发单,以下一 bar 开盘价作为参考价撮合
3.已方最优。tick 回测专用[仅限期货],市价单将以己方最优报盘价格成交(无己方报盘时以最新价成交)。
4.对手方最优。tick 回测专用[仅限期货], 以发单时下一个 tick 对手方最优报盘价格作为参考价撮合成交(无对手盘时以最新价作为参考价)。
5.最新价。tick 回测专用, 市价单将以最新价成交
一个完整的撮合机制需要包括两个方面:参考价与投资者在下单时的委托方式。投资者可以选择的委托方式包括有限价单和市价单。
限价单(LimitOrder)如果买单价格>=参考价,或卖单价格<=参考价,以参考价加入滑点影响成交。市价单(MarketOrder)直接以参考价加入滑点影响成交。
对于分钟回测与日回测来说,默认成交数量都不超过当前 bar 成交量的 25%。一旦超过,市价单会在部分成交之后被自动撤单;限价单会一直在订单队列中等待下一个 bar 数据撮合成交,直到当日收盘。当日收盘后,所有未成交限价单都将被系统自动撤单。您可以在策略编辑页面"更多"选项下进行是否开启限制成交量,以及开启之后成交百分比的设置。对于 tick 回测来说则没有成交量的限制。
当前收盘价:在一个
handelbar
内下单,下单时立刻撮合成交,成交价取决于撮合机制以及滑点设置。下一开盘价:在一个
handle_bar
内下单,在该 handle_bar 结束时统一撮合成交,成交价取决于撮合机制以及滑点设置(分钟回测支持,日回测不支持)。对手方最优/己方最优/ 最新价:在一个
handle_tick
内下单,在该 handle_tick 结束时统一撮合成交(成交价取决于撮合机制以及滑点设置)。
所以在“下一开盘价”的撮合方式下,handle_bar
内发单之后立刻通过cancel_order
对该订单进行撤单操作,是一定会撤单成功的。但在“当前收盘价”的撮合方式下则很可能撤单失败,因为“当前收盘价”中下单之后立刻撮合成交。
需要注意
- 如果需要当前 bar 开盘成交,可以使用open_auctionAPI 在盘前集合竞价时发单,以当日开盘价撮合。
- 在当前的分钟回测撮合模式下,用户在回测中无法通过在scheduler调用的函数中一次性实现 卖出 -> 资金释放 -> 买入 这种先卖后买的逻辑的。因为在分钟回测中,卖出并不能立刻成交。
举例来说,策略 A 设置每周一开盘进行调仓操作,先卖后买。那么,以下这种方式在分钟回测中无法实现卖出资金立刻释放的(在开启验资的风控情况下,可能导致后面的买入操作因资金不足而拒单):
#scheduler调用的函数需要包括context, bar_dict两个参数
def rebalance(context, bar_dict):
order_shares('000001.XSHE', -100)
order_shares('601998.XSHG', 100)
def init(context):
scheduler.run_weekly(rebalance, weekday=1)
有如下几种情况无法完成下单:
- portfolio 内可用资金不足
- 下单数量不足一手(股票为 100 股)
- 下单价格超过当日涨跌停板限制
- 当前可卖(可平)仓位不足
- 股票当日停牌
- 合约已经退市(到期)或尚未上市
另外需要注意的是,如果当时市场处于涨停或跌停这种单边市情况,买单(对应涨停),卖单(对应跌停)是无法成交的。尽管 bar 数据中可能成交量不为 0.判断单边市的标准我们采用的是:当前 bar 数据的收盘价等于涨停价,则当前市场处于涨停状态。跌停也是类似处理。
# 滑点
为了更好模拟实际交易中订单对市场的冲击,我们引入滑点的设置。您可以在策略编辑页面"更多"选项下进行滑点设置,该设置将在一定程度上使最后的成交价"恶化",也就是买得更贵,卖得更便宜。目前支持的滑点类型有百分比和跳/手,百分比:按照成交价的一定比例进行恶化, 取值范围 [0, 1),例如,当股票市价为 10 元,参数设为 0.1,则回测时买入价为 10 + 10 * 0.1 = 11 元; 跳/手:按照最小价格变动单位对成交价进行恶化,例如,上例中设置值为 5, 最终成交价将变成 10.05
注意,滑点默认为 0,原有的默认 0.246%的滑点值以及通过 context.slippage 设置的方式被废弃。
# 性能分析
开启该功能之后,策略回测完毕将会在回测详情页面的"性能分析"选项卡下查看策略运行性能报告。需要注意的是,开启该功能将会导致策略运行效率的下降。
# 分红派息
- 拆分(送股、增股)
在回测中您无须担心拆分对股票价格带来的影响因为我们已经在数据的预处理中准确地帮你做了这个工作。
- 股息
在股息事件中有四个关键的日期:
1.方案实施公告日 :公司公布股息分配方案的日期。
2.股权登记日 :在股权登记日这一天收盘时仍持有或买进该公司的股票的投资者可以享有此次股息分红。
3.除权除息日 :股权登记日的下一个交易日即是除权除息日,该日证券交易所会计算出股票的除权除息价,以作为投资者在除权除息日开盘的参考。
4.股息到帐日 :现金股息划拨到投资者资金账户的日期。
当您的投资策略在股权登记日时仍持有分股息的股票,那么您的投资策略将有资格参与此次股息分红。在除权除息日结束的时候您投资组合中的 DividendRecivable 会增加对应持有股票的股息分红数目。然后在股息到帐日那天 DividendRecivable 将会被搬入投资组合中的 AvailableCash - 您最终拿到了应收股息分红的金额,并且可以用这笔钱进行再投资了。
# 分红再投资
红利再投资俗称利滚利,是指基金进行现金分红时,基金持有人将分红所得的现金以当天基金价格直接用于购买该基金,增加原先持有基金的份额。
开启该功能以后,基金分红将按照当日净值折算成基金份额。
# 仓位管理
在交易中国 A 股市场证券时引入了 T+1 机制,当日买入的股票需要在下一日才能够卖出。另外,如果持有仓位的股票已经退市,那么系统会自动将仓位清零。此时,投资组合价值将会出现"跳水";如果持有期货直到到期,那么会按照到期日的结算价进行现金交割。
另外,所有仓位均会在当天收盘之后进行统一清理,被平掉的仓位不会出现在下一交易日初始的持仓中。但在日内,存在持仓为 0 的仓位记录(它还记录了该仓位的建仓价格、累计盈亏等信息,具体请参考仓位信息)。
# 日志功能
通常可以通过日志来了解程序的行为,或者用日志类解决程序中暗藏的问题。同样的,您也可以在您的策略中通过日志来协助开发与调试策略。
譬如,您希望在第一个交易日打印一条日志,把这一天发单的情况打印出来。为了实现这一功能,您只需如下图所示在代码中调用日志类即可:
需要注意,回测中系统只会保存开始的 10000 条记录,多出的信息将无法被保存。在实盘模拟中,每天的日志上限是 1000 条。
# 标的品种
支持股票、期货、期权、可转债、场内基金合约的日/分钟/tick 级别的回测,上金所现货日级别回测。不同品种的标的在发单接口、费用计算、账户和仓位计算等方面有所差异。
# 股票和场内基金
支持 A 股和 ETF、LOF 等场内基金回测
- 发单接口:股票和场内基金支持 order_shares、order_lots、order_value、order_percent、order_target_value、order_target_percent 六个下单接口。
- 账户设置:股票和场内基金的持仓归属于股票(STOCK)账户
- T+1:股票交易默认开启 T+1 限制,详细介绍见仓位管理
# 期货
支持期货回测
- 发单接口:不同于股票,期货可使用buy_open、sell_close、sell_open 和 buy_close四个接口发单。
- 账户设置:期货持仓归属于期货(FUTURE)账户
- 保证金交易:期货采用保证金交易,持有期货仓位会占用保证金,这部分资金会被冻结,不能再用于发单,保证金会在平仓时解冻。
- 使用的保证金率可以通过
instruments
接口查看,该接口接收合约代码参数,返回Instrument
对象,例如使用如下代码查询 RB2010 的保证金率:instruments("RB2010").margin_rate
- 可以通过设置保证金倍率来调整的保证金率,实际使用的保证金率为默认的保证金率乘以保证金倍率
- 使用的保证金率可以通过
- 逐日盯市:期货采用“逐日盯市”制度,每日盘后会进行结算,将浮盈浮亏计入现金。
# 期权
支持商品、股指、ETF 期权回测(需开通量化企业版)。
发单接口:交易期权使用与期货相同的发单接口buy_open、sell_close、sell_open 和 buy_close。
账户设置:根据实际市场中所在交易所不同,期权持仓分属股票(STOCK)和期货(FUTURE)账户,其中 ETF 期权属于股票账户,商品期权和股指期权属于期货账户。
行权
- 行权采用现金交割,即将行权产生的盈利或亏损直接计入现金中。
- 主动行权:期权可通过 exercise 接口主动行权,该函数接收合约代码和行权数量两个参数,例如:
exercise("M1905C2350", 2)
- 被动行权:期权持有至到期日将会触发自动行权。对于权利方(多头)持仓,若回测引擎判定行权可以盈利,则触发自动行权,否则仓位作废;而义务方(空头)持仓会在判定对手方可以盈利时触发行权
权利金和保证金
- 权利方(多头):开仓需要缴纳权利金,该过程与股票的开仓类似
- 义务方(空头):开仓会收取权利金并付出保证金,保证金会被冻结(类似期货开仓);同时义务方也采取逐日盯市制度,每日盘后结算,浮盈浮亏将被计入现金。
支持的期权合约代码规则见期权数据相关
# 可转债
支持可转换债券、场内公开交易的可交换债券、分离交易可转债(债券等)的回测(需开通量化企业版)。
- 发单接口:可转债使用 order_shares、order_value、order_percent、order_target_value、order_target_percent 五个接口下单,用法与股票相同
- 账户设置:可转债持仓归属于股票(STOCK)账户
- 回售和转股:可转债支持主动发起回售或转股,使用 exercise 接口,相比于期权行权,除了合约代码和数量两个参数,还加入了第三个参数用于区分本次行权是转股还是回售,如:
exercise("132003.XSHG", 100, convert=False) # 回售 exercise("132003.XSHG", 100, convert=True) # 转股
- 本息偿付:可转债发生付息时,利息将进入对应账户的现金;发生强制赎回时,仓位将被清空,对应账户的现金会按照强赎时实际的现金流变动。
# 上金所现货
支持上海黄金交易所交易的黄金、白银、铂金等现货合约的回测(需开通量化企业版)。
- 发单接口:与期货交易相同,上金所现合约货使用 buy_open、sell_close、sell_open 和 buy_close四个接口下单。
- 账户设置:上金所现货合约持仓归属于股票(STOCK)账户。
- 保证金交易:与期货类似,上金所现货合约采用保证金交易,同样可以配置保证金倍率,同样采用“逐日盯市”制度。
# 股票自动搜索及补全
- Windows 用户 : 输入ctrl + i
- Mac 用户 :输入command + i
- Linux 用户 :输入ctrl + i
当您输入了这个组合键之后,Ricequant 在线 IDE 就会进入股票代码搜索和自动完成模式,接着您可以输入任何一种进行搜索和自动补全:
股票数字代码 - 自动补全为股票数字代码,比如**"000024.XSHE"**:
股票中文全称 - 自动补全为股票中文全称,比如**"招商地产"**
股票拼音缩写 - 这里比较特殊,自动补全为股票中文全称,因为股票拼音缩写并不是独一无二的,比如 ZSDC 补全为**"招商地产"**
# 股票与期货混合策略注意事项
鉴于不同合约交易时间的不同(例如股票没有夜间交易,期货一些品种有夜盘交易),您在编写策略的时候需要注意策略的有效运行时间。比如在 2015 年 12 月之前,中金所股指期货的交易时间段是 09:15~11:30, 13:00~15:15,比 A 股市场多出了 30 分钟。在这个时候进行混合回测的时候就需要通过订阅的方式让策略引擎'知道'handle_bar 是要在每天 09:16 产生第一个 bar 数据,而不是股票的 09:31。
如果您创建的是单一的期货策略,则必须在策略初始化的时候订阅(subscribe)有效期货合约。由于期货有到期日,所以您需要保证在回测期间,始终都有正在交易的合约被订阅。
混合策略的股票、期货子账户信息可以分别通过context.stock_account以及context.future_account获取到。
# 向导式策略生成器
# 创建向导式策略
您可以通过在'我的策略'下点击'向导式策略生成器'来通过向导式生成策略,如下图:
# 选股设置
您可以通过选股设置实现投资域的筛选,并利用各类指标设置选股条件,最后对选出的股票进行排序。界面如下图:
# 股票池设置
该部分不仅支持不同股票池的偏好设置,还支持板块、行业、ST 股这三个细分投资域的偏好设置。
股票池选择 默认值 选项性质 选项范围 选择股票池 全市场 单选 全市场(全部 A 股市场)、沪深 300、上证 50、中证 500 板块 全部 多选 全部(所有板块)、主板、中小板、创业板 行业 全部 多选 中信一级行业,包括农林牧渔、采掘、化工、钢铁等 ST 股票 包含 ST 单选 包含 ST、过滤 ST、仅包含 ST
# 选股指标
界面左边是米筐提供的所有指标的展示区域,右边是您所选择指标的设置区域。基于购物车理念,您可以更加方便地对您选择的指标进行参数调整,界面如下图:
您可以通过点击选择指标,所选出的指标会右边“我的指标”中展示,并进行相应的设置。选股指标包含五个分类,具体详情如下:
分类 类别详情 行情 开盘价、收盘价、最高价、最低价、成交量、成交额、换手率、上市天数 技术指标 MA、MACD、KDJ、CCI、WILLR、ATR、ROC、TRIX、RSI、MFI、阿隆指标、布林线等 财务指标 估值类、盈利能力类、偿债能力类、营运能力类、成长能力类等 财务数据 营业收入类、营业支出类、收益利润类、资产类、负债类、权益类、经营现金流、投资现金流、筹资现金流等 形态指标 两只乌鸦、三只乌鸦、三胞胎乌鸦、红三兵、锤头、倒锤头、乌云盖顶、晨星、黄昏之星等
其中,财务指标与财务数据的差异为,财务数据是原始数据,财务指标是基于财务数据得到的指标。
# 排序指标
可用于排序的指标有四类,分别为行情指标、技术指标、财务指标、财务数据,比选股因子少了形态指标。
# 选股条件
您可以利用选股指标对股票池粗筛选出的股票进一步进行筛选。您可在选股条件部分对选股指标的数值范围进行设置,如下图:
您可以在该部分进行如下功能的设置:
分类 支持选项 行情 大于、小于、区间、排名%区间(默认升序)、大于 N 日均值、小于 N 日均值、介于 N1,N2 均值间 技术指标 大于、小于、区间、金叉、死叉、多头、空头、价格多头、价格多头 财务指标 大于、小于、区间、排名%区间(默认升序) 财务数据 大于、小于、区间、排名%区间(默认升序) 形态指标 无选项
其中,对于技术指标,您可基于自己的偏好调整其对应的参数。
# 自定义规则
为了支持更多个性化规则,您也可以点击“添加自定义规则”,通过比对两个指标的数值大小,筛选出符合您条件的股票。
# 排序条件
对于您筛选出的股票,您可以从排序指标中选出用于排序的指标,在排序条件部分对所选指标进行升序或降序的处理,并赋予不同的权重,从而实现对股票的排序。对于技术指标,您可以对其参数进行偏好设置。如下图:
# 模型选择
您可以在模型选择中设置您策略所需要的模型,米筐提供两种模型,分别为定期轮动、条件触发。
# 定期轮动
定期轮动为定期调仓交易模型,您可以基于选出的股票,设置调仓周期、最大持仓股票数量。该模型会定期在调仓日卖出不符合选股条件的股票,等权买入符合条件的股票。界面如下图:
# 条件触发
对于条件触发模型,您可以设置买入条件、卖出条件。界面如下:
区别于定期轮动模型,条件触发模型将调仓周期分为了三个周期,分别为选股周期、买入周期、卖出周期。
- 选股周期:该周期决定多少个交易日执行一次选股操作,即筛选出满足选股设置里选股条件的股票并按排序条件对其排序。一般用财务指标实现股票池的筛选,由于企业财务指标大多属于季度更新,故该周期可以设置长一些。
- 买入周期:该周期决定多少个交易日执行一次买入操作,即买入满足买入条件的股票。买入条件中一般用于技术指标、形态指标等比较难以捕捉的信号的捕捉,故买入周期可以设置短一些。
- 卖出周期:该周期决定多少个交易日执行一次卖出操作,即卖出满足卖出条件的股票。
买入条件:
您可以在买入条件设置选股周期、买入周期、最大持仓股票数、个股最大持仓比重,同时可以通过对行情、技术指标、财务指标、财务数据、形态指标设置买入条件。这部分提供的指标及指标设置情况可参考选股指标、选股条件。
卖出条件:
您可以在卖出条件设置卖出周期,同时也可设置行情、技术指标、财务指标、财务数据、形态指标。这部分提供的指标及指标设置情况可参考选股指标、选股条件。
# 风险控制
您可以在“风险控制”部分对策略的风险进行设置。风险控制支持对止盈止损、大盘择时(开仓)、大盘择时(平仓)的设置。如下图:
风控名称 作用阶段 可选指标 止盈止损 股票的卖出 个股止损、个股止盈、持仓价值止损、持仓价值止盈、策略最大亏损、策略最大盈利 大盘择时(开仓) 股票的买入 大盘指数的各类指标,包括行情、涨跌幅、技术指标 大盘择时(平仓) 股票的卖出 大盘指数的各类指标,包括行情、涨跌幅、技术指标
风险控制可以实现对用户策略的整个过程风险的全面控制。在开仓前,可以通过大盘择时来判断是否买入;在买入后,可以通过止盈止损和大盘择时(平仓)实现事后风控。
# 回测设置
您可以在“策略回测”部分对回测的参数进行相应的设置,如下图所示:
可以设置的参数如下:
参数名 解释 开始日期 回测期间的开始日期 结束日期 回测期间的结束日期 - 如果回测结束日期在今天之后,将会自动使用最后一天的历史数据 调仓周期 回测期间的调仓周期,可根据偏好进行设置 - 默认收盘后进行相应的调仓 起始资金 回测的起始资金 - 您将使用多少钱去投资策略 基准合约 设置策略表现的对照基准
在设置完回测参数之后,可通过‘保存'按钮来保存您的所有设置;点击"运行回测"将会带您进入完整的回测结果页面,您可以查看更加详细的策略回测分析结果,帮助您对策略的表现实现更细致的评估。
# 回测结果分析
# 回测结果
当回测运行没有出错,回测结果页面将会载入您的投资组合的各种交易、盈亏和风险信息。
下图是回测结果的介绍:
收益概览:展示策略的风险调整收益(Sharpe, InformationRatio 等)、回测收益图、每日盈亏图以及成交记录图。您自己通过plot画图结果也会在该页面展示
交易详情:展示回测期的历史交易记录,包括成交时间、成交价、费用等信息
每日持仓:展示回测期的仓位信息,包括建仓成本、累计盈亏等信息
账户信息:展示回测期的账户信息,包括账户总权益、可用资金、当日盈亏、累计盈亏等信息
输出日志:您在策略中通过 print 或者打印日志的方式输出的信息都在这里展示。需要注意,回测最多保存最新 10000 条日志记录
性能分析:前端勾选性能分析后,策略回测完毕将会展示策略运行性能报告
# 收益指标
回测收益率: 策略在期限内的收益率。
年化收益率: 采用了复利累积的年化方式计算得到的年化收益。
基准收益率: 相同条件下,一个简单的买入并持有基准合约策略的收益率(默认基准合约为沪深 300 指数,这里假设指数可交易,最小交易单位为 1)。
每日收益率: 通过投资组合权益计算出的日收益率。
阿尔法(alpha,): CAPM模型表达式中的残余项。表示策略所持有投资组合的收益中和市场整体收益无关的部分,是策略选股能力的度量。当策略所选股票的总体表现优于市场基准组合成分股时,阿尔法取正值;反之取负值。
其中为策略所持有投资组合收益;为无风险组合收益;为 CAPM 模型中的贝塔系数;表示随机变量的期望。
# 风险指标
年化波动率(volatility,): 策略收益率的标准差,最常用的风险度量。波动率越大,策略承担的风险越高。这里假设一年有 252 个交易日。
其中,为回测期内交易日数目;表示第 i 个交易日策略所持有投资组合的日收益率;为回测期内策略日收益率的均值。
年化跟踪误差(tracking error,): 纯多头主动交易策略(阿尔法策略和基准择时策略)收益和市场基准组合收益之间差异的度量。跟踪误差越大,意味着策略所持有投资组合偏离基准组合的程度越大。需要注意,跟踪误差不适用于多-空结合的对冲策略的风险评估。
其中,为回测期内交易日数量;,,分别表示第 i 个交易日策略所持有投资组合的日主动收益、日收益率和基准组合的日收益率。
年化下行波动率(downside risk,): 相比波动率,下行波动率对收益向下波动和向上波动两种情况做出了区分,并认为只有收益向下波动才意味着风险。在实际计算中,我们统一使用无风险组合收益为目标收益,作为向上波动和向下波动的判断标准。
其中,为回测期内交易日数量;,分别表示第 i 个交易日策略所持有投资组合的日收益率、无风险组合的日收益率;为指示函数(indicator function),如果第 i 个交易日策略所持有投资组合收益低于无风险组合收益,则标记为 1(向下波动),否则标记为 0(向上波动)。
贝塔(beta,): CAPM 模型中市场基准组合项的系数,表示资产收益对市场整体收益波动的敏感程度。
其中为策略收益率;为市场基准组合收益率;表示协方差;表示方差
Beta 值 解释 举例 < 0 投资组合和指数基准的走向通常反方向 反向指数 ETF 或空头头寸 = 0 投资组合和指数基准的走向没有相关性 固定收益产品,他们的走向通常和股市不相关 0 << 1 投资组合和指数基准的走向相同,但是比指数基准的移动幅度更小 稳定的股票,比如制作肥皂的公司的股票,通常和市场的走势相同,但是受到每日的波动影响更小 = 1 投资组合和指数基准的走向相同,并且和指数基准的移动幅度贴近 蓝筹股,指数中占比重大的股票 > 1 投资组合和指数基准的走向相同,但是比指数基准的移动幅度更大 受每日市场消息或是受经济情况影响很大的股票
最大回撤(max drawdown): 在回测期内,在任一交易日往后推,策略总权益走到最低点时收益率回撤幅度的最大值。最大回撤是评估策略极端风险管理能力的重要指标。其计算方式如下:
# 风险调整后收益指标
夏普率(sharpe ratio): 衡量策略相对于无风险组合的表现,是策略所获得风险溢价的度量——即如果策略额外承担一单位的风险,可以获得多少单位的收益作为补偿。
其中为回测期内策略日超额收益率均值;为回测期内交易日数目;分别为第 i 个交易日策略所持有投资组合的日收益率以及无风险组合日收益率;为策略超额收益率的波动率。
索提诺比率(sortino ratio): 衡量策略相对于目标收益的表现。其使用下行波动率作为风险度量,因此区别于夏普率。在目前的计算中,我们使用无风险组合收益作为目标收益,以此作为区分向上波动和向下波动的标准。
其中为回测期内策略日超额收益率均值;为回测期内交易日数目;分别为第 i 个交易日策略所持有投资组合的日收益率以及无风险组合日收益率;为策略年化下行波动率。
信息比率(information ratio): 衡量策略相对于市场基准组合的表现。一般用于评估纯多头的主动交易策略(包括阿尔法策略和基准择时策略)。需要注意的是,信息率不适用于多-空结合的对冲策略的表现评估。
其中为回测期主动日收益率均值;为回测期内交易日数目;分别为第 i 个交易日策略所持有投资组合的日收益率以及基准组合日收益率;为策略跟踪误差。
在我们提供的三个风险调整后收益指标中,信息率用于评估投资组合相对于市场基准组合的表现,一般适用于纯多头的主动交易策略(包括阿尔法策略和基准择时策略);夏普率用于评估投资组合相对于无风险组合的表现,一般适用于多-空结合的交易策略(例如市场中性策略或配对交易策略),或没有公认市场基准组合的投资品种的交易策略(例如期货 CTA 策略)。
索提诺比率使用下行波动率作为风险度量,因而有别于信息率和夏普率。下行波动率区分了收益向上波动和向下波动两种情况,并认为收益向下波动才代表风险。因此,索提诺比率的优点,在于其使用的风险度量更为切合我们实际投资中面对的风险;而其缺点则是不如信息率和夏普率常用,认知度较低,且其目标收益(区分收益波动是向上还是向下的标准)的设定是任意的,并不依赖于任何基准组合(不同于信息比率)。因此,在横向对比不同策略或基金业绩时,我们需要使用统一的目标收益来区分向上波动和向下波动。在实际计算中,我们以无风险组合收益作为索提诺比率的目标收益。