问答交流

[新手小白] 量价共振分时策略 为什么回测无任何交易数据

由bqg7lmdh创建,最终由bqg7lmdh 被浏览 7 用户

小白第一次使用这个工具,折腾了几天都是没有交易数据,不知道问题出在哪里,请大神指教。

我在ai策略助手里测试提示词如下:

量价共振策略:5分钟分时周期,当量比> 1.5 且股票价格涨幅 > 0.5% 时买入总资金的10%,买入价格回落1%,立即止损止盈;上涨超过3%,分批止盈;初始资金为100万;手续费按行业规则设置(买0.03%,卖0.13%,单笔最低5元)

测试代码:

from bigmodule import M

# <aistudiograph>

import pandas as pd
from datetime import datetime, timedelta

# 近一年到今天
today = datetime.today()
end_date = today.strftime('%Y-%m-%d 15:00:00')
start_date = (today - timedelta(days=365)).strftime('%Y-%m-%d 09:30:00')

# @param(id="m5", name="initialize")
def m5_initialize_bigquant_run(context):
    from bigtrader.finance.commission import PerOrder
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
    context.stop_profit_level = dict()  # 止盈层级跟踪
    context.last_buy_price = dict()     # 记录买入成本

# @param(id="m5", name="handle_data")
def m5_handle_data_bigquant_run(context, data):
    import numpy as np
    current_dt = getattr(data, "current_dt", None)
    if current_dt is None:
        return
    today_df = pd.DataFrame()
    try:
        if hasattr(context, "data") and isinstance(context.data, pd.DataFrame):
            time_str = current_dt.strftime("%Y-%m-%d %H:%M:%S")
            today_df = context.data[context.data["date"] == time_str]
    except Exception:
        pass
    account_positions = set(context.get_account_positions().keys())
    target_instruments = set(today_df.get("instrument", []))
    for instrument in account_positions - target_instruments:
        try:
            context.order_target_percent(instrument, 0)
        except Exception:
            pass
        context.stop_profit_level.pop(instrument, None)
        context.last_buy_price.pop(instrument, None)
    for _, x in today_df.iterrows():
        ins = x.instrument
        try:
            position = context.get_position(ins)
        except Exception:
            position = None
        if position is not None and getattr(position, "amount", 0) > 0:
            continue
        try:
            context.order_target_percent(ins, 0.1)
        except Exception:
            continue
        context.stop_profit_level[ins] = 0
        context.last_buy_price[ins] = None
    for ins in list(account_positions):
        try:
            position = context.get_position(ins)
        except Exception:
            continue
        if position is None or getattr(position, "amount", 0) == 0:
            continue
        last_price = getattr(position, "last_price", None)
        cost_price = getattr(position, "cost_price", None)
        if context.last_buy_price.get(ins) is None and cost_price is not None and cost_price > 0 and np.isfinite(cost_price):
            context.last_buy_price[ins] = cost_price
        buy_price = context.last_buy_price.get(ins, cost_price)
        if buy_price is None or buy_price == 0 or not np.isfinite(buy_price):
            continue
        if last_price is None or not np.isfinite(last_price):
            continue
        try:
            return_pct = (float(last_price) - float(buy_price)) / float(buy_price)
        except Exception:
            continue
        if not np.isfinite(return_pct):
            continue
        # 止损:跌超1%立即清仓
        if return_pct <= -0.01:
            try:
                context.order_target_percent(ins, 0)
            except Exception:
                pass
            context.stop_profit_level.pop(ins, None)
            context.last_buy_price.pop(ins, None)
            continue
        # 止盈:涨3%即全部止盈(如需分级止盈可自行扩展)
        if return_pct >= 0.03 and context.stop_profit_level.get(ins, 0) < 1:
            try:
                context.order_target_percent(ins, 0)
            except Exception:
                pass
            context.stop_profit_level[ins] = 1
            context.last_buy_price.pop(ins, None)

# @module(comment="A股基础筛选,非ST,上市满20天")
m1 = M.cn_stock_basic_selector.v8(
    drop_suspended=True,  # 分钟级容易抽中停牌,多加保护
    m_name="m1"
)

# @module(comment="输入分时量价因子表达式")
m2 = M.input_features_dai.v30(
    input_1=m1.data,
    mode="表达式",
    expr="volume/m_avg(volume, 48) AS vol_rate\n(close/m_lag(close, 1)-1) AS pct_chg\nclose, open\nvol_rate AS score",
    expr_filters="amount > 0\nlist_days > 20\nst_status = 0\nvol_rate > 1.5\npct_chg > 0.005",
    expr_tables="cn_stock_prefactors",
    extra_fields="date, instrument",
    order_by="date, instrument",
    expr_drop_na=True,
    extract_data=False,
    m_name="m2"
)

# @module(comment="抽取5分钟分时周期数据")
m3 = M.extract_data_dai.v20(
    sql=m2.data,
    start_date=start_date,
    start_date_bound_to_trading_date=True,
    end_date=end_date,
    end_date_bound_to_trading_date=True,
    before_start_days=7,
    keep_before=False,
    debug=False,
    m_name="m3"
)

# @module(comment="评分分仓,等权0.1持仓")
m4 = M.score_to_position.v4(
    input_1=m3.data,
    score_field="score DESC",
    hold_count=0,
    position_expr="0.1 AS position",
    total_position=1,
    extract_data=True,
    m_name="m4"
)

# @module(comment="高频回测,5分钟open成交,严格止损止盈")
m5 = M.bigtrader.v43(
    data=m4.data,
    start_date=start_date,
    end_date=end_date,
    initialize=m5_initialize_bigquant_run,
    handle_data=m5_handle_data_bigquant_run,
    capital_base=1000000,
    frequency="minute",
    product_type="股票",
    rebalance_period_type="交易日",
    rebalance_period_days="1",
    rebalance_period_roll_forward=True,
    backtest_engine_mode="标准模式",
    before_start_days=0,
    volume_limit=1,
    order_price_field_buy="open",
    order_price_field_sell="open",
    benchmark="沪深300指数",
    plot_charts=False,
    debug=False,
    backtest_only=True,  # 防止回测后处理因NaN报错
    m_name="m5"
)
# </aistudiograph>

回测结果如下:\n

{link}