量化初步-《python与量化投资从基础到实战》——优矿策略

python与量化投资从基础到实战——策略初步

量化数据获取

优矿介绍

网址链接: https://uqer.datayes.com/
在这里插入图片描述

在这里插入图片描述

使用方式

注册登录,点击【开始研究】——【新建】,新建notebook用于写策略。
页面有新手指引,帮助快速入门。
在这里插入图片描述
首先要获取数据,点【研究数据】,可以自己查找,也可以上方直接关键词搜索。
在这里插入图片描述
点击数据会出现函数使用代码,可复制到notebook里运行。根据下方函数说明更改代码获取自己需要的数据。
在这里插入图片描述

日行情数据

获取平安银行和浦发银行在2015年5月13号的收盘价与总市值。

DataAPI.MktEqudGet(tradeDate=u'20150513',secID=u"",ticker=["000001","600000"],field=u'secID,ticker,secShortName,tradeDate,preClosePrice,marketValue',pandas="1")

在这里插入图片描述
一段时间的数据:

DataAPI.MktEqudGet(tradeDate=u'',secID=u"",ticker=["000001","600000"],beginDate=u"20180117",endDate=u"20180119",field=u'secID,ticker,secShortName,tradeDate,preClosePrice,marketValue',pandas="1")

在这里插入图片描述

因子数据

根据需求选择函数
在这里插入图片描述

DataAPI.MktStockFactorsDateRangeGet(secID=u"",ticker=["000001","600000"],beginDate=u"20170612",endDate=u"20170616",field=u"secID,ticker,tradeDate,PS,PB,NetProfitGrowRate",pandas="1")

在这里插入图片描述
除这些常用的金融数据,优矿数据模块还包括财报数据、事件数据和期货数据,自行去探索哈哈哈

数据处理

数据合并

收盘价与均线数据合并

df_quotation=DataAPI.MktEqudGet(tradeDate=u'',secID=u"",ticker=["000001","600000"],beginDate=u"20180101",endDate=u"20180121",field=u'secID,ticker,tradeDate,closePrice',pandas="1")

df_factor=DataAPI.MktStockFactorsDateRangeGet(secID=u"",ticker=["000001","600000"],beginDate=u"20180101",endDate=u"20180121",field=u"secID,ticker,tradeDate,MA10,MA5",pandas="1")
df_quotation.merge(df_factor,on=['ticker','tradeDate'])

在这里插入图片描述

数据透视

求股票每天的市值之和:

df_quotation=DataAPI.MktEqudGet(tradeDate=u'',secID=u"",ticker=["000001","600000"],beginDate=u"20180101",endDate=u"20180121",field=u'secID,ticker,tradeDate,closePrice,marketValue',pandas="1")
df_quotation=df_quotation.pivot_table(index='tradeDate',columns='secID',values='marketValue')
df_quotation

在这里插入图片描述

数据过滤

选取PE>0的数据

df=DataAPI.MktStockFactorsOneDayGet(tradeDate=u"20180119",secID=set_universe('A'),ticker=u"",field=u"secID,tradeDate,PE",pandas="1")
df[df.PE>0].head(10)

在这里插入图片描述

数据获取与整理

直方图和箱线图

df=DataAPI.MktStockFactorsOneDayGet(tradeDate=u"20180119",secID=set_universe('A'),ticker=u"",field=u"secID,tradeDate,ROE",pandas="1")
df.plot.hist(bins=100)

在这里插入图片描述

_=df.boxplot(sym='rs')

在这里插入图片描述
数据去极值,处理后的因子建模更加稳定,是数据挖掘中常提及的“盖帽法”

df_=df.copy()
df_.loc[df.ROE-df.ROE.mean()<-3*df.ROE.std(),'ROE']=df.ROE.mean()-3*df.ROE.std()
df_.loc[df.ROE-df.ROE.mean()>3*df.ROE.std(),'ROE']=df.ROE.mean()+3*df.ROE.std()
df_.plot.hist(bins=100)

在这里插入图片描述

数据转化: 标准化 哑变量

标准化
Min-max标准化后值同一到0-1;z-score标准化后均值0,方差1.

((df_['ROE']-df_['ROE'].min())/(df_['ROE'].max()-df_['ROE'].min())).plot.hist(bins=100)

在这里插入图片描述

((df_['ROE']-df_['ROE'].mean())/df_['ROE'].std()).plot.hist(bins=100)

在这里插入图片描述
哑变量

import pandas as pd
df_industry=DataAPI.EquIndustryGet(secID=df_['secID'].tolist(),ticker=u"",industryVersionCD=u"010303",industry=u"",intoDate=u"20180101",
                                   field=u"secID,industryName1",pandas="1")
industry_list=df_industry['industryName1'].drop_duplicates().tolist()
df_industry
def get(x):
    ind_s=pd.Series([0]*len(industry_list),index=industry_list)
    if len(df_industry[df_industry['secID']==x])>0:
        ind=df_industry[df_industry['secID']==x]['industryName1'].values[0]
        ind_s.loc[ind]=1
    return ind_s    
df_[industry_list]=df_['secID'].apply(lambda x:get(x))
df_.head()

在这里插入图片描述

通联数据回测

在【开始研究】中【新建】,选择【策略】,出现如下策略模板:
在这里插入图片描述

回测平台函数与参数设置

大致函数说明,详情看书《python与量化投资从基础到实战》。

设置回测参数

start与end(设置回测区间) :指回测的起始日期
universe(证券池):指策略回测的证券池,即策略逻辑作用的域,下单与历史数据获取都只限于universe中的证券。universe支持全部A股及全部可在二级市场交易的ETF与LOF;还支持以三种方式获取证券池:DynamicUniverse、set_universe 和StockScreener;也可以使用固定的股票列表,例如[‘000001.XSHE’,‘600000.XSHG’]。对这个参数的设置,主要是为了让回测平台能够提前预加载相关数据,以加快回测速度。
set_universe(静态证券池):用于返回预设的证券代码列表,支持行业成分股、指数成分股。当资产池指定为一个特定的列表时,策略框架仅返回相应列表中的内容。
DynamicUniverse(动态证券池) 用于返回动态证券池实例。在使用板块成分股、指数成分股或行业成分股作为策略的交易对象时,策略框架会根据实际情况调整当天股票池的内容。
apply_filter 用于将筛选条件作用于动态证券池的每个交易日的证券池上,进一 步缩小策略标的范围。当前支持使用优矿因子库中的所有因子对证券池 进行筛选。
benchmark(参考基准) 为策略参照标准,即该量化策略回测结果的比较标准,通过比较可以大致看出策略的好坏,为str类型。策略的一些风险指标如alpha、beta等也要通过benchmark计算。

freq和refresh_rate(策略运行频率) 策略回测在本质上是使用历史行情和其他依赖数据对策略的逻辑进行历史回放。freq和refresh_rate这两个函数共同决定了回测使用的数据和调仓频率,其中,freq表示使用的数据为日线行情数据或者分钟线行情数据,为str类型;refresh_rate表示调仓间隔的时间,为每次触发handle_data间隔的时间,为int或(a,b)结构。

accounts账户配置

为优矿回测框架的交易账户配置函数,优矿最新框架支持多种交易品种,可对多个交易账户同时进行回测。

AccountConfig(账户配置) 用于配置单个交易账户,在策略初始化时会根据账户的配置创建对应的交易账户。
account_type(账户类型设置) 用于设置交易账户类型,为 str 类型,支持 security 股票和场内基金、futures 期货、otc_fund场外基金(不含货币基金)、index指数。
capital_base(初始资金设置)
position_bas(初始持仓设置)
cost_base(初始成本设置)
commission(手续费设置)
slippage(滑点设置)
margin_rate(保证金比率设置)
dividend_method(基金分红方式设置)

initialize(策略初始化环境)

initialize()为策略初始化函数,用于配置策略运行环境context对象的属性或自定义各种变量,在策略运行周期中只执行一次。我们可以通过 context 添加新的属性或自定义各种变量。示

handle_data(策略运行逻辑)

handle_data()为策略算法函数,在策略运行时(回测或模拟交易)会根据初始化配置的策略算法运行频率调用该函数。策略算法可以通过 context 获取运行时的行情数据、K线图、因子数据、订单簿等数据,并根据分析的结果通过交易账户进行订单委托。

context(策略运行环境)

context表示策略运行环境,包含运行时间、行情数据等内容,还可
用于在存储策略中生成的临时数据的存储。

now(策略运行时的当前时刻)
current_date(当前回测日期)
previous_date(回测日期的前一交易日)
current_minute(当前运行的分钟值)
current_price(获取成交价)
get_account(获取交易账户)
get_universe(获取当前交易日证券池)
transfer_cash(账户间资金划转)

股票模板实例

一个完整的股票策略实例:

策略思想是选取过去60个交易日累积收益率最高的60只股票买入,换仓频率为60天。
可以看出,该策略最后的表现结果一般,比指数略好.

import pandas as pd 
start = '2014-11-01'                       # 回测起始时间
end = '2018-01-01'                         # 回测结束时间
benchmark = 'HS300'                        # 比较基准沪深300指数
universe = DynamicUniverse('HS300')        # 股票池是动态沪深300成分股
refresh_rate=60    #调仓频率是每60个交易日调仓一次,默认频率参数是“d”天
max_history_window=60 #默认对日线数据支持30个交易日,对分钟线支持240条K线数据 
#cintext的history方法调用要确保必须max_history_window大于调用历史数据窗口

accounts = {
    
    
    'fantasy_account': AccountConfig(account_type='security', capital_base=10000000,commission=Commission(buycost=0.001,sellcost=0.002,unit='perValue'),slippage=Slippage(value=0.0,unit='perValue'))
}
#account_type='security', capital_base=10000000股票策略 初始资金1000万元
#commission参数用于设置手续费,而 slippage 参数用于设置滑点,它们接收的是特定的Commission和Slippage实例

def initialize(context):
    pass

def handle_data(context):   
    account = context.get_account('fantasy_account') #获取我们在前面设定好的股票账户
    universe = context.get_universe(exclude_halt=True)
    #context自带了一些日期属性及价量信息、股票池处理等功能。 
    #context的get_universe方法的参数exclude_halt被设置成了True,意思是获取我们当前的股票池并且剔除停牌的股票。
    #因为我们只能交易非停牌的股票,所以要把停牌的股票去掉。
    history = context.history(universe,'closePrice',60)
    #获取了各只股票在历史上 60 个交易日的前复权收盘价,格式是一个字典,键为股票代码,值是一个索引为时间、列为前复权收盘价的DataFrame。
    
    momentum = {
    
    'symbol':[],'c_ret':[]}
    for stk in history.keys():
        momentum['symbol'].append(stk)
        momentum['c_ret'].append(history[stk]['closePrice'][-1]/history[stk]['closePrice'][0])
        # 按照过去60日收益率排序,并且选择前60只的股票作为买入候选
        
#字典初始化,对每只股票进行循环,用最近的前复权价格除以60个交易日之前的前复权价格,得到累积净值。
#然后对股票按累计净值进行排序,选取前60只股票作为待买股票池。
    momentum = pd.DataFrame(momentum).sort(columns='c_ret',ascending=False).reset_index()
    #print(momentum)
    momentum=momentum[:60] 
    buylist=momentum['symbol'].tolist()
 
 #于获取策略当前的所有持仓,具体返回的是一个字典,键为股票代码,值为持仓股票数量。
#对持仓的股票进行遍历,若它不在我们的待买股票池里,就做一个order_to(stk,0)操作,意思是将该股票清仓
    for stk in account.get_positions(): 
        if stk not in buylist:
            order_to(stk,0)
      
 #把在持仓里但不在待买股票池里的股票卖出,接着也是通过account的方法account.portfolio_value获取组合的市值,然后运用 order_pct_to 方法将所有待买股票买入或卖出到等权。
#需要注意的是,通常我们都会将卖出操作写在买入操作的前面,因为只有卖出股票腾出现金,我们才可以买入其他股票
    #等权重买入所选股票
    protfolio_value=account.portfolio_value
    for stk in buylist:
        order_pct_to(stk,1.0/len(buylist))

在这里插入图片描述

history方法

用于获取K线图等时间序列数据。对其参数说明如下。

(1)symbol:指需要获取的证券列表,支持单个证券或证券列表。
(2)attribute:指需要获取的属性,支持单个值或属性列表。可选的范围如下。
◎ openPrice:前复权开盘价。
◎ highPrice:前复权最高价。
◎ lowPrice:前复权最低价。
◎ closePrice:前复权收盘价。
◎preClosePrice:前复权前收盘价。
◎ turnoverVol:前复权成交量。
◎ turnoverValue:前复权成交额。
(3)time_range:指所需回溯的历史K线图条数,和freq属性相对应。
(4)freq:指 K线图周期,支持’1d’、‘1m’、‘5m’、‘15m’、‘30m’、'60m’等周期。'1d’表示日线,‘1m’表示一分钟线。分钟K线图仅可在分钟频率回测时使用。
(5)style:指数据返回的类型,可以选择’ast’、‘sat’或者’tas’这三种 类型,其中’a’表示’attribute’,'s’表示symbol,‘t’表示时间,三种选择分别对应这三个维度呈现的顺序,例如’ast’表示在返回的字典中的键是attribute,其值为列为symbol、行为time的DataFrame,依此类推。
(6)rtype:指返回值的数据类型。可以选择’frame’、'array’这两种 类型。

order(symbol,amount,price=0.,otype=‘market’)

指根据指定的参数,进行订单委托。订单类型支持市价单或限价单,在限价单中需将otype设置为"limit",并设置下单价格。
对其参数说明如下。

◎ 为symbol时,指需要交易的证券代码,必须包含后缀,其中上证 证券为.XSHG,深证证券为.XSHE。
◎为amount时,指需要交易的证券代码为symbol的证券数量,为正 则买入,为负则卖出;程序会自动对amount向下取整到最近的整百。
◎为price时,指下限价单时的下单价格(仅日内策略可用)。
◎为otype时,指可选’market’(市价单)和’limit’(限价单)这两个 值,表示交易指令类型(为limit时仅日内策略可用)。

order_to (symbol,amount,price=0.,otype=‘market’)

指通过下单,将某只股票的持仓调整到持有多少手。策略框架会自动计算当前持仓和目标持仓的差额,并进行下单。在每次 handle_data时调用,最多只允许一次 order_to 函数调用,否则可能造成下单量计算错误。
对其参数说明如下。

◎ 为symbol时,指需要交易的证券代码,必须包含后缀,其中上证证券为.XSHG,深证证券为.XSHE。
◎ 为amount时,指需要交易的证券代码为symbol的证券数量,为正则买入,为负则卖出。程序会自动对amount向下取整到最近的整百。
◎ 为price时,指下限价单时的下单价格(仅日内策略可用)。
◎ 为otype时,指可选’market’(市价单)和’limit’(限价单)这两个值,表示交易指令类型(为limit时仅日内策略可用)。

order_pct (symbol,pct)

指根据当前的账户权益按一定比例下单。比如当前账户有100 000元,下单20%,就会使用20000元计算最大可委托手数并下单。
对其参数说明如下。

◎ 为symbol时,指需要交易的证券代码,必须包含后缀,其中上证 证券为.XSHG,深证证券为.XSHE。
◎ 为pct时,指需要交易的证券代码为symbol的证券占虚拟账户当前总价值的百分比,范围为0~1,为正则买入,为负则卖出。程序会自动对计算出的下单数量向下取整到最近的整百。

order_pct_to(symbol,pct)

指根据当前的账户权益按一定比例下单。策略框架会自动计算当前持仓和目标持仓的差额,并进行下单。比如当前账户有100 000元,下单20%,就会使用20000元计算最大可委托手数,为500股,当前持有300股,则下单200股。
对其参数说明如下。

◎ 为symbol时,指需要交易的证券代码,必须包含后缀,其中上证证券为.XSHG,深证证券为.XSHE。
◎为pct时,指需要交易的证券代码为symbol的证券占虚拟账户当 前总价值的百分比,范围为0~1,为正则买入,为负则卖出。程序会自动对计算出的下单数量向下取整到最近的整百。

期货模板实例

一个期货策略的实例:

策略思想是在每天 9点半开盘时买入1手沪深300期货,在9点 36分时卖出、清仓,在此期间做一个亏损5000元的止损。

universe = ['IFM0'] #策略期货合约 指沪深300期货主力
#因为一只期货的存续时间较短,所以在进行长期回测时会涉及期货品种的切换,而在优矿的期货回测内部已经帮大家做好了这个。
#将universe设置成期货主力后,在后面的handle_data中会根据日期自动切换品种。
start = '2015-01-01'                       # 回测起始时间
end = '2015-04-07'                         # 回测结束时间
capital_base = 600000                      #初始可用资金60万元
freq = 'm'                                 # 策略频率,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测
refresh_rate = 1                           # 调仓周期 调仓频率是每分钟调仓一次。
  
commission = Commission(buycost=0.0,sellcost=0.0,unit='perValue') #设置股指期货交易手续费
slippage = Slippage(value=0,unit='perValue') #设置价格滑点百分比

accounts = {
    
    
    'fantasy_account': AccountConfig(account_type='futures', capital_base=capital_base,commission=commission,slippage=slippage)
}#设置虚拟期货账户 要将‘account_type’调整为‘futures’,因为我们的账户是期货账户。这里为了简单展示,把交易费用与滑点都设置为了0。
  
def initialize(context): #初始化虚拟期货账户,一般用于设置计数器,回测辅助变量等。
    pass
  
def handle_data(context):    #回测调仓逻辑,每个调仓周期运行一次,可在此函数内实现信号生产,生产调仓指令。
    futures_account = context.get_account('fantasy_account') #拿到期货账户
    symbol = context.get_symbol(universe[0]) #拿到目前的期货主力对应的期货品种。

#context的current_minute获取当前的分钟时刻,判断其是否是9点半,如果是,则运用期货账户的order方法买入一手沪深300期货。
#需要注意的是,期货账户的下单方法要比股票多一个参数,那就是方向。因为期货既可以做多也可以做空 
    if context.current_minute == '09:30':
        futures_account.order(symbol,1,'open')
        
    #平仓   
#们在9点36分时首先通过futures_account.get_positions()获取期货账户的持仓情况,获取期货的多头持仓数量 long_amount。
#get_positions()方法返回的虽然也是一个字典,它的键是对应的期货代码,但它的值是包含持仓信息的一个实例。
    elif context.current_minute == '09:36':
        long_position = futures_account.get_positions().get(symbol,dict()).long_amount
        if long_position > 0:
            futures_account.order(symbol,-long_position,'close')
    
    #止损
#在9点36分做的就是把持有的仓位给平了。而对于止损是在 9 点半至 9点36分之间做的.
#我们首先判断目前是否有持仓,接着判断持仓是否已经亏了5000元,如果是,则提前卖出它。
    elif context.current_minute < '09:36':
        if len(futures_account.get_positions()) > 0 and futures_account.get_positions().get(symbol).today_profit<-5000:
            long_position = futures_account.get_positions().get(symbol,dict()).long_amount
            if long_position > 0:
                futures_account.order(symbol,-long_position,'close')        

在这里插入图片描述

get_symbol(获得主力连续合约的映射合约)

我们在进行信号生成时,可以使用主力合约时间序列,但在下单时
要使用具体的合约。若想得到当天的主力合约映射的具体合约符号,则可以使用context.get_symbol方法获取:context.get_symbol(symbol)
context.get_symbol方法用于获取某个主力连续合约的映射合约,返
回主力连续合约的映射合约,仅适用于期货品种。其参数为smybol,指主力合约的符号,为str类型。

mapping_changed(判断是否切换主力连续合约的映射合约)

用于判断是否切换某个主力连续合约的映射合约,返回布尔值,仅
适用于期货品种。其参数为smybol,指主力合约符号,为str类型。
示例如下:
bool context.mapping_changed(symbol)

get_rolling_tuple(获取主力连续合约映射关系变化前后的具体合约)

用于获取主力连续合约映射关系变化前后的具体合约,仅适用于期
货品种。其参数为smybol,指主力合约符号,为str类型。
其示例如下:context.get_rolling_tuple(symbol)
其返回如下,指主力切换前后的对应具体合约,为字符串对类型:
(symbol_before,symbol_after)

switch_position(移仓操作)

指移仓操作,下达 symbol_before 至 symbol_after 相同数量的平仓
及开仓指令(含多空持仓),仅适用于期货品种。其参数为
symbol_before 时指移仓前合约,为 str 类型;其参数为symbol_after时指移仓后合约,为str类型。
示例如下:
futures_account.switch_position(symbol_before,symbol_after)

futures_account.order(symbol,amount,offset_flag,order_type=‘market’,price=0)

该函数为期货下单函数。对其参数说明如下。

◎ 为symbol时,指需要交易的期货代码。 ◎ 为offset_flag时,指开仓或平仓参数,可选open和close这两个参
数,open为开仓,close为平仓。 ◎ 为 amount 时,指需要交易的期货代码为 symbol 的证券数量,其
正负含义需与offset_flag结合起来看。若offset_flag为open,则amount为
正就是买入开仓,为负就是卖出开仓;若offset_flag为close,则amount 为正就是买入平仓,为负就是卖出平仓。 ◎
为price时,指下限价单时的下单价格(仅日内策略可用)。 ◎
为otype时,可选’market’(市价单)和’limit’(限价单)这两个 值,表示交易指令类型(为limit时仅日内策略可用)。

策略回测详情

点击【回测详情】,可查看回测平台给出的详细调
仓持仓及风险收益指标等数据。
在这里插入图片描述
在这里插入图片描述
也可以通过代码查看回测结果:

bt

指回测报告,格式为 pandas.DataFrame,包括日期、现金头寸、证券头寸、投资组合价值、参考指数收益率、交易指令明细表等6列,以及用户在observe中定义的其他列。

bt_by_account

指回测报告,格式为 pandas.DataFrame。包括日期、现金头寸、证券头寸、投资组合价值、参考指数收益率、交易指令明细表等6列,以及用户在observe中定义的其他列。

perf

指根据回测记录计算各项风险收益指标,格式为字典,键为指标名称,值为指标的值,有些为float,有些为list。

策略的风险评价指标

年化收益率(Annualized Returns)

表示投资期限为一年的预期收益率,计算公式为
在这里插入图片描述
其中,pend指策略最终总资产,pstart指策略初始总资产,n指回测交易日数量。

基准年化收益率(Benchmark Returns)

表示参考标准年化收益率,计算公式为
在这里插入图片描述
其中,Bend指基准最终值,Bstar指基准初始值,n指回测交易日数量。

阿尔法(Alpha)

表示在投资中面临的非系统性风险。Alpha 是投资者获得的与市场波动无关的回报,一般用来度量投资者的投资技能。比如投资者获得了12%的回报,其基准获得了10%的回报,那么Alpha或者价值增值的部分就是2%。其计算公式为
在这里插入图片描述
其中,Pr为策略年化收益率,rf为无风险收益率,Br为基准年化收益率。

a>0,策略相对于风险获得了超额收益
a=0,策略相对于风险获得了适当收益
a<0,策略相对于风险获得了较少收益

贝塔(Beta)

表示在投资中面临的系统性风险,反映了策略对大盘变化的敏感性。例如,一个策略的Beta为1.3,则在大盘涨1%时,策略就可能涨1.3%,反之亦然;如果一个策略的Beta为-1.3,则说明在大盘涨1%时,策略可能跌1.3%,反之亦然。其计算公式为
在这里插入图片描述
其中,pn 指策略每日收益率,Bn 指基准每日收益率, 指基准每日收益方差,Cov(pn,Bn)指策略每日收益率和基准每日收益率的协方差。

夏普比率(Sharpe Ratio)

表示每承受一单位总风险,会产生多少超额报酬,可以同时对策略的收益与风险进行综合考虑。其计算公式为
在这里插入图片描述
其中,pr指策略年化收益率,rf指无风险收益率,σp指策略收益波动率。

收益波动率(Volatility)

用于测量资产的风险性,波动越大,代表策略风险越高。其计算公式为
在这里插入图片描述
其中,n指回测交易日数量,pt指策略每日收益率, 在这里插入图片描述指策略每日平均收益率。 在这里插入图片描述的计算公式为在这里插入图片描述

信息比率(Information Ratio)

用于衡量单位超额风险带来的超额收益。信息比率越大,则说明该策略单位跟踪误差所获得的超额收益越高。因此,信息比率较大的策略的表现要优于信息比率较低的基金。合理的投资目标应该是在承担适度风险的情况下,尽可能地追求高信息比率。其计算公式为
在这里插入图片描述
其中,pr指策略年化收益率,Br指基准年化收益率,σt指策略每日收益差值与基准每日收益差值的年化标准差。

最大回撤(Max Drawdown)

用于描述策略可能出现的最糟糕的情况,计算公式为
在这里插入图片描述
其中,px、py指策略某日总资产(证券持仓和现金之和),y>x。

换手率(Turnover Rate)

用于描述策略变化的频率及持有某只股票平均时间的长短,计算公式为
在这里插入图片描述
其中,px指买入总价值和卖出总价值中的较小者,pavg指虚拟账户的平均价值。

策略交易细节

回测交易撮合机制和订单委托

在回测时,订单撮合过程发生在运行 handle_data 函数结束之后,是以历史实时行情进行的虚拟撮合。由于是对真实场景的模拟,所以订单并不会立刻以某个价格成交,而是通过和实时行情的具体价格和具体成交量进行比对,来断定成交价格和成交时间。
撮合机制遵循“先下单先处理,开盘价撮合”原则,即对先下单的订单先进行撮合尝试。

滑点

在真实的证券成交环境下,下单的点位和最终成交的点位往往有一定的偏差,在订单委托到市场后,会对市场的走向造成一定的影响,比如买单会提高市场价格,卖单会降低市场价格。这类冲击成本会造成滑点的出现。优矿为了更真实地模拟策略在真实市场的表现,在回测时提供了滑点模式,用于评估由于市场冲击和交易价格变化引起的交易成本变化。我们可以通过设置slippage关键字来设置具体的滑点信息,默认的滑点为0。

交易税费

交易税费主要包含券商手续费和印花税。优矿回测默认采用买入千分之一、卖出千分之二的税费。如果需要进行更加细微的调整,则可以通过设置回测初始化参数commission关键字来自定义税费信息。
◎ 券商手续费:券商征收的下单手续费,中国A股市场目前为双边收费,每个券商的手续费不同。
◎ 印花税:是国家强制征收的印花税,目前对卖方单边征收,对买方不再征收,为0.1%。

停牌退市

如果委托的订单在当天有停牌退市等不可以交易的情况,则订单会
被拒绝,变为废单。

涨跌停

如果委托的订单在当天一直涨停或者跌停,无法买入或卖出,则订单会一直处于挂单状态,直到收盘。

期货连续合约跳空处理

连续合约是由不同的合约拼合而成的,前后两个合约存在价差,所以连续合约有明显的价格跳空现象。在前后合约的价差比较大时,会引起策略出现假信号,造成信号失真。优矿提供了价差平移法和前复权法,对连续合约时间序列进行处理,减少假信号造成的影响,同时提供了合约指数,可以直接根据合约指数进行信号生成。

猜你喜欢

转载自blog.csdn.net/qq_47326711/article/details/126972962