问答交流

为什么写出来的策略会在第一天全部买入呢?

由bq095770创建,最终由bq095770 被浏览 52 用户

问题

为什么写出来的策略会在第一天全部买入呢?

代码

# 本代码由可视化策略环境自动生成 2022年8月13日 13:20
# 本代码单元只能在可视化模式下编辑。您也可以拷贝代码,粘贴到新建的代码单元或者策略,然后修改。


# 回测引擎:初始化函数,只执行一次
def m6_initialize_bigquant_run(context):


    # 系统已经设置了默认的交易手续费和滑点,要修改手续费可使用如下函数
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
   
# 回测引擎:每日数据处理函数,每天执行一次
def m6_handle_data_bigquant_run(context, data):
    #1.获取今天的日期
    today=data.current_dt.strftime('%Y-%m-%d')
    
    #2.获取目前持仓的股票和最新市值
    stock_hold_now={e.symbol:p.amount*p.last_sale_price for e,p in context.portfolio.positions.items()}
    
    #3.获取当前账户可用现金
    cash_for_buy=context.portfolio.cash
    
    #4.获取当日的买卖信号股票列表
    try:
        buy_stock=context.daily_stock_buy[today]
    except:
        buy_stock=[]
       
    try:
        sell_stock=context.daily_stock_sell[today]
    except:
        sell_stock=[]
        
    #5.确认需要卖出的股票
    stock_to_sell=[i for i in stock_hold_now if i in sell_stock]
    
    #6.执行卖出操作
    if len(stock_to_sell)>0:
        for instrument in stock_to_sell:
            sid=context.symbol(instrument)
            cur_position=context.portfolio.positions[sid].amount #当前持仓
            if cur_position >0 and data.can_trade(sid):
                context.order_target_percent(sid,0)
                #根据卖出的股票更新现金
                cash_for_buy += stock_hold_now[instrument]
              
    #7.执行买入操作
    if len(buy_stock)>0:
        weight=1/len(buy_stock) #每只股票的比重为等资金比例持有
        for instrument in buy_stock:
            sid=context.symbol(instrument) 
            cur_position=context.portfolio.positions[sid].amount
            if data.can_trade(sid) and cur_position==0:
                context.order_target_value(sid,weight*cash_for_buy)
        

# 回测引擎:准备数据,只执行一次
def m6_prepare_bigquant_run(context):
    #加载预测数据
    df=context.options['data'].read_df()
    
    #函数:求满足开仓条件的股票列表
    def open_pos_con(df):
        return list(df[df['buy_condition']>0].instrument)
    
    #函数:求满足平仓条件的股票列表
    def close_pos_con(df):
        return list(df[df['sell_condition']>0].instrument)
    
    #每日买入股票的数据框
    context.daily_stock_buy=df.groupby('date').apply(open_pos_con)
    #每日卖出股票的数据框
    context_daily_stock_sell=df.groupby('date').apply(close_pos_con)
def m6_before_trading_start_bigquant_run(context,data):
    pass


m1 = M.instruments.v2(
    start_date='2015-01-01',
    end_date='2017-01-01',
    market='CN_STOCK_A',
    instrument_list="""600010.SHA
000001.SZA""",
    max_count=0
)

m2 = M.input_features.v1(
    features="""
# #号开始的表示注释,注释需单独一行
# 多个特征,每行一个,可以包含基础特征和衍生特征,特征须为本平台特征
buy_condition=where(mean(close_0,5)>mean(close_0,20),1,0) #买入条件
sell_condition=where(mean(close_0,5)<mean(close_0,20),1,0) #卖出条件"""
)

m3 = M.general_feature_extractor.v7(
    instruments=m1.data,
    features=m2.data,
    start_date='',
    end_date=''
)

m4 = M.derived_feature_extractor.v3(
    input_data=m3.data,
    features=m2.data,
    date_col='date',
    instrument_col='instrument',
    drop_na=False,
    remove_extra_columns=False,
    user_functions={}
)

m7 = M.dropnan.v2(
    input_data=m4.data
)

m6 = M.trade.v4(
    instruments=m1.data,
    options_data=m7.data,
    start_date='',
    end_date='',
    initialize=m6_initialize_bigquant_run,
    handle_data=m6_handle_data_bigquant_run,
    prepare=m6_prepare_bigquant_run,
    before_trading_start=m6_before_trading_start_bigquant_run,
    volume_limit=0.025,
    order_price_field_buy='close',
    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='000300.HIX'
)

{w:100}

解答

策略里面算出来的context.daily_stock_buy在2015-01-05只有000001.SZA这只票,所以它全仓买入了这只票,另外,在回测准备函数中,context.daily_stock_sell误写成了 context_daily_stock_sell,注意检查一下

标签

策略回测
评论
  • 策略里面算出来的context.daily_stock_buy在2015-01-05只有000001.SZA这只票,所以它全仓买入了这只票,另外,在回测准备函数中,context.daily_stock_sell误写成了 context_daily_stock_sell,注意检查一下
{link}