历史文档

【历史文档】策略回测-常用设置

由qxiao创建,最终由small_q 被浏览 567 用户

更新

本文内容对应旧版平台与旧版资源,其内容不再适合最新版平台,请查看新版平台的使用说明

新版量化开发IDE(AIStudio):

https://bigquant.com/wiki/doc/aistudio-aiide-NzAjgKapzW

新版模版策略:

https://bigquant.com/wiki/doc/demos-ecdRvuM1TU

新版数据平台:

https://bigquant.com/data/home

https://bigquant.com/wiki/doc/dai-PLSbc1SbZX

新版表达式算子:

https://bigquant.com/wiki/doc/dai-sql-Rceb2JQBdS

新版因子平台:

https://bigquant.com/wiki/doc/bigalpha-EOVmVtJMS5

\

set_commission

定义

set_commission(per_order)

手续费设置, 在initialize方法中调用。默认状态下,是股票交易设置手续费的API,买入时手续费为成交金额的万分之3,卖出时手续费为成交金额的千分之1.3,手续费不足5元按5元收取。 此外,还可以通过PerShare和PerTrade设置手续费。 手续费设置可以动态调整,比如股指期货我们可以在不同的交易日设置不同的手续费,以便回测更能接近真实情形。

参数

per_order – PerOrder对象 或者PerTrade对象 或者PerShare对象

示例代码

# 示例代码1
def initialize(context):
    # buy_cost,买入时手续费
    # sell_cost,卖出时手续费
    # min_cost,最少的手续费
    # 买入时手续费为成交金额的万分之3,卖出时手续费为成交金额的千分之1.3,手续费不足5元按5元收取。
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))

# 示例代码2
def initialize(context):
    # 股票成交时,手续费按成交次数收取,每一次成交收取5元手续费
    context.set_commission(PerTrade(5))

# 示例代码3
def initialize(context):
    # 股票成交时,手续费按成交金额一定比例收取,手续费为成交金额的千分之一
    context.set_commission(PerShare(0.001))

# 上面三个例子都是股票交易时如何设置手续费,如果是期货交易的话,可以参照如下示例代码设置
# 示例代码4
def initialize(context):
    context.set_commission(futures_commission=PerContract(cost={'IF':(0.0023, 0.0015, 0.0023)})) 

\

set_slippage

定义

set_slippage(slippage)

滑点设置, 只能在initialize方法中调用,定义在策略中的其他位置则无效。当您下单交易时,您的订单将影响市场。您的买单驱使价格上涨,您的卖单驱使价格下滑;这通常被称为您的交易的“价格影响”。价格影响的大小取决于您的订单与当前交易量相比有多大。如果您的订单太大,那么滑点方法也会进行评估:您的交易量不能超过市场的容量,通常您也不能期望交易量超过一小部分(比如百分之5,举牌)。所有这些概念都被封装在了set_slippage方法中。当订单因为不满足滑点条件没有完全成交,未成交的部分仍然可以在第二天继续成交。这会持续直到订单完全成交或被取消。

如果您没有指定set_slippage方式,则滑点默认为VolumeShareSlippage(volume_limit = 0.025,price_impact = 0.1)(您最多可以占用单支股票交易量的2.5%)。

滑点模型是通过set_slippage完成的,目前有:FixedBasisPointsSlippage、FixedSlippage、VolumeShareSlippage,同时,也可以自定义滑点模型。

FixedBasisPointsSlippage

\

固定基点滑点

context.slippage.FixedBasisPointsSlippage(basis_points=5, volume_limit=0.1)

参数

basis_point - 基点滑点 volume_limit - 成交量最大限制,默认为0.1,即10%

如果基点等于5,即0.05%,如果订单是买单,那么实际成交价是名义成交价的1*(1+0.05%)倍,如果订单是卖单,实际成交价是名义成交价的1*(1-0.05%)。比如名义成交价是100元,那么买单的成交价是100.05,卖单的成交价是99.95。 成交量最大限制参数确定了当根Bar最大能成交多少数量。举例,下单量是220手,volume_limit=0.1,接下来每根Bar成交量是1000手,在这种情形下,220手的订单会拆分为3笔成交(100手、100手、20手)分别在接下来三根Bar上完成撮合成交。 如果volume_limit=1.00,那么在接下来的一根Bar上最大可以成交1000手,因此220手的订单可以直接一下子成交,无须拆单。

VolumeShareSlippage

\

成交量比例滑点

context.slippage.VolumeShareSlippage(volume_limit=0.025, price_impact=0.1)

参数

volume_limit - 成交量最大限制,默认为0.025 price_impact - 价格影响幅度,默认为0.1 volume_limit参数含义同上,可以参考FixedBasisPointsSlippage。比如,当前下单的订单数量是60手,接下来的几根Bar的成交量都是1000手,那么在0.025的默认值下,订单会被拆分为25、25、10依次成交。 price_impact衡量的是滑点对价格的影响幅度,默认值为0.1,滑点的计算为:price_impact*(实际成交量/总成交量)^2 在前面的例子中,25手的单子的价格影响为:0.1*(25/1000)(25/1000)=0.00625%,对于10手的订单,价格影响为:0.1*(10/1000)*(10/1000)=0.001%。

固定滑点

context.slippage.FixedSlippage(spresd)

参数

spread - 价差

当采取固定滑点模型时,订单量的大小并不会影响撮合时的价格,但是蕴含假设为,下单时买一和卖一的价差-spread会影响价格。如果是买单,那么实际成交价为名义成交价+0.5spread,如果是卖单,那么实际成交价为名义成交价-0.5spread。

自定义滑点

您也可以构建一个自定义滑点模型,该模型使用您自己的逻辑将订单流转换为交易流。在initialize()函数中,您必须指定要使用的滑点模型和滑点模型将使用的任何特殊参数。您的自定义模型必须是一个继承自slippage.SlippageModel并实现process_order(self,data,order)函数的类。process_order方法必须返回一个元素(execution_price, execution_volume),它表示模型想要生成的交易价格和交易量。然后为您创建交易。具体使用请参考示例代码。

示例代码

# 示例代码1
# 自定义滑点模型
class PerStockSpreadSlippage(slippage.SlippageModel):
    # 指定初始化函数
    def __init__(self, spreads):
        # 存储spread的字典,用股票代码作为key
        self.spreads = spreads

    def process_order(self, data, my_order):
        spread = self.spreads[my_order.sid]
        price = data.current(my_order.sid, 'price')

        # 在这个模型中滑点是spread的一半
        slip_amount = spread / 2

        # 计算交易的价格影响,价格影响跟订单交易方向有关,买单会增加价格,而卖单会减少价格。
        new_price = price + (slip_amount * my_order.direction)

        return (new_price, my_order.amount)

def initialize(context):
    # 限制每单交易不超过单只股票交易额的 1%,若超过会进行分单处理,即订单不是一次性成交完毕,而是多日完成。
    context.set_slippage(VolumeShareSlippage(volume_limit=0.01))
    # 固定滑点模型,下一个买单时,价格会加0.5;而下一个卖单时,价格会减0.5。
    context.set_slippage(FixedSlippage(spread=1.00))
    context.spreads = {
        context.symbol('000001.SZA'): 0.05
    }
    # 使用自定义的滑点模型
    context.set_slippage(PerStockSpreadSlippage(context.spreads))
# 示例代码2 
# 按指定价格成交
def initialize(context):
    from zipline.finance.slippage import SlippageModel
        class FixedPriceSlippage(SlippageModel):
            def process_order(self, data, order, bar_volume=0, trigger_check_price=0):
                if order.limit is None:
                    price_field = self._price_field_buy if order.amount > 0 else self._price_field_sell
                    price = data.current(order.asset, price_field)
                else:
                    price = order.limit
                # 返回希望成交的价格和数量
                return (price, order.amount)
        context.fix_slippage = FixedPriceSlippage()
        # 设置price_field,在没有指定成交价格时,开盘价买入,收盘价卖出
        context.fix_slippage = FixedPriceSlippage(price_field_buy='open', price_field_sell='close')
        context.set_slippage(us_futures=fix_slippage) # us是universe的简写,如果是股票,需要传入us_equities

def handle_data(context, data):
    # 生成限价单,订单的限价为指定的价格,如果是买单,价格高于low就能成交,并且成交价为my_price,如果是卖单,价格低于high就能成交,成交价格为my_price
    sid = context.future_symbol('RB1901.SHF')
    context.order(sid, 2, limit_price=my_price)

\

set_long_only

定义

set_long_only

回测设置只允许做多,不允许做空

示例代码

def initialize(context):
    # 如果下一个订单,导致当前持股为负,则策略会抛出一个异常
    context.set_long_only()

\

set_max_leverage

定义

set_max_leverage(max_leverage)

设置策略的最大杠杆限制

参数

max_leverage – float,策略允许的最大杠杆,若没有设置则没有最大限制

示例代码

from zipline.api import set_max_leverage
def initialize(context):
    context.set_max_leverage(1)

\

set_need_settle

定义

set_need_settle(need_settle)

期货策略设置是否每日结算

参数

need_settle – bool,如果product_type为期货;默认为True,否则为False

示例代码

def initialize(context):
    context.set_need_settle(False)

\

set_margin

定义

set_margin(security_code, margin)

设置期货品种的保证金比率,支持国内四大期货交易所,每个品种的默认设置请参考表《期货基本信息表》

参数

security_code – str,期货品种 margin - float,保证金比率,数值在0-1之间

示例代码

def initialize(context):
    context.set_margin('RB', 0.1)

\

set_benchmark

定义

set_benchmark(benchmark)

设置策略基准。

参数

benchmark – Asset,这个资产将成为新的策略基准

示例代码

def initialize(context):
    context.set_benchmark(context.symbol('000903.SHA'))

\

set_max_order_count

定义

set_max_order_count(max_count, on_error=’fail’)

设置在某一天可以提交的order数量上限

参数

max_count – int,在某一天可以提交的order数量上限

示例代码

from zipline.api import set_max_order_count
def initialize(context):
    context.set_max_order_count(10)

\

set_max_order_size

定义

set_max_order_size(asset=None, max_shares=None,max_notional=None,on_error=’fail’)

设置在某一天可以提交的order上限。

参数

asset – Asset, optional,如果这个参数提供,则保证头寸限制规则只用在这个资产上 max_shares – int,optional,单次order最大股票数量上限 max_notional – float,单次order最大现金

示例代码

def initialize(context):
    context.set_max_order_size(max_notional=4000)

\

set_max_position_size

定义

set_max_position_size(asset=None,max_shares=None,max_notional=None, on_error=’fail’)

针对某一头寸设置最大股票数量或最大头寸金额

参数

asset – Asset, optional,如果这个参数提供,则保证头寸限制规则只用在这个资产上

max_shares –int,optional,单次头寸最大股票数量上限

max_notional – float,单个头寸最大金额

示例代码

def initialize(context):
    context.set_max_position_size(max_notional=4000)

\

周期执行调度函数

如果每根Bar不一定都要运行一下主函数(handle_data),因此你的策略可以回测的更快。比如按月调仓的多因子选股策略,只需要在特定的Bar上运行handle_data主函数,为此,平台提供了schedule_function这一周期执行调度函数。 不仅如此,周期执行调度函数还使用了日期和时间规则,以便更加灵活和高效。所有的周期执行调度函数都在初始化函数(initialize)中进行定义。

定义

schedule_function(func, date_rule, time_rule)

周期执行调度函数,在符合date_rule, time_rule下周期性执行,需在 initialize 函数中调用。如果initialize中调用了schedule_function函数,那么算法会按照date_rule和time_rule周期性执行func函数,如果没有调用schedule_function函数,则算法会每个单位时间调用handle_data函数。

参数

func – 被调用函数,包含两个参数 context 和 data,同handle_data date_rule – 日期规则,通过date_rules下的方法可获取,后面会给出具体详情 time_rule – 时间规则,通过time_rules下的方法可获取,后面会给出具体详情

月度执行调度模型(month_start和month_end)正如字面含义,决定了在哪些日期点上运行,比如month_start表明在每个月月初第一天运行func,month_end表明在月末最后一天运行func。 可以传入参数——days_offset,默认该参数为0,该参数可以理解成一个时间偏移量,month_start(1)表明在该月第二个交易日运行func,依此类推,如果该参数超过当月交易日,那么该函数在该月就不会运行func。

示例代码

def initialize(context):
    schedule_function(func=rebalance,
        date_rule=date_rules.week_start(),   # 例如每周开始时执行一次
        time_rule=time_rules.market_open(hours=1))   # 开盘后一个小时执行

def rebalance(context, data):
    # 策略交易逻辑和订单生成在此部分构建,代替了handle_data函数
    pass

下面是日期规则和时间规则的两幅截图

 {w:100}{w:100}{w:100}  {w:100}{w:100}{w:100}

日期规则

定义

date_rule

在固定的日期规则下调用func函数,func为被调用函数,func函数需要传入context和data,用法同handle_data

示例代码

# 每天调用一次func函数
schedule_function(func=rebalance, date_rule=date_rules.every_day())

# 每周开始时调用一次func函数,默认为days_offset=0,该周交易日的第一天调用
schedule_function(func=rebalance, date_rule=date_rules.week_start())

# 每周开始时调用一次func函数,days_offset=1表示该周交易日的第二天调用,以此类推
schedule_function(func=rebalance, date_rule=date_rules.week_start(days_offset=1))

# 每月开始时调用一次func函数,days_offset默认为0,表示每个月交易日的第一天
schedule_function(func=rebalance, date_rule=date_rules.month_start())

# 每周结束时调用一次func函数,days_offset=0表示该周交易日的最后一天调用
schedule_function(func=rebalance, date_rule=date_rules.week_end())

# 每月结束时调用一次func函数,days_offset默认为0,表示每个月交易日的最后一天
schedule_function(func=rebalance, date_rule=date_rules.month_end())

\

时间规则

定义

time_rule

在固定的时间规则下调用func函数

market_open表明开盘时调用func,如果没有偏移,默认为开盘后一分钟调用func

market_close表明收盘时调用func,如果没有偏移,默认为收盘前两分钟调用func

示例代码

# 每日开盘后1小时30分钟调用func
schedule_function(func=rebalance, date_rules.every_day(), time_rule=time_rules.market_open(hours=1, minutes=30))
# 每日收盘前5分钟调用func
schedule_function(func=rebalance, date_rules.every_day(), time_rule=time_rules.market_close(minutes=5))

\

多个周期执行调度函数

可以使用多个周期执行调度函数,比如在月初和月中都调用下换仓函数。 示例代码

def initialize(context):
  # 在每个月的第二个交易日执行
  schedule_function(
    rabalance,
    date_rules.month_start(days_offset=1)
  )

  # 在每个月的第十个交易日执行
  schedule_function(
    rebalance,
    date_rules.month_start(days_offset=9)
  )

def myfunc(context,data):
    pass

\

期货基本信息表

序号 合约品种 交易所 交易所编码 名称 价格最小单位 乘数 保证金率 手续费计算方式 平昨手续费率 平今手续费率 开仓手续费率
1 A DCE DCE 豆一 1 10 0.09 按数量 2 0 2
2 AG SHFE SHF 白银 1 15 0.12 按金额 0.00005 0.00005 0.00005
3 AL SHFE SHF 沪铝 5 5 0.08 按数量 3 0 3
4 AU SHFE SHF 黄金 0.05 1000 0.08 按数量 10 0 10
5 AP CZCE CZC 苹果 1 10 0.08 按数量 0.5 0 0.5
6 B DCE DCE 豆二 1 10 0.08 按数量 2 2 2
7 BB DCE DCE 胶板 0.05 500 0.4 按金额 0.0001 0.00005 0.0001
8 BU SHFE SHF 沥青 2 10 0.1 按金额 0.0001 0.0001 0.0001
9 C DCE DCE 玉米 1 10 0.08 按数量 1.2 0 1.2
10 CF CZCE CZC 棉花 5 5 0.07 按数量 4.3 0 4.3
11 CS DCE DCE 淀粉 1 10 0.07 按数量 1.5 0 1.5
12 CU SHFE SHF 沪铜 10 5 0.08 按金额 0.000025 0 0
13 CY CZCE CZC 棉纱 5 5 0.07 按数量 4 4 4
14 FB DCE DCE 纤板 0.05 500 0.1 按金额 0.00005 0 0.00005
15 FG CZCE CZC 玻璃 1 20 0.06 按数量 3 0 3
16 FU SHFE SHF 燃油 1 50 0.1 按金额 0.00002 0.00002 0.00002
17 HC SHFE SHF 热卷 1 10 0.08 按金额 0.00001 0.00001 0.00001
18 I DCE DCE 铁矿 0.5 100 0.11 按金额 0.00006 0.00003 0.00006
19 IC CFFEX CFE 中证500 0.2 200 0.3 按金额 0.000023 0.000115 0.000023
20 IF CFFEX CFE 沪深300 0.2 300 0.2 按金额 0.000023 0.000115 0.000023
21 IH CFFEX CFE 上证50 0.2 300 0.2 按金额 0.000023 0.000115 0.000023
22 J DCE DCE 焦炭 0.5 100 0.09 按金额 0.00006 0.00003 0.00006
23 JD DCE DCE 鸡蛋 1 10 0.07 按金额 0.00015 0.00015 0.00015
24 JM DCE DCE 焦煤 0.5 60 0.09 按金额 0.00006 0.00003 0.00006
25 JR CZCE CZC 粳稻 1 20 0.05 按数量 3 3 3
26 L DCE DCE 塑料 5 5 0.11 按数量 2 0 2
27 LR CZCE CZC 晚稻 1 20 0.05 按数量 3 0 3
28 M DCE DCE 豆粕 1 10 0.05 按数量 1.5 0 1.5
29 MA CZCE CZC 甲醇 1 10 0.07 按数量 1.4 0 1.4
30 NI SHFE SHF 沪镍 10 1 0.1 按数量 6 6 6
31 OI CZCE CZC 菜油 2 10 0.06 按数量 2.5 0 2.5
32 P DCE DCE 棕榈 2 10 0.05 按数量 2.5 0 2.5
33 PB SHFE SHF 沪铅 5 5 0.08 按金额 0.00004 0 0.00004
34 PM CZCE CZC 普麦 1 50 0.06 按数量 5 5 5
35 PP DCE DCE 聚丙烯 1 5 0.05 按金额 0.00005 0.000025 0.00005
36 RB SHFE SHF 螺纹 1 10 0.08 按金额 0.000045 0 0.000045
37 RI CZCE CZC 早稻 1 20 0.05 按数量 2.5 2.5 2.5
38 RM CZCE CZC 菜粕 1 10 0.06 按数量 1.5 0 1.5
39 RS CZCE CZC 菜籽 1 10 0.2 按数量 2 2 2
40 RU SHFE SHF 橡胶 5 10 0.08 按金额 0.000045 0.000045 0.000045
41 SF CZCE CZC 硅铁 2 5 0.07 按数量 3 0 3
42 SM CZCE CZC 锰硅 2 5 0.07 按数量 3 0 3
43 SN SHFE SHF 沪锡 10 1 0.08 按数量 3 0 3
44 SR CZCE CZC 白糖 1 10 0.07 按数量 3 0 3
45 T CFFEX CFE 债十 0.005 10000 0.02 按数量 3 0 3
46 TA CZCE CZC PTA 2 5 0.06 按数量 3 3 3
47 TF CFFEX CFE 债五 0.005 10000 0.012 按数量 3 3 3
48 V DCE DCE PVC 5 10000 0.09 按数量 2 0 2
49 WH CZCE CZC 强麦 1 20 0.05 按数量 2.5 0 2.5
50 WR SHFE SHF 线材 1 10 0.08 按金额 0.00004 0.00004 0.00004
51 Y DCE DCE 豆油 2 10 0.08 按数量 2.5 0 2.5
52 ZC CZCE CZC 郑煤 0.2 100 0.05 按数量 4 0 4
53 ZN SHFE SHF 沪锌 5 5 0.08 按数量 3 0 3
54 SC INE INE 原油 0.1 1000 0.05 按金额 0.0001 0.0001 0.0001




\

标签

股票交易API

文档

【历史文档】策略回测-策略回测结果指标详解【历史文档】策略回测-如何在策略中设置滑点设置回测基准期货案例【历史文档】策略回测-WAP价格回测功能【历史文档】策略回测-设置回测基准设置回测基准 (副本)
{link}