问答交流

策略能有效回测但提交实盘没有信号

由jameszhanfeng0创建,最终由jameszhanfeng0 被浏览 2 用户

策略社区的小市值策略拿来修改了一下(增加一些选股条件),能回测但提交实盘不产生信号,策略代码如下:

from bigquant import bigtrader, dai
import pandas as pd

def initialize(context: bigtrader.IContext):
    context.set_commission(bigtrader.PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))

    # 策略参数
    stock_num = 3  # 持股数量
    float_market_cap_threshold = 500000000  # 流通市值下限 5亿
    pe_lower_bound = 0
    pe_upper_bound = 50
    pb_upper_bound = 5
    net_profit_yoy_threshold = 0.2
    revenue_yoy_threshold = 0.2
    list_days_threshold = 365 # 上市天数一年
    context.holding_nums = stock_num
    context.counter = 1

    context.logger.info("开始计算选股数据...")

    sql = """
    SELECT
        date,
        instrument,
        total_market_cap,
        -- 等权重
        1.0/$stock_num AS weight
    FROM cn_stock_prefactors
    WHERE
        -- 非ST股票
        st_status = 0
        -- 非科创板
        AND list_sector != 3
        AND list_sector != 4
        -- 非停牌
        AND suspended = 0
        -- 流通市值大于 5 亿元
        AND float_market_cap > $float_market_cap_threshold
        -- 非新股,上市时间大于一年
        AND list_days > $list_days_threshold
        -- 净利润同比增长 > 20%
        AND net_profit_to_parent_shareholders_ttm_yoy > $net_profit_yoy_threshold
        -- 营业收入同比增长 > 20%
        AND total_operating_revenue_ttm_yoy > $revenue_yoy_threshold
        AND total_liabilities / total_assets < 0.6
        -- 0 < 市盈率 < 50
        AND pe_ttm > $pe_lower_bound AND pe_ttm < $pe_upper_bound
        -- 市净率 < 5
        AND pb < $pb_upper_bound
        -- 近一个月无减持公告 (假设字段存在)
        -- AND NOT has_reduction_announcement_1m
    ORDER BY date, total_market_cap ASC
    """

    params = {
        "stock_num": stock_num,
        "float_market_cap_threshold": float_market_cap_threshold,
        "pe_lower_bound": pe_lower_bound,
        "pe_upper_bound": pe_upper_bound,
        "pb_upper_bound": pb_upper_bound,
        "net_profit_yoy_threshold": net_profit_yoy_threshold,
        "revenue_yoy_threshold": revenue_yoy_threshold,
        "list_days_threshold": list_days_threshold
    }

    # 查询数据
    df = dai.query(sql, filters={"date": [context.add_trading_days(context.start_date, -10), context.end_date]}, params=params).df()
    context.logger.info(f"数据计算完成,共 {len(df)} 条记录")

    # # 每个交易日选取总市值最小的前N只股票
    # df = df.groupby('date').head(stock_num)

    # df = bigtrader.TradingDaysRebalance(5, context=context).select_rebalance_data(df) # 每5个交易日调仓

    # 保存到context中供后续使用
    context.data = df

def handle_data(context: bigtrader.IContext, data: bigtrader.IBarData): 
    #获取当前日期
    current_date = data.current_dt.strftime("%Y-%m-%d")
    # 获取当日数据
    current_day_data = context.data[context.data["date"] == current_date]
    instrument_list = current_day_data.sort_values(["total_market_cap"], ascending=[True])["instrument"].values[:context.holding_nums]
    context.target_weights = {ins: 1/len(instrument_list) for ins in instrument_list}
    if len(current_day_data) == 0:
        return
    context.counter += 1
    if context.counter == 3:
        
        context.counter = 0
        # 获取当前已持有股票
        current_hold_instruments = set(context.get_account_positions().keys())
        
        for ins in current_hold_instruments:
            # 若长线大于短线且有持仓
            if ins not in instrument_list:
                context.order_target(ins, 0)
        for ins in instrument_list:
            # 若短线大于长线且没有持仓
            if ins not in current_hold_instruments:
                context.order_target_percent(ins, context.target_weights[ins])

performance = bigtrader.run(
    market=bigtrader.Market.CN_STOCK,
    frequency=bigtrader.Frequency.DAILY,
    start_date="2025-01-01",
    end_date="2026-04-17",
    capital_base=300000.00,
    initialize=initialize,
    handle_data=handle_data,
)

performance.render()

\

{link}