策略回测

宽易平台对于回测,模拟交易和实盘交易采用统一函数接口runStrat,以显著降低客户的学习成本和增加易用性。

对于第三方数据, 也同样可以使用runStrat函数作为统一接口,只要数据符合规范模式,也一样可以进行回测。

对于akshare股票数据,本章特别介绍了如何转化为我们需要的数据格式,以使得客户可以方便地在宽易平台回测股票相关的策略。

以下我们先按照标准接口函数讲解回测过程,然后提供一例akshare数据的示例,最后是runStrat函数的详细说明。

回测标准流程

先使用这个简单但是完整的策略,来开始宽易的回测交易之旅:

#导入函数库
from qereal import *
from qedata import *
import warnings
warnings.filterwarnings("ignore")

#编写回测交易策略
class mystrat(qeStratBase):
    def __init__(self):
        self.holding_flag = False    # 是否有仓位的标识
        self.instid = ['AG2112.SFE']
        self.datamode = 'daily'

    def onBar(self,context):
        try:    
            if not self.holding_flag: #如果现在账户中没有仓位,就买入
                make_order(context, instid=context.instid[0], direction=1, price=10000,\
                           volume=1,ordertype='market',action='open')  
                self.holding_flag = True #现在账户下有仓位
            else: #如果现在账户中有仓位,就卖出
                make_order(context, instid=context.instid[0],direction=-1, price=10000, \
                               volume=1, ordertype='market',action='close',closetype='closetoday')
                self.holding_flag = False #现在账户下仓位被清完
        except Exception as e:
            print('handleData error', e.__traceback__.tb_lineno, e)

    def crossDay(sellf, context):
        cancel_order(context, 0)

#调用执行historyDataBackTest函数并得到report数据
report = runStrat('scott','test',mystrat(),test_startdate='2021-01-08',test_enddate='2021-02-01',\
                  test_initcap=30000000)

这样,我们就成功运行了宽易的回测交易,我们可以发现开始回测交易只需要3步:

  1. 导入函数库
  2. 编写回测交易策略
  3. 调用执行runStrat函数

策略执行函数详细说明请参照统一策略运行函数

运行结果附图:

对于分钟级数据和tick级数据,回测结果会输出每次开平仓记录,每日统计和最终统计,红框中为最终统计内容。我们可以通过蓝色框中的链接查看回测报告。

布林带策略回测

下面我们来看一个真正实用的策略——布林带策略:

在这个策略里, 我们会根据历史价格和布林带上轨,中轨,下轨做出判断: 1.如果上一时间点价格高出五天布林带上轨, 则卖出 2.如果上一时间点价格低于五天布林带下轨, 则买入

首先引入必要的库

# 导入宽易函数库和相关需要的工具库
from qedata import *
from qereal import *
import talib
from talib import MA_Type
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import warnings
from datetime import datetime,timedelta
warnings.filterwarnings("ignore")

设置开始日期和结束日期

start_date = datetime.strptime('2021-01-08','%Y-%m-%d') ##起始日期
end_date =  datetime.strptime('2021-10-01','%Y-%m-%d') ##结束日期
instid = 'AG2112.SFE'  ##合约名称

这过程中需要引入talib.BBANDS函数来生成布林带信号,生成过程如下

#获取收盘价以计算布林带
df = get_price(instid, start_date, end_date, freq='daily')
#获取布林带数据
close =df.close.values
upper,middle,lower=talib.BBANDS(close,timeperiod=5, matype=MA_Type.T3)

plot一下布林带的图示效果

下面我们根据布林带构造一个策略,当突破上轨做空,突破下轨做多,回到中轨平仓。

布林带策略代码:

class mystrat(qeStratBase):
    def __init__(self):
        self.flippage = 1 ##设置模拟撮合交易市价单产生的滑点数
        self.traderate = 0.2 ##设置交易手数占市场交易量最大比例
        self.instid = ['AG2112.SFE'] ## 合约名是必填项
        self.name = 'Bollinger' ## 给策略取名
        self.datamode = 'daily' ## 日线bar策略
        self.dailyminutes = 5 ## 收盘提前5分钟产生日线bar

    def onBar(self, context):
        ## 获取当前日期
        curday = context.curtime.date()
        instid = self.instid[0]
        try:
            ## 获取开始时间到昨天的所有历史行情
            df1 = get_price(instid, start_date, curday-timedelta(days=1), 'daily')
            ## 获取当天收盘前的日bar数据
            df2 = context.getDailyData(instid)
            ## 拼接成一个DataFrame
            df = pd.concat([df1,df2],join='outer')
            ## 计算布林带上下轨
            close = df.close.values
            upper,middle,lower=talib.BBANDS(close,timeperiod=5, matype=MA_Type.T3)
            if not np.isnan(upper[-1]):
                 ## 若布林带数据非空
                if close[-1] < lower[-1]:
                    ##低于下轨,做多
                    make_order(context, instid, 1, close[-1], 1,'market',action='open')
                elif close[-1] > upper[-1]:
                    ##高于上轨,做空
                    make_order(context, instid,-1, close[-1], 1,'market',action='open')
                if close[-1] > middle[-1] and context.getAccountPosition(instid,'long','volume') > 0:
                    ##有多仓回到中轨以上,平多
                    make_order(context,  instid,-1, close[-1],context.getAccountPosition(instid,'long','volume'),\
                               'market',action='close',closetype='closetoday')
                if close[-1] < middle[-1] and context.getAccountPosition(instid,'short','volume') > 0:    
                    ##有空仓回到中轨一下,平空
                    make_order(context, instid,1, close[-1], context.getAccountPosition(instid,'short','volume'),\
                               'market',action='close',closetype='closetoday')        
        except Exception as e:
            print('handleData error', e.__traceback__.tb_lineno, e)

    def crossDay(sellf, context):
        ##撤掉所有未成交订单
        cancel_order(context, 0)

此时我们就可以开始回测了

#调用回测接口,初始资金30万
report = runStrat('scott','test',mystrat(),test_startdate=start_date+timedelta(30) ,test_enddate=end_date ,\
                              test_initcap=300000)

运行结果附图:

开平仓行情图:

盈亏图:

资金回撤图:

网页版回测结果分析

回测报告主要分为三部分:

1.统计指标(蓝色框) 2.列表(绿色框,查看成交,委托,统计的详情信息) 3.统计图(红色框,包含开平仓图,资金图和盈亏图通过tab切换)

统计指标

查看用户名,回报率,夏普比例等统计数据

统计图部分

主要分为开平仓图,资金图和盈亏图。

开平仓图

通过开平仓图,可以查看回测过程中的行情数据,开平仓数据和成交量。

可用操作
  1. 查看特定回测时刻的成交信息

    如果我们想查看特定时刻的交易信息,我们可以把鼠标放在特定时刻的交易点上,此时我们可以看到上图红框中的此刻的具体交易信息,比如具体的时间和行情价格等。

  2. 使用游标查看特定时间段的开平仓信息

    如果我们想查看特定时间段内的开平仓信息,我们可以左右滑动上图红框中的两个游标,选择我们想要查看的时间段。在选择完成后只会显示相应时间段的开平仓图。

资金图

通过资金图,我们可以查看回测过程中总资金,回撤和最大保证金的数据。

盈亏图

通过盈亏图,我们可以查看回测过程中日回报率,累积回报率,P&L和总费用的数据。

列表部分

列表部分主要包含成交表,委托表和统计表。

成交表

在成交表中我们可以查询所有成交单的具体信息,包含合约名,订单号,时间等。

委托表

在委托表中我们可以查询所有委托单的具体信息,包含合约名,订单号,平仓类型,价格等。

统计表

在统计表中,我们可以获得日收益率,回撤,最大保证金等数据。

页面切换

在成交表,委托表和日志表中,可能会有大量记录,此时表格会对数据自动分页,每页保留100条记录。通过下图红框中的按钮选择想要查看的页数。

回测图形化业绩评估

以布林带为例,后续的数据分析我们使用平台提供的回测绩效分析函数

注:做绩效评估要求数据至少半年以上,如果低于半年会报错。

示例代码:

reportPerformance(report)

分析结果:

                           Strategy    Benchmark
-------------------------  ----------  -----------
Start Period               2021-01-08  2021-01-08
End Period                 2021-09-30  2021-09-30
Risk-Free Rate             0.0%        0.0%
Time in Market             42.0%       99.0%

Cumulative Return          10.55%      -22.4%
CAGR﹪                     14.81%      -29.48%

Sharpe                     3.54        -1.14
Smart Sharpe               2.92        -0.94
Sortino                    7.94        -1.5
Smart Sortino              6.54        -1.24
Sortino/√2                 5.61        -1.06
Smart Sortino/√2           4.63        -0.88
Omega                      3.16        3.16

Max Drawdown               -1.2%       -24.84%
Longest DD Days            7           240
Volatility (ann.)          4.04%       28.04%
R^2                        0.0         0.0
Calmar                     12.39       -1.19
Skew                       1.64        -0.31
Kurtosis                   8.07        5.17

Expected Daily %           0.06%       -0.14%
Expected Monthly %         1.12%       -2.78%
Expected Yearly %          10.55%      -22.4%
Kelly Criterion            28.03%      -20.5%
Risk of Ruin               0.0%        0.0%
Daily Value-at-Risk        -0.36%      -3.03%
Expected Shortfall (cVaR)  -0.36%      -3.03%

Gain/Pain Ratio            2.16        -0.18
Gain/Pain (1M)             56.87       -0.62

Payoff Ratio               2.49        0.81
Profit Factor              3.16        0.82
Common Sense Ratio         11.0        0.72
CPC Index                  3.82        0.3
Tail Ratio                 3.48        0.88
Outlier Win Ratio          23.2        2.03
Outlier Loss Ratio         21.37       2.04

MTD                        -0.18%      -10.97%
3M                         2.54%       -15.4%
6M                         7.55%       -12.88%
YTD                        10.55%      -22.4%
1Y                         10.55%      -22.4%
3Y (ann.)                  14.81%      -29.48%
5Y (ann.)                  14.81%      -29.48%
10Y (ann.)                 14.81%      -29.48%
All-time (ann.)            14.81%      -29.48%

Best Day                   1.31%       7.71%
Worst Day                  -0.94%      -9.08%
Best Month                 2.53%       6.14%
Worst Month                -0.18%      -10.97%
Best Year                  10.55%      -22.4%
Worst Year                 10.55%      -22.4%

Avg. Drawdown              -0.2%       -16.96%
Avg. Drawdown Days         3           130
Recovery Factor            8.83        -0.9
Ulcer Index                0.0         0.12
Serenity Index             63.78       -0.19

Avg. Up Month              1.14%       3.19%
Avg. Down Month            -0.18%      -10.97%
Win Days %                 48.65%      46.02%
Win Month %                87.5%       44.44%
Win Quarter %              100.0%      33.33%
Win Year %                 100.0%      0.0%
Beta                       -0.0        -
Alpha                      0.14        -

Worst Drawdowns

Start Valley End Days Max Drawdown 99% Max Drawdown
1 2021-09-23 2021-09-30 2021-09-30 7 -1.195233 -0.581464
2 2021-03-04 2021-03-05 2021-03-08 4 -0.943414 -0.001359
3 2021-02-22 2021-02-23 2021-02-26 4 -0.648552 -0.390327
4 2021-03-30 2021-03-31 2021-04-02 3 -0.410575 -0.138638
5 2021-07-19 2021-07-20 2021-07-23 4 -0.235527 -0.148376

Strategy Visualization

回测数据指标分析

我们还可以使用平台提供的reportIndicators计算回测结果的一些关键指标,比如sharp比率等。

reportIndicators(report,riskfree=0)

结果如下

{'accret': 0.23522839455330163,
 'arr': 0.3239938264602079,
 'highwater': 1.2785476999999998,
 'maxdrawback': -0.041039004999999885,
 'avol': 0.1334835813413924,
 'winrate': 1.0,
 'odds': 1,
 'downrisk': 0.005791978629006393,
 'sharpratio': 2.2773874015466,
 'sortinoratio': 2.7472069784951394,
 'calmarratio': 7.407436570652937,
 'maxmarg': 55330.2}

比如winrate表示胜率, odds表示赔率, 各项指标具体解释参见回测报告指标计算函数

对冲策略回测

下面演示一个简单的近远月对冲策略,选择'AG2112.SFE' 和'AG2206.SFE'作为标的,对冲公司为 b/a(后者除以前者)

首先引入python库和宽易平台库

from qedata import *
from qereal import *
import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings("ignore")

策略的设计(详解解读见如何写策略)

##对冲策略设计
class hedgeStrat(qeStratBase):
    def __init__(self):
        self.instid =['AG2112.SFE','AG2206.SFE']
        self.datamode = 'minute' ## 分钟级策略
        self.freq = 1 # 每一分钟收到一次onBar
        self.formula = 'b/a' ##计算公式为log(合约2/合约1),用比价代替
        self.name = 'hedge AG' ##策略名
        ##保存仓位数据
        self.pos0 = {'long':0,'short':0} 
        self.pos1 = {'long':0,'short':0}
        self.longvol = 0
        self.shortvol = 0
        ##最大持仓手数
        self.maxvol = 50
    def onBar(self,context):
        try:
            ##比较context仓位和本地仓位,若不符合,则判断还在等待交易未成交
            bTrading = (self.pos0['long'] != context.getAccountPosition(context.instid[0],'long','volume')) or \
                       (self.pos0['short'] != context.getAccountPosition(context.instid[0],'short','volume')) or \
                       (self.pos1['long'] != context.getAccountPosition(context.instid[1],'long','volume')) or \
                       (self.pos1['short'] != context.getAccountPosition(context.instid[1],'short','volume')) 


            #若非等待交易有方差数据
            if not bTrading : 
                    bardata = get_bar(context, 1) # 获取当天bar数据
                    curday = context.curtime.date() # 获取当天日期
                    offset = 1 if curday.weekday() > 0 else 3  ## 若为周一 往前3天, 否则往前1天
                    ## 获取第一个合约前一个交易日数据
                    df1 = get_price(context.instid[0],curday-timedelta(days=offset), curday,'minute')
                    while len(df1) == 0: ## 处理万一有节假日情况,找到最近一个工作日
                        offset += 1
                        df1 = get_price(context.instid[0],curday-timedelta(days=offset), curday,'minute')
                    ## 获取第二个合约前一个交易日数据
                    df2 = get_price(context.instid[1],curday-timedelta(days=offset), curday,'minute')

                    ## 将数据和当天bar数据拼接
                    df1 = pd.concat([df1,bardata[context.instid[0]]],join='outer')
                    df2 = pd.concat([df2,bardata[context.instid[1]]],join='outer')

                    ## 获得两个合约价格的log差
                    close1 = df1.close.values
                    close2 = df2.close.values
                    close = np.log(close2)-np.log(close1)

                    ## 使用布林带计算log比价的上轨,中轨,下轨
                    upper,middle,lower=talib.BBANDS(close,timeperiod=15, matype=MA_Type.T3)

                    if  close[-1] < lower[-1] and self.longvol + self.shortvol < self.maxvol :
                    #低于下轨并且还没到最大仓位,做多价差
                        self.pos0['short'] += 1
                        self.pos1['long'] += 1
                        self.longvol += 1
                        ##合约0下空单
                        make_order(context,context.instid[0],-1,\
                                                   context.getCurrent(context.instid[0]),1,'market',action='open')
                        ##合约1下多单
                        make_order(context,context.instid[1],1, \
                                      context.getCurrent(context.instid[1]),1,'market',action='open')
                        ##记录当前对冲开仓点
                        record_hedge_point(context,'open','short',1)

                    elif close[-1] > upper[-1] and self.longvol + self.shortvol < self.maxvol:
                    #高于上轨并且还没到最大仓位,做多价差
                        self.pos0['long'] += 1
                        self.pos1['short'] += 1
                        self.shortvol += 1
                        #合约0下多单
                        make_order(context,context.instid[0],1, \
                                      context.getCurrent(context.instid[0]),1,'market',action='open')
                        #合约1下空单
                        make_order(context,context.instid[1],-1, \
                                      context.getCurrent(context.instid[1]),1,'market',action='open')
                        #记录当前对冲开仓点
                        record_hedge_point(context,'open','long',1)

                    if close[-1] > middle[-1] and self.longvol > 0:
                     #高于中轨并且有多头仓位,平仓
                        #合约0平空仓
                        make_order(context,context.instid[0],1, \
                                      context.getCurrent(context.instid[0]),self.longvol,\
                                   'market',action='close',closetype='closetoday')
                        #合约1平多仓
                        make_order(context,context.instid[1],-1, \
                                      context.getCurrent(context.instid[1]),self.longvol,\
                                   'market',action='close',closetype='closetoday')
                        #记录当前对冲平仓点
                        record_hedge_point(context,'close','short',1)
                        self.pos0['short'] = 0
                        self.pos1['long'] = 0
                        self.longvol = 0

                    if close[-1] < middle[-1] and self.shortvol > 0:
                      #低于中轨并且有空头仓位,平仓
                        #合约0平多仓
                        make_order(context,context.instid[0],-1, \
                                      context.getCurrent(context.instid[0]),self.shortvol,\
                                   'market',action='close',closetype='closetoday')
                        #合约1平空仓
                        make_order(context,context.instid[1],1, \
                                      context.getCurrent(context.instid[1]),self.shortvol,\
                                   'market',action='close',closetype='closetoday')
                        #记录当前对冲平仓点
                        record_hedge_point(context,'close','long',1)
                        self.pos0['long'] = 0
                        self.pos1['short'] = 0
                        self.shortvol = 0
        except Exception as e:
            print('handleData error', e.__traceback__.tb_lineno, e)

这里使用布林带来获取上中下轨, 15分钟作为数据窗口。

然后开始回测

##调用接口进行回测
report = runStrat('scott','test',hedgeStrat(), test_startdate='2021-11-01',test_enddate='2021-11-15' ,\
                   test_initcap=1000000,test_dynamic_instid=False )

注:对冲模式下必须关闭动态合约模式,将 test_dynamic_instid 设置为False

运行结果附图:

开平仓行情图:

资金图:

盈亏图:

注:若策略没有在构造函数中初始化self.formula ,系统认为该策略是非对冲策略,该函数将不会有任何作用。

回测函数说明

宽易平台回测相关的接口函数

  1. 获取合法用户名函数

    方便客户获取系统登录用户名

  2. 统一策略运行函数

    回测、模拟和实盘统一策略运行函数。

  3. akshare股票数据转化函数

    对于akshare查询数据,可以通过该转化函数转化为宽易标准数据格式。客户可以在转化后直接调用runStrat函数进行回测。

  4. 回测报告作图函数

    对于runStrat返回报告作图

  5. 回测绩效分析函数

    调用第三方quantstat绩效分析函数分析回测报告

  6. 回测报告指标计算函数

    对于runStrat返回报告计算关键指标

获取合法用户名

getuserid(user)

参数:user,str类型。 用魔法函数 %pwd 获取的用户路径

返回值:str类型。 系统合法用户名

示例

user = %pwd
user = getuserid(user)
print(user)

返回值

'admin'

统一策略运行函数

runStrat(user, runmode, strat,  simu_token=None, mode_724=False, csv_orders=False, simu_simnow724_account=None, \
         real_account=None, printlog=True, rfrate=0.02, test_dynamic_instid=True, \
         test_startdate=None, test_enddate=None,  test_initcap=10000000,test_showchart=False)

详细使用说明如下

函数说明 参数表
参数 类型 回测 模拟 实盘 说明 备注
user str 系统登录用户名,可以通过getuserid函数获取.
runmode str 'test'回测,'simu'模拟,'real'实盘,一个参数切换运行模式.
strat qeStratBase / list qeStratBase派生策略或派生策略的列表,回测只支持单策略,输入列表仅第一项有效,模拟/实盘支持多策略并发
simu_token str 模拟用令牌token。使用createSimuAccount创建的模拟账户时生成。
mode_724 bool 是否使用SIMNOW 7x24小时模拟测试服务.默认False不使用,不使用时非市场开盘时间不可以运行模拟或实盘交易。若为True使用,但需要客户给出SIMNOW账户信息。
csv_orders bool 是否使用csv下单工具.默认False不使用,True为使用,不可用于回测,详见 辅助工具相关说明。
simu_simnow724_account dict 模拟用SIMNOW7*24小时账户信息,当模拟测试时 mode_724为True时,系统将检查该项账户配置,比如{'investorid':'133231','password':’888888'}
real_account dict 实盘交易使用的账户信息。若mode_724为True,该实盘账户应设置为SIMNOW7*24小时账户。详见实盘交易
printlog bool 是否打印开平仓信息和warning信息。默认为True
rfrate float 无风险利率,用于计算sharp比率等,默认2%
test_dynamic_instid bool 是否使用动态合约回测模式,默认为True
test_startdate str 回测数据开始时间,比如'2021-01-01'.test_date不为None,此参数无效
test_enddate str 回测数据结束时间,比如'2021-01-01'.test_date不为None,此参数无效
test_initcap float 回测用初始资金,默认为10000000
test_showchart bool 回测执行结果是否输出三张分析图,默认关闭
real_skip_settle_check bool 是否skip实盘确认昨日结算单过程,默认为False.若用户自行打开设置为True,宽易不对任何结算单相关问题负责。

返回值 若为模拟/实盘模式,无返回值。若为回测模式,运行结束后返回Dict类型的回测报告。有‘Report’,'Orders','Trades','Cancels'四个Key

回测模式返回的回测报告为dict类型,相关说明如下表:

键值 类型 说明
Data dict或者pandas.DataFrame 行情及开平仓信息表。可以用于生产开平仓点位图。若为对冲模式,返回DataFrame格式,否则返回以合约名为key,数据DataFrame为value的dict类型,
Orders pandas.DataFrame 下单报告,按照orderid排序。涵盖每笔委托的具体数据,包含订单价格,订单量,多空方向,开平仓类型等
Trades pandas.DataFrame 成交报告,按照tradeid排序。涵盖每笔成交的具体数据,包含成交价格,成交量,多空方向,开平仓类型等
Stat pandas.DataFrame 按日统计报告,包括每日盈亏,资金,回撤,交易额,最大资金占用等信息。

注意事项

  1. strat参数必须是qeStratBase派生类的实例或者实例列表

  2. instids参数必须是list类型,如果只有一个合约也要写成 [ 合约名 ]

  3. 如果是对冲策略,需要在strat类构造时候给 self.formula 赋值。单合约self.formula 无效

  4. test_data里面各合约的列名必须相同,并且列名对应合约的先后顺序必须和instids里面的合约顺序相同。 比如分钟级,instids为['AG2206.SFE','AU2206.SFE‘], 那么df的columns应该是 ['open-AG2206.SFE', 'close-AG2206.SFE', .....'open-AU2206.SFE', 'close-AU2206.SFE'.....].

  5. test_exdata仅用于回测,无法在模拟和实盘中使用,所以仅用于验证算法方便,尽量不使用该函数才能保证平滑过渡到模拟和实盘交易。

示例代码

## 新建策略实例
strat = mystrat()
start_date = '2021-01-08' ##起始日期
end_date = '2021-10-01' ##结束日期
strat.instid = ['AG2112.SFE']  ##合约名称
##调用回测接口,初始资金30万
report = runStrat('scott','test', strat, test_startdate=start_date, test_enddate=end_date, test_initcap=300000)

关于动态合约回测模式

  1. 支持在策略运行过程中crossDay/handleData/onBar 接口中修改 instid 字段,系统会自动识别合约名(列表)发生了变更,并做相应处理。
  2. 适用于期货切换主力合约等应用场景,仅用于回测时使用,模拟/实盘自动支持动态合约无需设置。
  3. 当该模式打开时:
    • 不支持tick数据,strat.datamode不可以是‘’tick‘’
    • 不支持对冲模式,strat.formula 必须为None
    • 不支持第三方数据, test_data必须为None
    • 不支持外部数据, test_exdata 必须为None
    • 将按30天加载数据进行回测,若出现换月重新加载30天数据,直到到达test_enddate设定的终止日期
    • showCharts不显示换合约前的合约开平仓图,仅显示最后有效的合约开平仓图,其他图正常显示。
    • 可以在点击提示网址打开的report网页中查看所有合约的历史开平仓情况。
    • onBar中切换合约不会立即生效,将在下一次onBar时生效,所以修改合约后马上下单无效。一般建议吧切换合约放在crossDay中。

在crossDay中切换合约名列表示例:

def crossDay(self,context):
      self.instid.remove('AG2106.SFE')
      self.instid.append('AG2112.SFE')

回测报告作图函数

showCharts(report)

用于根据回测返回报告生成开平仓图, 资金回撤图,盈亏图。 详细如下:

▼ 函数说明 参数
参数 类型 说明
report Dict runStrat返回的回测报告

结果
显示开平仓图,资金图,盈亏图三张图

示例

report = runStrat('scott','test', strat, test_startdate=start_date, test_enddate=end_date, test_initcap=300000)
showCharts(report)

回测绩效分析函数

reportPerformance(report, benchmark=None)

用于使用第三方绩效分析库对回测结果进行评估, 使用的数据必须超过半年,否则无法运行。详细如下:

▼ 函数说明 参数
参数 类型 说明
report Dict runStrat返回的回测报告
benchmark pandas.Series 作为比较用的基准数据同期日回报率数据,比如南华指数。注:该数据日期必须与report['Stat']日期序列完全对应。默认为None,超额回报率等指标将不被计算。

结果
生成绩效评估报告

示例

report = runStrat('scott','test', strat, test_startdate=start_date, test_enddate=end_date, test_initcap=300000)
reportPerformance(report)

注:使用的数据日期跨度必须超过半年。若使用benchmark必须是和数据日期完全匹配的回报率。

回测报告指标计算函数

reportIndicators(report, riskfree, benchmark=None)

详细说明

▼ 函数说明 参数
参数 类型 说明
report Dict runStrat返回的回测报告
riskfree float 无风险回报率,比如0.02代表2%
benchmark pandas.Series 作为比较用的基准数据同期日回报率数据,比如南华指数。注:该数据日期必须与report['Stat']日期序列完全对应。默认为None,超额回报率等指标将不被计算。

返回值
dict类型,生成如下指标结果:
键值 说明
accret 累积回报率
arr 年化回报率
highwater 最高回报率
maxdrawback 最大回撤率
avol 年化波动率
winrate 胜率
odds 赔率
downrisk 下行风险
sharpratio sharp比率
sortinoratio sortino比率
calmarratio calmar比率
maxmarg 最大保证金占用
relativeret 超额回报率(有benchmark)
arrr 年化超额回报率(有benchmark)
correlation 相关系数(有benchmark)
rsquare R2指数(有benchmark)

示例

reportIndicators(report,0.02)

结果

{'accret': 0.23522839455330163,
 'arr': 0.3239938264602079,
 'highwater': 1.2785476999999998,
 'maxdrawback': -0.041039004999999885,
 'avol': 0.1334835813413924,
 'winrate': 1.0,
 'odds': 1,
 'downrisk': 0.005791978629006393,
 'sharpratio': 2.2773874015466,
 'sortinoratio': 2.7472069784951394,
 'calmarratio': 7.407436570652937,
 'maxmarg': 55330.2}
Copyright © QUANTEASE Team all right reserved,powered by Gitbook该文件修订时间: 2023-06-29 11:18:32

results matching ""

    No results matching ""