克隆策略

    {"description":"实验创建于2017/11/22","graph":{"edges":[{"to_node_id":"-8687:input_1","from_node_id":"-8421:data"},{"to_node_id":"-8692:instruments","from_node_id":"-8421:data"},{"to_node_id":"-8692:options_data","from_node_id":"-8687:data_1"}],"nodes":[{"node_id":"-8421","module_id":"BigQuantSpace.instruments.instruments-v2","parameters":[{"name":"start_date","value":"2016-01-01","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"2017-11-21","type":"Literal","bound_global_parameter":null},{"name":"market","value":"CN_STOCK_A","type":"Literal","bound_global_parameter":null},{"name":"instrument_list","value":"000001.SZA\n000002.SZA\n000089.SZA\n000333.SZA\n600519.SZA\n601198.SHA\n002310.SZA\n601998.SHA\n601377.SHA\n601966.SHA\n000728.SZA\n601766.SHA\n600660.SHA\n002450.SZA\n600600.SHA\n600030.SHA\n000898.SZA\n002508.SZA \n601888.SHA","type":"Literal","bound_global_parameter":null},{"name":"max_count","value":0,"type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"rolling_conf","node_id":"-8421"}],"output_ports":[{"name":"data","node_id":"-8421"}],"cacheable":true,"seq_num":1,"comment":"","comment_collapsed":true},{"node_id":"-8687","module_id":"BigQuantSpace.cached.cached-v3","parameters":[{"name":"run","value":"def add_column(df, series, name):\n df[name] = series\n return df\n# 计算atr函数\ndef atr(high,low,close,window):\n a=high-low\n b=np.abs(close.shift(1)-high)\n c=np.abs(close.shift(1)-low)\n tr=a.where(a>b,b)\n tr=tr.where(tr>c,c)\n return tr.rolling(window).mean()\n\n# Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端\ndef bigquant_run(input_1, input_2, input_3):\n # 示例代码如下。在这里编写您的代码\n df = input_1.read_pickle()\n \n start_date = df['start_date']\n end_date = df['end_date']\n fields = ['open','high','low','close']\n instruments = df['instruments']\n data = D.history_data(instruments, start_date, end_date, fields)\n atr_data = data.groupby('instrument').apply(lambda x:add_column(x,atr(x.high,x.low,x.close,20),'ATR')).set_index('date') \n data = DataSource.write_df(atr_data)\n return Outputs(data_1=data, data_2=None, data_3=None)\n","type":"Literal","bound_global_parameter":null},{"name":"post_run","value":"# 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。\ndef bigquant_run(outputs):\n return outputs\n","type":"Literal","bound_global_parameter":null},{"name":"input_ports","value":"","type":"Literal","bound_global_parameter":null},{"name":"params","value":"{}","type":"Literal","bound_global_parameter":null},{"name":"output_ports","value":"","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_1","node_id":"-8687"},{"name":"input_2","node_id":"-8687"},{"name":"input_3","node_id":"-8687"}],"output_ports":[{"name":"data_1","node_id":"-8687"},{"name":"data_2","node_id":"-8687"},{"name":"data_3","node_id":"-8687"}],"cacheable":true,"seq_num":2,"comment":"","comment_collapsed":true},{"node_id":"-8692","module_id":"BigQuantSpace.trade.trade-v3","parameters":[{"name":"start_date","value":"","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"","type":"Literal","bound_global_parameter":null},{"name":"handle_data","value":"# 回测引擎:每日数据处理函数,每天执行一次\ndef bigquant_run(context, data):\n \n dt = data.current_dt.strftime('%Y-%m-%d') # \n for i in context.instruments:\n # 当天没有该股票的ATR数据就continue \n try:\n atr = context.atr_data.loc[dt].set_index('instrument').loc[i]['ATR']\n except KeyError:\n continue\n # 如果该股票的ATR为nan或者为0,就填充其为100 \n if numpy.isnan(atr) == False and atr != 0:\n a_unit = int(context.portfolio.portfolio_value*0.01/atr)\n else:\n a_unit = 100\n \n sid = context.symbol(i)\n price = data.current(sid, 'price') \n high_point = data.history(sid, 'high', context.entry_pos_period, '1d').max()\n low_point = data.history(sid, 'low', context.exit_pos_period, '1d').min()\n stock_hold_now = [equity.symbol for equity in context.portfolio.positions]\n \n # 计算加仓点和止损点\n if i in stock_hold_now:\n add_pos_point = context.portfolio.positions[sid].last_sale_price+0.5*atr\n stop_loss_point = context.portfolio.positions[sid].last_sale_price-2*atr\n else:\n add_pos_point = np.nan\n stop_loss_point = np.nan\n # 卖出逻辑和加仓逻辑\n if i in stock_hold_now:\n # 是否需要止损\n if price<stop_loss_point and context.portfolio.positions[sid].amount>0 and data.can_trade(sid):\n order_target_value(sid, 0)\n context.unit_remark[i] = 0\n # 是否需要出场 \n if price<low_point and context.portfolio.positions[sid].amount>0 and data.can_trade(sid):\n order_target_value(sid, 0) \n context.unit_remark[i] = 0\n # 是否需要加仓,超过4 unit就不加仓了\n if price>add_pos_point and context.portfolio.positions[sid].amount>0 and data.can_trade(sid) and context.unit_remark[i]<4:\n order(sid, a_unit)\n context.unit_remark[i] = context.unit_remark[i]+1\n else:\n pass\n # 买入逻辑\n if price>high_point and context.portfolio.positions[sid].amount==0 and data.can_trade(sid):\n order(sid, a_unit)\n context.unit_remark[i] = 1\n else:\n pass\n \n","type":"Literal","bound_global_parameter":null},{"name":"prepare","value":"# 回测引擎:准备数据,只执行一次\ndef bigquant_run(context):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"initialize","value":"# 回测引擎:初始化函数,只执行一次\ndef bigquant_run(context):\n \n context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))\n context.entry_pos_period = 55\n context.exit_pos_period = 20\n context.unit_remark = {}\n context.atr_data = context.options['data'].read_df()\n context.instruments = m1.data.read_pickle()['instruments']\n \n \n","type":"Literal","bound_global_parameter":null},{"name":"before_trading_start","value":"# 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。\ndef bigquant_run(context, data):\n pass\n","type":"Literal","bound_global_parameter":null},{"name":"volume_limit","value":"0","type":"Literal","bound_global_parameter":null},{"name":"order_price_field_buy","value":"open","type":"Literal","bound_global_parameter":null},{"name":"order_price_field_sell","value":"open","type":"Literal","bound_global_parameter":null},{"name":"capital_base","value":"10000000","type":"Literal","bound_global_parameter":null},{"name":"benchmark","value":"000300.SHA","type":"Literal","bound_global_parameter":null},{"name":"auto_cancel_non_tradable_orders","value":"True","type":"Literal","bound_global_parameter":null},{"name":"data_frequency","value":"daily","type":"Literal","bound_global_parameter":null},{"name":"price_type","value":"后复权","type":"Literal","bound_global_parameter":null},{"name":"plot_charts","value":"True","type":"Literal","bound_global_parameter":null},{"name":"backtest_only","value":"False","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-8692"},{"name":"options_data","node_id":"-8692"}],"output_ports":[{"name":"raw_perf","node_id":"-8692"}],"cacheable":false,"seq_num":3,"comment":"","comment_collapsed":true}],"node_layout":"<node_postions><node_position Node='-8421' Position='-7,-30,200,200'/><node_position Node='-8687' Position='288,154,200,200'/><node_position Node='-8692' Position='297,407,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
    In [4]:
    # 本代码由可视化策略环境自动生成 2021年10月16日 11:52
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
    
    
    def add_column(df, series, name):
        df[name] = series
        return df
    # 计算atr函数
    def atr(high,low,close,window):
        a=high-low
        b=np.abs(close.shift(1)-high)
        c=np.abs(close.shift(1)-low)
        tr=a.where(a>b,b)
        tr=tr.where(tr>c,c)
        return tr.rolling(window).mean()
    
    # Python 代码入口函数,input_1/2/3 对应三个输入端,data_1/2/3 对应三个输出端
    def m2_run_bigquant_run(input_1, input_2, input_3):
        # 示例代码如下。在这里编写您的代码
        df = input_1.read_pickle()
        
        start_date = df['start_date']
        end_date = df['end_date']
        fields = ['open','high','low','close']
        instruments =  df['instruments']
        data = D.history_data(instruments, start_date, end_date, fields)
        atr_data  = data.groupby('instrument').apply(lambda x:add_column(x,atr(x.high,x.low,x.close,20),'ATR')).set_index('date')  
        data = DataSource.write_df(atr_data)
        return Outputs(data_1=data, data_2=None, data_3=None)
    
    # 后处理函数,可选。输入是主函数的输出,可以在这里对数据做处理,或者返回更友好的outputs数据格式。此函数输出不会被缓存。
    def m2_post_run_bigquant_run(outputs):
        return outputs
    
    # 回测引擎:每日数据处理函数,每天执行一次
    def m3_handle_data_bigquant_run(context, data):
        
        dt = data.current_dt.strftime('%Y-%m-%d') #  
        for i in context.instruments:
            # 当天没有该股票的ATR数据就continue 
            try:
                atr = context.atr_data.loc[dt].set_index('instrument').loc[i]['ATR']
            except KeyError:
                continue
            # 如果该股票的ATR为nan或者为0,就填充其为100    
            if numpy.isnan(atr) == False and atr != 0:
                a_unit = int(context.portfolio.portfolio_value*0.01/atr)
            else:
                a_unit = 100
                
            sid = context.symbol(i)
            price = data.current(sid, 'price')  
            high_point = data.history(sid, 'high', context.entry_pos_period, '1d').max()
            low_point = data.history(sid, 'low', context.exit_pos_period, '1d').min()
            stock_hold_now = [equity.symbol for equity in context.portfolio.positions]
            
            # 计算加仓点和止损点
            if i in stock_hold_now:
                add_pos_point = context.portfolio.positions[sid].last_sale_price+0.5*atr
                stop_loss_point = context.portfolio.positions[sid].last_sale_price-2*atr
            else:
                add_pos_point = np.nan
                stop_loss_point = np.nan
            # 卖出逻辑和加仓逻辑
            if i in stock_hold_now:
                # 是否需要止损
                if price<stop_loss_point and context.portfolio.positions[sid].amount>0 and data.can_trade(sid):
                    order_target_value(sid, 0)
                    context.unit_remark[i] = 0
                # 是否需要出场  
                if price<low_point and context.portfolio.positions[sid].amount>0 and data.can_trade(sid):
                    order_target_value(sid, 0)   
                    context.unit_remark[i] = 0
                # 是否需要加仓,超过4 unit就不加仓了
                if price>add_pos_point and context.portfolio.positions[sid].amount>0 and data.can_trade(sid) and context.unit_remark[i]<4:
                    order(sid, a_unit)
                    context.unit_remark[i] = context.unit_remark[i]+1
            else:
                pass
            # 买入逻辑
            if price>high_point and context.portfolio.positions[sid].amount==0 and data.can_trade(sid):
                order(sid, a_unit)
                context.unit_remark[i] = 1
            else:
                pass
       
    
    # 回测引擎:准备数据,只执行一次
    def m3_prepare_bigquant_run(context):
        pass
    
    # 回测引擎:初始化函数,只执行一次
    def m3_initialize_bigquant_run(context):
       
        context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
        context.entry_pos_period = 55
        context.exit_pos_period = 20
        context.unit_remark = {}
        context.atr_data = context.options['data'].read_df()
        context.instruments = m1.data.read_pickle()['instruments']
         
         
    
    # 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。
    def m3_before_trading_start_bigquant_run(context, data):
        pass
    
    
    m1 = M.instruments.v2(
        start_date='2016-01-01',
        end_date='2017-11-21',
        market='CN_STOCK_A',
        instrument_list="""000001.SZA
    000002.SZA
    000089.SZA
    000333.SZA
    600519.SZA
    601198.SHA
    002310.SZA
    601998.SHA
    601377.SHA
    601966.SHA
    000728.SZA
    601766.SHA
    600660.SHA
    002450.SZA
    600600.SHA
    600030.SHA
    000898.SZA
    002508.SZA 
    601888.SHA""",
        max_count=0
    )
    
    m2 = M.cached.v3(
        input_1=m1.data,
        run=m2_run_bigquant_run,
        post_run=m2_post_run_bigquant_run,
        input_ports='',
        params='{}',
        output_ports=''
    )
    
    m3 = M.trade.v3(
        instruments=m1.data,
        options_data=m2.data_1,
        start_date='',
        end_date='',
        handle_data=m3_handle_data_bigquant_run,
        prepare=m3_prepare_bigquant_run,
        initialize=m3_initialize_bigquant_run,
        before_trading_start=m3_before_trading_start_bigquant_run,
        volume_limit=0,
        order_price_field_buy='open',
        order_price_field_sell='open',
        capital_base=10000000,
        benchmark='000300.SHA',
        auto_cancel_non_tradable_orders=True,
        data_frequency='daily',
        price_type='后复权',
        plot_charts=True,
        backtest_only=False
    )
    
    • 收益率72.55%
    • 年化收益率34.83%
    • 基准收益率13.04%
    • 阿尔法0.31
    • 贝塔0.25
    • 夏普比率1.89
    • 胜率1.0
    • 盈亏比0.0
    • 收益波动率14.79%
    • 信息比率0.07
    • 最大回撤8.82%
    bigcharts-data-start/{"__type":"tabs","__id":"bigchart-1cafff692d4b451bad10e58d070f348a"}/bigcharts-data-end