【宽客学院】设置交易费率和价格


(iQuant) #1

AI量化策略开发第六步:回测 教程中,我们介绍了Trade回测/模拟交易模块的重要函数和策略构建的基本流程,本文主要介绍如何在Trade模块中设置手续费和滑点。

在评估策略的时候,我们设置一定的交易手续费和滑点以模拟真实交易。在策略编写中,我们通常在回测模块的初始化函数中进行设置。

一、设置手续费

通过调用set_commission方法,在初始化函数中加入如下代码块实现相应的功能:

股票,按成交金额百分比设置手续费,手续费不足5元按5元收取
# 示例代码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(futures_commission=PerContract(cost={'IF':(0.0023, 0.0015, 0.0023)})) 

二、设置滑点

通过调用FixedPriceSlippage方法,在初始化函数中加入如下代码块实现相应的功能:

固定百分比滑点模型

本例中根据用户设置的spreads值(价格滑点的百分比),实现在买单的下单价格基础上乘以(1.0 + spreads),在卖单的下单价格基础上乘以(1.0 - spreads)。在该例子中我们在定义滑点价格的时候指定了股票的买入价格为开盘价price_field_buy=‘open’, 卖出价位收盘价 price_field_sell=‘close’,如果您的策略买入价/卖出价的设置不是这样,请适当修改以保证和策略一致。
fix_slippage = FixedPriceSlippage(price_field_buy=‘open’, price_field_sell=‘close’,spreads=0.01)

    from zipline.finance.slippage import SlippageModel
    class FixedPriceSlippage(SlippageModel):
        # 指定初始化函数
        def __init__(self, spreads, price_field_buy, price_field_sell):
            self.spreads = spreads
            self._price_field_buy = price_field_buy
            self._price_field_sell = price_field_sell
        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_base = data.current(order.asset, price_field)
               # 买单的下单价格向上偏移 spreads百分比 , 卖单的下单价格向下偏移 spreads百分比
                price = price_base * (1.0 + self.spreads) if order.amount > 0 else price_base * (1.0 - self.spreads)
            else:
                price = order.limit
                # 返回希望成交的价格和数量
            return (price, order.amount)
    # 设置滑点模型
    fix_slippage = FixedPriceSlippage(price_field_buy='open', price_field_sell='close',spreads=0.01)
    context.set_slippage(us_equities=fix_slippage)
固定金额滑点模型

本例中根据用户设置的spreads值(价格滑点的百分比),实现在买单的下单价格基础上加上 spreads 元,在卖单的下单价格基础上减去spreads 元。在该例子中我们在定义滑点价格的时候指定了股票的买入价格为开盘价price_field_buy=‘open’,卖出价位收盘价 price_field_sell=‘close’,如果您的策略买入价/卖出价的设置不是这样,请适当修改以保证和策略一致。

from zipline.finance.slippage import SlippageModel
class FixedPriceSlippage(SlippageModel):
    # 指定初始化函数
    def __init__(self, spreads, price_field_buy, price_field_sell):
        self.spreads = spreads
        self._price_field_buy = price_field_buy
        self._price_field_sell = price_field_sell
    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_base = data.current(order.asset, price_field)
           # 买单的下单价格向上偏移 spreads元 , 卖单的下单价格向下偏移 spreads元
            price = price_base  + spreads  if order.amount > 0 else price_base  -  spreads
        else:
            price = order.limit
            # 返回希望成交的价格和数量
        return (price, order.amount)
# 设置滑点模型
fix_slippage = FixedPriceSlippage(price_field_buy='open', price_field_sell='close',spreads=0.01)
context.set_slippage(us_equities=fix_slippage)

三、设置期货保证金比率

通过调用 set_margin 方法,在初始化函数中加入如下代码块实现相应的功能:

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

四、指定成交价

有时我们希望标的按指定的下单价格成交,而不是默认设置的开盘价或收盘价。此时我们需要在初始化函数中改写 FixedPriceSlippage类,并在主函数中的下单函数中通过 设置limit_price限价功能。

初始化函数代码设置
# 示例代码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)
    # 设置price_field在[low,high]就能保证只要限价单价格在此范围都能成交,也符合实际情形
    context.fix_slippage = FixedPriceSlippage(price_field_buy='low', price_field_sell='high')
    context.set_slippage(us_equities=context.fix_slippage) # us是universe的简写,如果是期货,需要传入us_future
主函数中的下单示例
def handle_data(context, data):
    # 生成限价单,订单的限价为指定的价格,如果是买单,价格高于low就能成交,并且成交价为my_price,如果是卖单,价格低于high就能成交,成交价格为my_price
    sid = context.symbol('000001.SZA')
    context.order(sid, 200, limit_price=my_price)

结语:本文介绍了策略中常用的费率和成交价格设置功能,通过粘贴对应代码到Trade回测模块的初始化函数可以快速实现对应功能。