A 股怎么做 T(T+0)?用 Python 回测日内高抛低

用户头像sh_*2176oo
2026-09-10 发布

一句话回答: A 股股票是 T+1,当天买的不能当天卖,所谓「做 T」其实是围绕已有底仓做日内高抛低吸——先卖后买(反 T)或先买后卖(正 T),日终净持股不变,赚的是日内波段差价。用 AlphaFeed 取 5 分钟 K 线,几十行就能把这套规则回测出来,还能诚实地把手续费和成交假设算进去。

为什么会有这个问题 / 传统做法的痛点

很多人把「做 T」神话成稳赚,但真回测时常常卡在两点:一是拿不到干净的历史分钟数据(免费源分钟线要么缺、要么口径乱);二是没想清楚 T+1 约束——以为可以当天买当天卖,结果回测逻辑本身就是错的。

正确的做 T 模型是:你手里本来就有 base_shares 股底仓,日内价格冲高时先卖一部分(反 T),回落时再等量买回,一天结束时持股数量回到原点,赚的是「卖价 − 买价」的差。数据上你需要的是多日、连续、复权正确的分钟 K 线

分步骤解决(每步配可运行代码)

第 1 步:取多日 5 分钟 K 线

af.klines.getperiod="5m" 会返回跨多日的历史分钟线(count 控制根数,一天约 48 根 5 分钟线)。

import pandas as pd
from alphafeed import AlphaFeed

def load_5m(symbol, count=1000):
    af = AlphaFeed()  # 读取环境变量 ALPHAFEED_API_KEY;或 AlphaFeed(api_key="...")
    df = af.klines.get(symbol, period="5m", count=count,
                       adjust="forward", to_dataframe=True)
    return df.sort_values("timestamp").reset_index(drop=True)

df = load_5m("300750.SZ", count=1000)   # 约 21 个交易日的 5m 线
print(df.shape, df["trade_date"].nunique())

第 2 步:写日内做 T 规则并回测

当日第一根 5 分钟 K 线的开盘价为锚点,设一个 band(如 ±0.5%):价格先摸到上轨就先卖(反 T),先摸到下轨就先买(正 T),另一侧成交完成一个回合。日终净持仓不变,只结算这一轮的价差。

def backtest_t0(df, band=0.005, base_shares=100, fee=0.0006):
    rows = []
    for day, g in df.groupby("trade_date"):
        g = g.reset_index(drop=True)
        anchor = g.loc[0, "open"]              # 当日锚点
        hi, lo = anchor * (1 + band), anchor * (1 - band)
        first_hi = first_lo = None
        for i, r in g.iterrows():
            if first_hi is None and r["high"] >= hi:
                first_hi = i
            if first_lo is None and r["low"] <= lo:
                first_lo = i
        sell_px = buy_px = kind = None
        if first_hi is not None and first_lo is not None:
            if first_hi < first_lo:            # 先冲高:反 T(先卖后买)
                sell_px, buy_px, kind = hi, lo, "反T"
            else:                              # 先杀跌:正 T(先买后卖)
                buy_px, sell_px, kind = lo, hi, "正T"
        if sell_px is not None:
            gross = (sell_px - buy_px) * base_shares
            cost = (sell_px + buy_px) * base_shares * fee     # 双边费用近似
            rows.append({"day": day, "kind": kind,
                         "sell": round(sell_px, 2), "buy": round(buy_px, 2),
                         "pnl": round(gross - cost, 2)})
    return pd.DataFrame(rows)

res = backtest_t0(df, band=0.005, base_shares=100)
print("完成 T 的天数:", len(res), " 累计盈亏:", round(res["pnl"].sum(), 2))
print(res.head().to_string(index=False))

真实跑通的一段输出(宁德时代 300750.SZ,约 21 个交易日,band=0.5%,底仓 100 股):完成 T 的天数 10,累计盈亏约 3329.84 元——但这是「假设每次都在上下轨精准成交」的乐观上限,见下文避坑。

参数与字段说明

参数 含义 备注
period="5m" 5 分钟 K 线 支持1m/5m/15m/30m/60m;分钟历史深度由 count 决定
adjust="forward" 前复权 跨越除权日时避免价格跳空污染
band 高抛低吸的偏离阈值 越小成交越频繁,但越贴近噪声、越难真成交
base_shares 底仓股数 做 T 是围绕底仓,不改变日终持股
fee 单边费率近似 A 股买入佣金、卖出佣金+印花税,见 FAQ

关键坑与注意事项

  • T+1 是硬约束:当日买入的股票当日不能卖出。本模型只在已有底仓上做「先卖后买」或「先买后卖」,日终持股回到原点,不是当天新开仓当天平。
  • 成交假设过于乐观:代码假设你能在 hi/lo 精确成交。实盘用限价单可能挂不上、用市价单有滑点;一字涨跌停更是买卖不到。回测结果是上限,不是预期收益。
  • 未来函数要当心:这里用同一根 K 线的 high/low 只用来判断「当天是否触及」,没有用未来价格决定当前动作;但如果你把「先卖后买」的顺序判断改成依赖收盘价,就会引入前视偏差。
  • 分钟历史深度有限count=1000 只能覆盖约 20 个交易日,样本很短,别据此下「稳赚」的结论。想要长样本要多次分段取或改用日线级研究。
  • 复权口径:跨除权日务必用 adjust="forward",否则除权跳空会被误当成日内波动。

常见问题(FAQ)

Q:做 T 到底能不能降低持仓成本?
A:在有波动、且你能大致踩到高低点时,长期能摊薄一点成本;但一旦方向判断反了(高买低卖),反而抬高成本。回测能帮你量化「在历史波动下这套规则的上限收益」,但成交假设越乐观,结论越不可信。

Q:手续费该怎么设?
A:A 股买入只收佣金(常见万 2.5~万 3),卖出还有千 1 印花税、以及沪市过户费。代码里 fee=0.0006 是双边近似,严谨做法是买卖分开计费并单独加印花税。

Q:可以换成 1 分钟或用当日实时分时吗?
A:可以。period="1m" 取更细的历史;想看当天实时分时用 af.klines.intraday(symbol, to_dataframe=True)(返回当日分钟线)。

Q:需要付费吗?
A:单标的历史分钟线免费额度即可体验;要全市场批量或标的池查询需 Starter 及以上,详见官网定价页。

小结

「做 T」的本质不是 T+0 套利,而是在底仓之上用日内波动做高抛低吸,受 T+1 规则约束、且高度依赖能否真的成交。用 AlphaFeed 的复权分钟 K 线,你可以把规则写清楚、把手续费和成交假设摆到台面上诚实回测——先搞明白「乐观上限」有多少,再决定这件事对你值不值得。

参考

评论