金叉死叉策略改动标的后,结果异常

策略分享
新手专区
标签: #<Tag:0x00007fcf699fae58> #<Tag:0x00007fcf699fad18>

(sorb_bigquant) #1

更改后策略:https://i.bigquant.com/user/sorb_bigquant/lab/share/金叉死叉策略%20提问.ipynb
@iQuant
根据量化学堂 金叉死叉策略做了一些改动,原策略地址:
[量化学堂-策略开发]金叉死叉策略

更改 内容:
@ 把标的改成了:instruments = [‘159920.OFA’]
@ 买入下单的形式改成: context.order_target_percent(sid, 1) # 买入

出现的问题:
@ 持仓比例超过100%,最后到1000+
@ 交易详情里只有两页,2012-11-28开始就没有交易了

我还想对交易引擎里的代码进行调试,比如查看以下变量的值:
short_mavg
long_mavg
cur_position
data.can_trade(sid)
如何在notebook的cell里面输入变量,然后ctrl+enter就可以查看他们的值。谢谢


(iQuant) #2

原因是这样的,该基金每天的价格就1元多,你如果下100万的超大单。系统判断你的订单太多,于是将其拆分到多天买入。所以你会发现不断交易的情形。你可以设置volume_limit=0这个参数屏蔽掉系统的这个订单量判断逻辑。

克隆策略

    {"Description":"实验创建于2017/12/13","Summary":"","Graph":{"EdgesInternal":[{"DestinationInputPortId":"-211:instruments","SourceOutputPortId":"-202:data"}],"ModuleNodes":[{"Id":"-202","ModuleId":"BigQuantSpace.instruments.instruments-v2","ModuleParameters":[{"Name":"start_date","Value":"2012-01-02","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"2017-12-12","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"market","Value":"CN_FUND","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"instrument_list","Value":"159920.OFA","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"max_count","Value":0,"ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"rolling_conf","NodeId":"-202"}],"OutputPortsInternal":[{"Name":"data","NodeId":"-202","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":1,"Comment":"","CommentCollapsed":true},{"Id":"-211","ModuleId":"BigQuantSpace.trade.trade-v3","ModuleParameters":[{"Name":"start_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"handle_data","Value":"# 回测引擎:每日数据处理函数,每天执行一次\ndef bigquant_run(context, data):\n \n if context.trading_day_index < context.long_period: # 长期均线值要有意义,需要在50根k线之后\n return\n \n k = context.instrument[0] # 标的为字符串格式\n sid = context.symbol(k) # 将标的转化为equity格式\n price = data.current(sid, 'price') # 最新价格\n \n short_mavg = data.history(sid, 'price',context.short_period, '1d').mean() # 短期均线值\n long_mavg = data.history(sid, 'price',context.long_period, '1d').mean() # 长期均线值\n\n cash = context.portfolio.cash # 现金\n cur_position = context.portfolio.positions[sid].amount # 持仓\n \n # 交易逻辑\n if short_mavg > long_mavg and cur_position == 0 and data.can_trade(sid): \n context.order_target_percent(sid, 1) # 买入\n \n elif short_mavg < long_mavg and cur_position > 0 and data.can_trade(sid): \n context.order_target_percent(sid, 0) # 全部卖出\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"prepare","Value":"# 回测引擎:准备数据,只执行一次\ndef bigquant_run(context):\n pass \n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"initialize","Value":"\n\n# 回测引擎:初始化函数,只执行一次\ndef bigquant_run(context):\n context.instrument = m1.data.read_pickle()['instruments'] \n context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5)) # 设置手续费\n context.short_period = 5 # 短期均线\n context.long_period = 50 # 长期均线 ","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"before_trading_start","Value":"# 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。\ndef bigquant_run(context, data):\n pass\n","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"volume_limit","Value":"0","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"order_price_field_buy","Value":"open","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"order_price_field_sell","Value":"open","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"capital_base","Value":1000000,"ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"benchmark","Value":"000300.SHA","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"auto_cancel_non_tradable_orders","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"data_frequency","Value":"daily","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"plot_charts","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"backtest_only","Value":"False","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"instruments","NodeId":"-211"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"options_data","NodeId":"-211"}],"OutputPortsInternal":[{"Name":"raw_perf","NodeId":"-211","OutputType":null}],"UsePreviousResults":false,"moduleIdForCode":2,"Comment":"","CommentCollapsed":true}],"SerializedClientData":"<?xml version='1.0' encoding='utf-16'?><DataV1 xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'><Meta /><NodePositions><NodePosition Node='-202' Position='86,52,200,200'/><NodePosition Node='-211' Position='168,157,200,200'/></NodePositions><NodeGroups /></DataV1>"},"IsDraft":true,"ParentExperimentId":null,"WebService":{"IsWebServiceExperiment":false,"Inputs":[],"Outputs":[],"Parameters":[{"Name":"交易日期","Value":"","ParameterDefinition":{"Name":"交易日期","FriendlyName":"交易日期","DefaultValue":"","ParameterType":"String","HasDefaultValue":true,"IsOptional":true,"ParameterRules":[],"HasRules":false,"MarkupType":0,"CredentialDescriptor":null}}],"WebServiceGroupId":null,"SerializedClientData":"<?xml version='1.0' encoding='utf-16'?><DataV1 xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'><Meta /><NodePositions></NodePositions><NodeGroups /></DataV1>"},"DisableNodesUpdate":false,"Category":"user","Tags":[],"IsPartialRun":false}
    In [30]:
    # 本代码由可视化策略环境自动生成 2017年12月13日 17:37
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
    
    
    m1 = M.instruments.v2(
        start_date='2012-01-02',
        end_date='2017-12-12',
        market='CN_FUND',
        instrument_list='159920.OFA',
        max_count=0
    )
    
    # 回测引擎:每日数据处理函数,每天执行一次
    def m2_handle_data_bigquant_run(context, data):
      
        if context.trading_day_index <  context.long_period:  # 长期均线值要有意义,需要在50根k线之后
            return
        
        k = context.instrument[0] # 标的为字符串格式
        sid = context.symbol(k) # 将标的转化为equity格式
        price = data.current(sid, 'price') # 最新价格
     
        short_mavg = data.history(sid, 'price',context.short_period, '1d').mean() # 短期均线值
        long_mavg = data.history(sid, 'price',context.long_period, '1d').mean() # 长期均线值
    
        cash = context.portfolio.cash # 现金
        cur_position = context.portfolio.positions[sid].amount # 持仓
        
        # 交易逻辑
        if short_mavg > long_mavg and cur_position == 0 and data.can_trade(sid):  
            context.order_target_percent(sid, 1) # 买入
            
        elif short_mavg < long_mavg and cur_position > 0 and data.can_trade(sid):  
            context.order_target_percent(sid, 0) # 全部卖出
    
    # 回测引擎:准备数据,只执行一次
    def m2_prepare_bigquant_run(context):
        pass 
    
    
    
    # 回测引擎:初始化函数,只执行一次
    def m2_initialize_bigquant_run(context):
        context.instrument = m1.data.read_pickle()['instruments'] 
        context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5)) # 设置手续费
        context.short_period = 5 # 短期均线
        context.long_period = 50 # 长期均线 
    # 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。
    def m2_before_trading_start_bigquant_run(context, data):
        pass
    
    m2 = M.trade.v3(
        instruments=m1.data,
        start_date='',
        end_date='',
        handle_data=m2_handle_data_bigquant_run,
        prepare=m2_prepare_bigquant_run,
        initialize=m2_initialize_bigquant_run,
        before_trading_start=m2_before_trading_start_bigquant_run,
        volume_limit=0,
        order_price_field_buy='open',
        order_price_field_sell='open',
        capital_base=1000000,
        benchmark='000300.SHA',
        auto_cancel_non_tradable_orders=True,
        data_frequency='daily',
        plot_charts=True,
        backtest_only=False
    )
    
    [2017-12-13 17:36:23.103125] INFO: bigquant: instruments.v2 开始运行..
    [2017-12-13 17:36:23.109366] INFO: bigquant: 命中缓存
    [2017-12-13 17:36:23.122993] INFO: bigquant: instruments.v2 运行完成[0.017852s].
    [2017-12-13 17:36:23.173432] INFO: bigquant: backtest.v7 开始运行..
    [2017-12-13 17:36:23.182210] INFO: bigquant: 命中缓存
    
    • 收益率27.81%
    • 年化收益率4.37%
    • 基准收益率71.2%
    • 阿尔法-0.01
    • 贝塔0.14
    • 夏普比率-0.0
    • 收益波动率13.04%
    • 信息比率-0.23
    • 最大回撤16.45%
    [2017-12-13 17:36:25.865340] INFO: bigquant: backtest.v7 运行完成[2.691916s].
    

    (sorb_bigquant) #3

    哦,原来如此,怪不得其他几个成交量大的ETF不会出现这种问题呢。
    还有volume_limit这个参数能再详细解释一下么?
    文档里:volume_limit (float) – 成交率限制:执行下单时控制成交量参数,默认值2.5%,若设置为0时,不进行成交量检查;默认值是0.025。
    是这么理解么:取默认值0.025时,如果下单金额超过当日成交量的0.25%,则剩下的订单推迟到第二天执行?


    (iQuant) #4

    yes!