上传了交割单CSV后,点击“运行全部”,提示错误,请协助

策略分享
标签: #<Tag:0x00007f4cdda5a9e8>

(hanjune) #1
克隆策略

成交单分析功能

版本v1.0

以"交割单模板.csv"为例,展示了成交单分析功能, 具体的csv文件格式可以参考帖子'交割单模板.csv'

1、成交单csv数据读取

输入:交割单模板.csv 指定:

  • 成交日期列的列名,本例的csv文件中日期列表头为"成交日期"
  • 证券代码列名,本例的csv文件中证券代码列表头为"证券代码"
  • 买卖标志列名,本例的csv文件中买卖标志列表头为"买卖标志"
  • 成交价格列名,本例的csv文件中成交价格列表头为"成交价格"
  • 成交数量列名,本例的csv文件中成交价格列表头为"成交数量"

此模块会将每日的交易记录读取至DataFrame,并将信号时间前移1天来实现模拟当日成交,输出股票代码列表、起止时间和前移1日后的交易信号数据(包括日期、代码、买卖方向、成交价格和数量)。

2、回测

  • 在初始化函数中,通过设置固定滑点模型实现按照指定价格交易,设置手续费
  • 在主函数中,首先获取当日的交易信号数据trade_data,然后针对每行交易信号数据执行买卖动作:

    context.order(context.symbol(trade_data['instrument'].iloc[i]), volume, limit_price=trade_data['trade_price'].iloc[i])

    即实现了对指定的一行交易记录的股票trade_data['instrument'].iloc[i],使用指定的价格trade_data['trade_price'].iloc[i],执行买入/卖出volume股的操作

  • 同时设置成交率限制为0,以保证所有下单能够成交。

3、下单检查

  • 我们通过回测结果中的交易详情可以看到每笔单子的下单时间、股票代码、买卖方向、成交数量、成交价和佣金。可以检查这些记录与成交单记录的csv文件的一致性。

4、 结果分析

  • 通过回测结果可以看到绩效曲线、成交记录和策略的阿尔法、夏普比率等统计指标;
  • 从画布左侧模块列表的“共享模块”列表中拖入 “最近N日绩效评估”、“Brinson绩效评估” 和 “每日持仓分析” 三个模块。运行后可以查看相关的阶段绩效、Brinson收益归因和每日持仓股票/行业等信息。
  • 通过调用m2.pyfolio_full_tear_sheet()查看收益分析,通过m2.risk_analyze()查看风险分析

    {"Description":"实验创建于2018/10/24","Summary":"","Graph":{"EdgesInternal":[{"DestinationInputPortId":"-6539:backtest_ds","SourceOutputPortId":"-1259:raw_perf"},{"DestinationInputPortId":"-6542:backtest_ds","SourceOutputPortId":"-1259:raw_perf"},{"DestinationInputPortId":"-320:backtest_ds","SourceOutputPortId":"-1259:raw_perf"},{"DestinationInputPortId":"-1259:instruments","SourceOutputPortId":"-129:instruments_ds"},{"DestinationInputPortId":"-1259:options_data","SourceOutputPortId":"-129:trading_records_ds"}],"ModuleNodes":[{"Id":"-1259","ModuleId":"BigQuantSpace.trade.trade-v4","ModuleParameters":[{"Name":"start_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"end_date","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"initialize","Value":"# 回测引擎:初始化函数,只执行一次\ndef bigquant_run(context):\n context.trade_data = context.options['data'].read_df()\n context.set_long_only()\n # 设置按制定价格交易\n from zipline.finance.slippage import SlippageModel\n class FixedPriceSlippage(SlippageModel):\n def process_order(self, data, order, bar_volume=0, trigger_check_price=0):\n if order.limit is None:\n price_field = self._price_field_buy if order.amount > 0 else self._price_field_sell\n price = data.current(order.asset, price_field)\n else:\n price = order.limit\n return (price, order.amount)\n fix_slippage = FixedPriceSlippage()\n fix_slippage._price_field_buy = 'low'\n fix_slippage._price_field_sell = 'high'\n fix_slippage = FixedPriceSlippage(price_field_buy='low', price_field_sell='high')\n context.set_slippage(us_equities=fix_slippage)\n context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"handle_data","Value":"# 回测引擎:每日数据处理函数,每天执行一次\ndef bigquant_run(context, data):\n # 按日期过滤得到今日收盘后的下单股票\n trade_data = context.trade_data[context.trade_data.date == data.current_dt.strftime('%Y-%m-%d')]\n\n for i in range(0, len(trade_data)):\n volume = trade_data['trade_volume'].iloc[i]\n if trade_data['side'].iloc[i] in ['BUY', '配售中签', '新股入帐']:\n pass\n elif trade_data['side'].iloc[i] == 'SELL':\n volume = -volume\n else:\n print('警告:未知的买卖标志 %s' % (trade_data['side'].iloc[i]))\n try:\n context.order(context.symbol(trade_data['instrument'].iloc[i]), volume, limit_price=trade_data['trade_price'].iloc[i])\n except Exception as e:\n #print('警告:%s' % (e))\n pass","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"prepare","Value":"# 回测引擎:准备数据,只执行一次\ndef bigquant_run(context):\n pass\n","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":"close","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"capital_base","Value":1000000,"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":"price_type","Value":"真实价格","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"product_type","Value":"股票","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"plot_charts","Value":"True","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"backtest_only","Value":"False","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"benchmark","Value":"","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"instruments","NodeId":"-1259"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"options_data","NodeId":"-1259"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"history_ds","NodeId":"-1259"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"benchmark_ds","NodeId":"-1259"},{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"trading_calendar","NodeId":"-1259"}],"OutputPortsInternal":[{"Name":"raw_perf","NodeId":"-1259","OutputType":null}],"UsePreviousResults":false,"moduleIdForCode":2,"IsPartOfPartialRun":null,"Comment":"","CommentCollapsed":true},{"Id":"-6539","ModuleId":"BigQuantSpace.N_days_performance_statistics.N_days_performance_statistics-v5","ModuleParameters":[{"Name":"N","Value":"5","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"backtest_ds","NodeId":"-6539"}],"OutputPortsInternal":[{"Name":"evaluation_of_perf_indicator","NodeId":"-6539","OutputType":null},{"Name":"analysis_of_stage_return_rat","NodeId":"-6539","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":5,"IsPartOfPartialRun":null,"Comment":"","CommentCollapsed":true},{"Id":"-6542","ModuleId":"BigQuantSpace.daily_position_analysis.daily_position_analysis-v6","ModuleParameters":[],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"backtest_ds","NodeId":"-6542"}],"OutputPortsInternal":[{"Name":"industry_market_value_daily","NodeId":"-6542","OutputType":null},{"Name":"top10_positions","NodeId":"-6542","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":6,"IsPartOfPartialRun":null,"Comment":"","CommentCollapsed":true},{"Id":"-129","ModuleId":"BigQuantSpace.order_record_input.order_record_input-v5","ModuleParameters":[{"Name":"trading_records_filename","Value":"sxtz.csv","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"date_col","Value":"","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"instrument_col","Value":"证券代码","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"side_col","Value":"买卖标志","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"trade_price_col","Value":"成交价格","ValueType":"Literal","LinkedGlobalParameter":null},{"Name":"trade_volume_col","Value":"成交数量","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[],"OutputPortsInternal":[{"Name":"instruments_ds","NodeId":"-129","OutputType":null},{"Name":"trading_records_ds","NodeId":"-129","OutputType":null}],"UsePreviousResults":false,"moduleIdForCode":4,"IsPartOfPartialRun":null,"Comment":"","CommentCollapsed":true},{"Id":"-320","ModuleId":"BigQuantSpace.Brinson.Brinson-v7","ModuleParameters":[{"Name":"benchmark","Value":"000300.HIX","ValueType":"Literal","LinkedGlobalParameter":null}],"InputPortsInternal":[{"DataSourceId":null,"TrainedModelId":null,"TransformModuleId":null,"Name":"backtest_ds","NodeId":"-320"}],"OutputPortsInternal":[{"Name":"perf_attribution","NodeId":"-320","OutputType":null}],"UsePreviousResults":true,"moduleIdForCode":1,"IsPartOfPartialRun":null,"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='-1259' Position='224,293,200,200'/><NodePosition Node='-6539' Position='-195,500,200,200'/><NodePosition Node='-6542' Position='554,514,200,200'/><NodePosition Node='-129' Position='239,105,200,200'/><NodePosition Node='-320' Position='188,509,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":true}
    In [5]:
    # 本代码由可视化策略环境自动生成 2019年11月5日 11:41
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
    
    
    # 回测引擎:初始化函数,只执行一次
    def m2_initialize_bigquant_run(context):
        context.trade_data = context.options['data'].read_df()
        context.set_long_only()
        # 设置按制定价格交易
        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)
        fix_slippage = FixedPriceSlippage()
        fix_slippage._price_field_buy = 'low'
        fix_slippage._price_field_sell = 'high'
        fix_slippage = FixedPriceSlippage(price_field_buy='low', price_field_sell='high')
        context.set_slippage(us_equities=fix_slippage)
        context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
    # 回测引擎:每日数据处理函数,每天执行一次
    def m2_handle_data_bigquant_run(context, data):
        # 按日期过滤得到今日收盘后的下单股票
        trade_data = context.trade_data[context.trade_data.date == data.current_dt.strftime('%Y-%m-%d')]
    
        for i in range(0, len(trade_data)):
            volume = trade_data['trade_volume'].iloc[i]
            if trade_data['side'].iloc[i] in ['BUY', '配售中签', '新股入帐']:
                pass
            elif trade_data['side'].iloc[i] == 'SELL':
                volume = -volume
            else:
                print('警告:未知的买卖标志 %s' % (trade_data['side'].iloc[i]))
            try:
                context.order(context.symbol(trade_data['instrument'].iloc[i]), volume, limit_price=trade_data['trade_price'].iloc[i])
            except Exception as e:
                #print('警告:%s' % (e))
                pass
    # 回测引擎:准备数据,只执行一次
    def m2_prepare_bigquant_run(context):
        pass
    
    # 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。
    def m2_before_trading_start_bigquant_run(context, data):
        pass
    
    
    m4 = M.order_record_input.v5(
        trading_records_filename='sxtz.csv',
        date_col='',
        instrument_col='证券代码',
        side_col='买卖标志',
        trade_price_col='成交价格',
        trade_volume_col='成交数量',
        m_cached=False
    )
    
    m2 = M.trade.v4(
        instruments=m4.instruments_ds,
        options_data=m4.trading_records_ds,
        start_date='',
        end_date='',
        initialize=m2_initialize_bigquant_run,
        handle_data=m2_handle_data_bigquant_run,
        prepare=m2_prepare_bigquant_run,
        before_trading_start=m2_before_trading_start_bigquant_run,
        volume_limit=0,
        order_price_field_buy='open',
        order_price_field_sell='close',
        capital_base=1000000,
        auto_cancel_non_tradable_orders=True,
        data_frequency='daily',
        price_type='真实价格',
        product_type='股票',
        plot_charts=True,
        backtest_only=False,
        benchmark=''
    )
    
    m5 = M.N_days_performance_statistics.v5(
        backtest_ds=m2.raw_perf,
        N=5
    )
    
    m6 = M.daily_position_analysis.v6(
        backtest_ds=m2.raw_perf
    )
    
    m1 = M.Brinson.v7(
        backtest_ds=m2.raw_perf,
        benchmark='000300.HIX'
    )
    

    成交单csv数据读取(order_record_input)使用错误,你可以:

    1.一键查看文档

    2.一键搜索答案

    ---------------------------------------------------------------------------
    ValueError                                Traceback (most recent call last)
    <ipython-input-5-6d100045c879> in <module>()
         57     trade_price_col='成交价格',
         58     trade_volume_col='成交数量',
    ---> 59     m_cached=False
         60 )
         61 
    
    ValueError: '' is not in list

    Pyfolio收益分析

    In [ ]:
    m2.pyfolio_full_tear_sheet()
    

    risk_analyze风险分析

    In [ ]:
    m2.risk_analyze()
    

    (iQuant) #2

    收到提问,已提交至策略工程师,会尽快给您回复。


    (达达) #3

    csv文件成交日期列前面有个空格删一下


    (hanjune) #4

    image
    删除了之后,显示这个错误


    (达达) #5

    去除一下缓存呢


    (hanjune) #6

    怎么去除缓存呀?我删除了新建一个,也重启过内核,也试过重新上传csv,还是不行哦。故障如#4


    (达达) #7

    单击一下m4,右侧属性栏中有个红色对号,去掉此对号试一下


    (hanjune) #8

    你的意思是“启用缓存加速”的勾选吗?没有勾选呀


    (yjz_quanter) #9

    遇到了同样的问题,请工程师帮忙解决下.


    (达达) #10

    是因为模块默认gbk编码的问题,上传文件默认是utf8的文件,我们修复一下


    (hanjune) #11

    好的,修复后麻烦在此贴留言告知,谢谢你


    (iQuant) #12

    已修复 可以再试一下哈。