SQN指数,与量化交易的圣杯:TopQ极宽bakctrader课件系列

SQN指数,与量化交易的圣杯:TopQ极宽bakctrader课件系列

圣杯(San-greal)是在公元33年,犹太历尼散月十四日,也就是耶稣受难前的逾越节晚餐上,耶稣遣走加略人犹大后和11个门徒所使用的一个葡萄酒杯子。
耶稣曾经拿起这个杯子吩咐门徒喝下里面象征他的血的红葡萄酒,借此创立了受难纪念仪式。后来有些人认为这个杯子因为这个特殊的场合而具有某种神奇的能力。相传彼世安温的魔法炉则是圣杯的前身。
很多传说相信,如果能找到这个圣杯而喝下其盛过的水就将返老还童、死而复生并且获得永生,这个传说广泛延续到很多文学、影视、游戏等作品中。
近年来,量化交易异军崛起,很多金融专家,AI人工智能团队,都在寻找传说中的圣杯。
金融量化,简而言之,不过是人工智能,数据分析技术,在金融行业,对于各种交易大数据的精密分析。
数字世界,一切靠数字说话。
传说中的圣杯,虽然还没找到。
金融专家Van Tharp,很早就提出一个非常重要的指数:即SQN指数。
这是一个量化策略的圣杯评判指数,可以用来衡量交易系统好坏程度的指数。
SQN指数,全称是:System Quality Number,系统质量指数,其计算公式很简单:
            SQN = ( 平均获利 / 标準差 )* 一年交易次数的平方根 ( 以 100 为上限 )
当交易数量>=30时,sqn指数,通常被认为是可靠的。
SQN指数,评判标准如下:
  • 1.6–1.9    Poor but tradable 不怎么样,可以凑合用
  • 2.0–2.4    Average 普通
  • 2.5–2.9   Good 好
  • 3.0–5.0   Excellent 杰出
  • 5.0–6.9   Superb 一流
  • 7.0-   Holy Grail 圣杯
SQN指数具有如下意义:
交易次数越多,获利机会越大。风险回报比越大越好。
风险回报比的标准差越小,交易结果越规律,回撤越小。
SQN指数的含义很显然,如果你要优化SQN指数,需要做的事请
包括:
使交易次数和平均风险回报比的乘积尽可能大;
使公式中的标准差尽可能小。

 


(本文摘自TopQuant.vip极宽量化培训课件2019系列)

backtreader量化软件当中,计算SQN指数,非常简单,只需要一个带SQN参数的addanalyzer通用分析函数:,

cerebro.addanalyzer(SQN,_name=’sqnAnz’)
cerebro是西班牙语“大脑”的意思,因为backtreader量化软件,开发团队主要是西班牙人。
addanalyzer通用分析函数,不光可以分析SQN指数,还可以分析常用的:SharpeRatio夏普指数,max_drowdown最大回撤参数 、AnnualReturn年化收益率,Trade交易分析报告等。
以下是针对最简单的MA均线策略进行的回测分析,数据使用的是A股当中代码:002046的股票,时间周期是2010.1月-2018.12月。
ps,选择002046股票代码,原因很简单,就是因为《2046》。王家卫、 梁朝伟、巩俐、王菲、木村拓哉、张曼玉、章子怡、刘嘉玲、张震,这么多专业级的大牌,还需要其他理由吗…
以下是回测曲线图:
输出信息比较长,其中和SQN指数相关的有:
SQN:
– sqn: 0.6551079074304348
– trades: 131
交易次数131次,SQN指数得分为0.65。
再看看投资回报:

#4,完成BT量化回溯运算
起始资金 Starting Portfolio Value: 100000.00
资产总值 Final Portfolio Value: 100049.16
利润总额: 49.16,
ROI投资回报率 Return on investment: 0.05 %

2010-2018,九年期间,10万投资,就赚了49元,

案例当中测试的是:最简单MA均线策略,参数周期是默认15天,也没有经过任何优化。
MA均线策略,看起来虽然有些垃圾,也很简单,不过考虑到2016,2017的几次超级大股灾,以及2018行业平均亏损20-30%的广大股民而言。
这个最简单的MA均线策略,总体上还算是表现不错的,属于保住了本金的那些少数幸运儿。

以下是其他部分输出数据,案例源码在文章最最后。

#8

#8-1,基本BT量化分析数据
夏普指数SharpeRatio : -36.40782970889061
最大回撤周期 max_drowdown_len : 1064
最大回撤 max_drowdown : 0.056098323568465475
最大回撤(资金)max_drowdown_money : 56.15616999994381

#8-2,常用量化分析数据
SQN指数、AnnualReturn年化收益率,Trade交易分析报告
可以通过修改参数,改为其他时间周期:周、月、季度等
===============================================================================
SQN:
– sqn: 0.6551079074304348
– trades: 131
===============================================================================
SharpeRatio:
– sharperatio: -36.40782970889061
===============================================================================
VWR:
– vwr: 0.005090450832663612
===============================================================================
AnnualReturn:
– 2010: 0.0002811820999994996
– 2011: -0.0001705094557934439
– 2012: 0.0001721233589053739
– 2013: -3.3483332015693534e-05
– 2014: 8.127973905480701e-06
– 2015: 0.0006680405434913439
– 2016: -0.000284659214648042
– 2017: 2.807501250545741e-05
– 2018: -0.00017706887861779208
===============================================================================
DrawDown:
– len: 448
– drawdown: 0.053900589786916614
– moneydown: 53.95616999993217
—————————————————————————–
– max:
– len: 1064
– drawdown: 0.056098323568465475
– moneydown: 56.15616999994381

 


 

核心策略函数

这个案例很简单,核心策略就是一个next函数:

  • 收盘价clsoe高于15天sma均线,BUY买入;
  • 收盘价clsoe低于15天sma均线,SELL卖出;

代码很简单,基本上每一行都有中文说明,方便初学者学习。

def next(self):
# next函数是最重要的trade交易(运算分析)函数,
# 调用log函数,输出BT回溯过程当中,工作节点数据包BAR,对应的close收盘价
self.log(‘当前收盘价Close, %.2f’ % self.dataclose[0])

# 检查订单执行情况,默认每次只能执行一张order订单交易,可以修改相关参数,进行调整
if self.order:
return

# 检查当前股票的仓位position
if not self.position:
# 如果该股票仓位为0 ,可以进行BUY买入操作,
# 这个仓位设置模式,也可以修改相关参数,进行调整

# 使用最简单的MA均线策略
if self.dataclose[0] > self.sma[0]:
# 如果当前close收盘价>当前的ma均价
# ma均线策略,买入信号成立:
# BUY, BUY, BUY!!!,买!买!买!使用默认参数交易:数量、佣金等
self.log(‘设置买单 BUY CREATE, %.2f, name : %s’ % (self.dataclose[0],self.datas[0]._name))

# 采用track模式,设置order订单,回避第二张订单2nd order,连续交易问题
self.order = self.buy()

else:
# 如果该股票仓位>0 ,可以进行SELL卖出操作,
# 这个仓位设置模式,也可以修改相关参数,进行调整
# 使用最简单的MA均线策略
if self.dataclose[0] < self.sma[0]:
# 如果当前close收盘价<当前的ma均价
# ma均线策略,卖出信号成立:
# 默认卖出该股票全部数额,使用默认参数交易:数量、佣金等
self.log(‘SELL CREATE, %.2f, name : %s’ % (self.dataclose[0],self.datas[0]._name))

# 采用track模式,设置order订单,回避第二张订单2nd order,连续交易问题
self.order = self.sell()

 

案例源码主程序

 

print(‘\n#1,设置BT量化回溯程序入口’)
cerebro = bt.Cerebro()

#
print(‘\n#2,设置BT回溯初始参数:起始资金等’)
dmoney0=100000.0
cerebro.broker.setcash(dmoney0)
dcash0=cerebro.broker.startingcash
#
#
print(‘\n\t#2-2,设置数据文件,数据文件,需要按时间字段,正序排序’)
rs0=’data/’
#
# 增加一个股票名称变量xcod,可以自策略函数内部使用
xcod=’002046′
fs0=xcod+’.csv’ #reverse=True
#
fdat=rs0+fs0
print(‘\t@数据文件名:’,fdat)

#
print(‘\t设置数据BT回溯运算:起始时间、结束时间’)
print(‘\t数据文件,可以是股票期货、外汇黄金、数字货币等交易数据’)
print(‘\t格式为:标准OHLC格式,可以是日线、分时数据。’)
t0str,t9str=’2010-01-01′,’2018-12-31′
data=tq.pools_get4fn(fdat,t0str,t9str)

#
# 增加一个股票名称变量xcod,可以在策略函数、绘图中使用
cerebro.adddata(data,name=xcod)
#
#
print(‘\n\t#2-3,添加BT量化回溯程序,对应的策略参数’)
print(‘\n\t# 案例当中,使用的是MA均线策略’)
cerebro.addstrategy(TQSta001)
#
print(‘\n\t#2-4,添加broker经纪人佣金,默认为:千一’)
cerebro.broker.setcommission(commission=0.001)
#
print(‘\n\t#2-5,设置每手交易数目为:10,不在使用默认值,默认是:1手’)
cerebro.addsizer(bt.sizers.FixedSize, stake=10)

print(‘\n\t#2-5,设置addanalyzer分析参数’)

#
cerebro.addanalyzer(SQN,_name=’sqnAnz’)
#
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name = ‘SharpeRatio’, legacyannual=True)
# 动态加权回报率 Variability-Weighted Return: Better SharpeRatio with Log Returns
cerebro.addanalyzer(bt.analyzers.VWR, _name=’VWR’)
#
cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name=’AnnualReturn’)
#
cerebro.addanalyzer(bt.analyzers.DrawDown, _name=’DW’)

#
print(‘\n#3,调用BT回溯入口程序,开始执行run量化回溯运算’)
results=cerebro.run()
#results= cerebro.run(runonce=False, exactbars=-2)

#
print(‘\n#4,完成BT量化回溯运算’)
dval9=cerebro.broker.getvalue()
dget=dval9-dcash0
kret=dget/dcash0*100
# 最终投资组合价值
print(‘\t起始资金 Starting Portfolio Value: %.2f’ % dcash0)
print(‘\t资产总值 Final Portfolio Value: %.2f’ % dval9)
print(‘\t利润总额: %.2f,’ % dget)
print(‘\tROI投资回报率 Return on investment: %.2f %%’ % kret)

#
#———
print(‘\n#8’)
strat =results[0]
anzs=strat.analyzers
#
dsharp=anzs.SharpeRatio.get_analysis()[‘sharperatio’]
#
dw=anzs.DW.get_analysis()
max_drowdown_len =dw[‘max’][‘len’]
max_drowdown =dw[‘max’][‘drawdown’]
max_drowdown_money =dw[‘max’][‘moneydown’]
#
print(‘\n#8-1,基本BT量化分析数据’)
print(‘\t夏普指数SharpeRatio : ‘,dsharp)
print(‘\t最大回撤周期 max_drowdown_len : ‘, max_drowdown_len)
print(‘\t最大回撤 max_drowdown : ‘, max_drowdown)
print(‘\t最大回撤(资金)max_drowdown_money : ‘, max_drowdown_money)
#
print(‘\n#8-2,常用量化分析数据’)
print(‘\tSQN指数、AnnualReturn年化收益率,Trade交易分析报告’)
print(‘\t可以通过修改参数,改为其他时间周期:周、月、季度等’)
for alyzer in strat.analyzers:
alyzer.print()

发表评论

电子邮件地址不会被公开。 必填项已用*标注