复制链接
克隆策略

    {"description":"实验创建于2023/2/10","graph":{"edges":[{"to_node_id":"-38:features","from_node_id":"-30:data"},{"to_node_id":"-23:features","from_node_id":"-30:data"},{"to_node_id":"-23:input_data","from_node_id":"-38:data"},{"to_node_id":"-38:instruments","from_node_id":"-31:data"},{"to_node_id":"-63:instruments","from_node_id":"-31:data"},{"to_node_id":"-63:options_data","from_node_id":"-23:data"}],"nodes":[{"node_id":"-30","module_id":"BigQuantSpace.input_features.input_features-v1","parameters":[{"name":"features","value":"\n# #号开始的表示注释,注释需单独一行\n# 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征\nclose","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"features_ds","node_id":"-30"}],"output_ports":[{"name":"data","node_id":"-30"}],"cacheable":true,"seq_num":2,"comment":"","comment_collapsed":true},{"node_id":"-38","module_id":"BigQuantSpace.use_datasource.use_datasource-v2","parameters":[{"name":"datasource_id","value":"bar1d_CN_FUND","type":"Literal","bound_global_parameter":null},{"name":"start_date","value":"","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"","type":"Literal","bound_global_parameter":null},{"name":"before_start_days","value":"3","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-38"},{"name":"features","node_id":"-38"}],"output_ports":[{"name":"data","node_id":"-38"}],"cacheable":true,"seq_num":5,"comment":"","comment_collapsed":true},{"node_id":"-31","module_id":"BigQuantSpace.instruments.instruments-v2","parameters":[{"name":"start_date","value":"2023-12-01","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"2023-12-21","type":"Literal","bound_global_parameter":null},{"name":"market","value":"CN_FUND","type":"Literal","bound_global_parameter":null},{"name":"instrument_list","value":"","type":"Literal","bound_global_parameter":null},{"name":"max_count","value":0,"type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"rolling_conf","node_id":"-31"}],"output_ports":[{"name":"data","node_id":"-31"}],"cacheable":true,"seq_num":3,"comment":"","comment_collapsed":true},{"node_id":"-23","module_id":"BigQuantSpace.derived_feature_extractor.derived_feature_extractor-v3","parameters":[{"name":"date_col","value":"date","type":"Literal","bound_global_parameter":null},{"name":"instrument_col","value":"instrument","type":"Literal","bound_global_parameter":null},{"name":"drop_na","value":"True","type":"Literal","bound_global_parameter":null},{"name":"remove_extra_columns","value":"True","type":"Literal","bound_global_parameter":null},{"name":"user_functions","value":"{}","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"input_data","node_id":"-23"},{"name":"features","node_id":"-23"}],"output_ports":[{"name":"data","node_id":"-23"}],"cacheable":true,"seq_num":1,"comment":"","comment_collapsed":true},{"node_id":"-63","module_id":"BigQuantSpace.trade.trade-v4","parameters":[{"name":"start_date","value":"","type":"Literal","bound_global_parameter":null},{"name":"end_date","value":"","type":"Literal","bound_global_parameter":null},{"name":"initialize","value":"# 交易引擎:初始化函数,只执行一次\ndef bigquant_run(context): \n \n # 加载预测数据\n #context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))\n\n #读取数据\n context.ranker_prediction = context.options['data'].read_df()\n context.ranker_prediction.set_index('date',inplace=True)\n \n\n","type":"Literal","bound_global_parameter":null},{"name":"handle_data","value":"from datetime import datetime,timedelta\nfrom scipy.optimize import minimize \n# 交易引擎:bar数据处理函数,每个时间单位执行一次\ndef bigquant_run(context, data):\n \n # 调仓时间,1就是一天一调仓\n remainder = context.trading_day_index % 5\n #如果没到调仓期直接结束运行\n if remainder !=0:\n return\n \n #==================== 数据准备\n today = data.current_dt.strftime('%Y-%m-%d')\n time = data.current_dt\n \n etf_pool = [\n #'510880.HOF', #红利ETF(价值股,蓝筹股,防御性,中大盘)\n #'512890.HOF', #天弘红利低波\n '513100.HOF', #纳指100(海外资产)\n '515100.HOF', #红利低波100\n #'159915.HOF', #创业板100(成长股,科技股,题材性,中小盘)\n '518880.HOF', #黄金ETF(大宗商品) \n \n ]\n\n\n # 计算投资组合方差的函数\n def portfolio_variance(weights, cov_matrix): # 定义投资组合方差函数\n return np.dot(weights.T, np.dot(cov_matrix* 250, weights)) # 计算并返回投资组合方差\n\n # 优化投资组合的函数\n def optimize_portfolio(returns): # 定义优化投资组合函数\n # 计算协方差矩阵\n cov_matrix = returns.cov() # 计算收益的协方差矩阵\n # 投资组合中的资产数量\n num_assets = len(returns.columns) # 计算投资组合中的资产数量\n # 初始权重(平均分配)\n init_weights = np.array([1/num_assets] * num_assets) # 设置初始权重\n # 约束条件\n weight_sum_constraint = {'type': 'eq', 'fun': lambda weights: np.sum(weights) - 1} # 权重和约束\n bounds = [(0, 1) for _ in range(num_assets)] # 权重范围约束\n # 优化\n result = minimize(portfolio_variance, init_weights, args=(cov_matrix), bounds=bounds, constraints=weight_sum_constraint) \n return result.x # 返回优化结果\n\n # 定义获取数据并调用优化函数的函数\n def run_optimization(stocks, end_date):\n start_date=end_date-timedelta(days=360)\n prices = DataSource(\"bar1d_CN_FUND\").read(stocks,start_date=start_date, end_date=end_date,fields=['close']) \n returns = prices.pivot(index='date', columns='instrument', values='close') \n returns = returns.pct_change().dropna() # 计算收益率\n weights = optimize_portfolio(returns)\n return weights \n \n # 交易\n end_date = time \n weights = run_optimization(etf_pool, end_date)\n print(today,weights)\n if weights is None:\n return\n\n total_value=context.portfolio.portfolio_value # 获取总资产\n index = 0\n for w in weights:\n value = total_value * w # 确定每个标的的权重\n context.order_target_value(etf_pool[index], value) # 调整标的至目标权重\n index+=1\n","type":"Literal","bound_global_parameter":null},{"name":"prepare","value":"# 回测引擎:准备数据,只执行一次\ndef bigquant_run(context):\n pass\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.025,"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":1000000,"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":"product_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},{"name":"benchmark","value":"000300.HIX","type":"Literal","bound_global_parameter":null}],"input_ports":[{"name":"instruments","node_id":"-63"},{"name":"options_data","node_id":"-63"},{"name":"history_ds","node_id":"-63"},{"name":"benchmark_ds","node_id":"-63"},{"name":"trading_calendar","node_id":"-63"}],"output_ports":[{"name":"raw_perf","node_id":"-63"}],"cacheable":false,"seq_num":4,"comment":"","comment_collapsed":true}],"node_layout":"<node_postions><node_position Node='-30' Position='294.4716796875,-159.20849609375,200,200'/><node_position Node='-38' Position='125.43524169921875,-48.82995796203613,200,200'/><node_position Node='-31' Position='-11.232795715332031,-155.58501434326172,200,200'/><node_position Node='-23' Position='117,39,200,200'/><node_position Node='-63' Position='50,149,200,200'/></node_postions>"},"nodes_readonly":false,"studio_version":"v2"}
    In [3]:
    # 本代码由可视化策略环境自动生成 2023年12月22日 20:49
    # 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。
    
    
    # 交易引擎:初始化函数,只执行一次
    def m4_initialize_bigquant_run(context):    
        
        # 加载预测数据
        #context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
    
        #读取数据
        context.ranker_prediction = context.options['data'].read_df()
        context.ranker_prediction.set_index('date',inplace=True)
        
    
    
    from datetime import datetime,timedelta
    from scipy.optimize import minimize  
    # 交易引擎:bar数据处理函数,每个时间单位执行一次
    def m4_handle_data_bigquant_run(context, data):
        
        # 调仓时间,1就是一天一调仓
        remainder = context.trading_day_index % 5
        #如果没到调仓期直接结束运行
        if remainder !=0:
            return
            
        #==================== 数据准备
        today = data.current_dt.strftime('%Y-%m-%d')
        time = data.current_dt
        
        etf_pool = [
            #'510880.HOF', #红利ETF(价值股,蓝筹股,防御性,中大盘)
            #'512890.HOF', #天弘红利低波
            '513100.HOF', #纳指100(海外资产)
            '515100.HOF', #红利低波100
            #'159915.HOF', #创业板100(成长股,科技股,题材性,中小盘)
            '518880.HOF', #黄金ETF(大宗商品)    
            
        ]
    
    
        # 计算投资组合方差的函数
        def portfolio_variance(weights, cov_matrix):  # 定义投资组合方差函数
            return np.dot(weights.T, np.dot(cov_matrix* 250, weights))  # 计算并返回投资组合方差
    
        # 优化投资组合的函数
        def optimize_portfolio(returns):  # 定义优化投资组合函数
            # 计算协方差矩阵
            cov_matrix = returns.cov()  # 计算收益的协方差矩阵
            # 投资组合中的资产数量
            num_assets = len(returns.columns)  # 计算投资组合中的资产数量
            # 初始权重(平均分配)
            init_weights = np.array([1/num_assets] * num_assets)  # 设置初始权重
            # 约束条件
            weight_sum_constraint = {'type': 'eq', 'fun': lambda weights: np.sum(weights) - 1}  # 权重和约束
            bounds = [(0, 1) for _ in range(num_assets)]  # 权重范围约束
            # 优化
            result = minimize(portfolio_variance, init_weights, args=(cov_matrix), bounds=bounds, constraints=weight_sum_constraint)  
            return result.x  # 返回优化结果
    
        # 定义获取数据并调用优化函数的函数
        def run_optimization(stocks, end_date):
            start_date=end_date-timedelta(days=360)
            prices = DataSource("bar1d_CN_FUND").read(stocks,start_date=start_date, end_date=end_date,fields=['close']) 
            returns = prices.pivot(index='date', columns='instrument', values='close') 
            returns = returns.pct_change().dropna() # 计算收益率
            weights = optimize_portfolio(returns)
            return weights     
        
        # 交易
        end_date = time            
        weights = run_optimization(etf_pool, end_date)
        print(today,weights)
        if weights is None:
            return
    
        total_value=context.portfolio.portfolio_value # 获取总资产
        index = 0
        for w in weights:
            value = total_value * w # 确定每个标的的权重
            context.order_target_value(etf_pool[index], value) # 调整标的至目标权重
            index+=1
    
    # 回测引擎:准备数据,只执行一次
    def m4_prepare_bigquant_run(context):
        pass
    
    # 回测引擎:每个单位时间开始前调用一次,即每日开盘前调用一次。
    def m4_before_trading_start_bigquant_run(context, data):
        pass
    
    
    m2 = M.input_features.v1(
        features="""
    # #号开始的表示注释,注释需单独一行
    # 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征
    close"""
    )
    
    m3 = M.instruments.v2(
        start_date='2023-12-01',
        end_date='2023-12-21',
        market='CN_FUND',
        instrument_list='',
        max_count=0
    )
    
    m5 = M.use_datasource.v2(
        instruments=m3.data,
        features=m2.data,
        datasource_id='bar1d_CN_FUND',
        start_date='',
        end_date='',
        before_start_days=3
    )
    
    m1 = M.derived_feature_extractor.v3(
        input_data=m5.data,
        features=m2.data,
        date_col='date',
        instrument_col='instrument',
        drop_na=True,
        remove_extra_columns=True,
        user_functions={}
    )
    
    m4 = M.trade.v4(
        instruments=m3.data,
        options_data=m1.data,
        start_date='',
        end_date='',
        initialize=m4_initialize_bigquant_run,
        handle_data=m4_handle_data_bigquant_run,
        prepare=m4_prepare_bigquant_run,
        before_trading_start=m4_before_trading_start_bigquant_run,
        volume_limit=0.025,
        order_price_field_buy='open',
        order_price_field_sell='open',
        capital_base=1000000,
        auto_cancel_non_tradable_orders=True,
        data_frequency='daily',
        price_type='真实价格',
        product_type='股票',
        plot_charts=True,
        backtest_only=False,
        benchmark='000300.HIX'
    )
    
    2023-12-01 [0.13833423 0.30932146 0.55234431]
    2023-12-08 [0.13918087 0.3184101  0.54240903]
    2023-12-15 [0.14539723 0.32421976 0.53038301]
    
    • 收益率-1.13%
    • 年化收益率-17.32%
    • 基准收益率-4.73%
    • 阿尔法-0.07
    • 贝塔0.18
    • 夏普比率-3.17
    • 胜率0.33
    • 盈亏比0.13
    • 收益波动率6.87%
    • 信息比率0.32
    • 最大回撤1.52%
    bigcharts-data-start/{"__type":"tabs","__id":"bigchart-eda0b544ab634823a32bfd93b5d7ee0c"}/bigcharts-data-end