摘要: 用Python搭建日内交易策略,从数据获取到回测执行全流程拆解。股票期货都适用,重点在均线突破与止损纪律,避开常见陷阱。

为什么选择Python做日内交易

日内交易讲究快进快出,持仓不过夜。股票T+1制度下,严格意义的日内交易只能做T(底仓做差价)或者交易可转债、ETF。期货市场天然T+0,更适合纯日内策略。Python能帮你把重复的盯盘、计算、下单动作自动化,反应速度比人眼快得多。

数据准备:从哪里拿分钟级K线

做日内策略,日线数据没用,至少需要1分钟或5分钟K线。免费来源有akshare、tushare(部分接口收费)、yfinance(适合美股期货)。以akshare为例:


import akshare as ak

# 获取股票分钟数据

df = ak.stock_zh_a_minute(symbol='sh600519', period='5', adjust='qfq')

# 获取期货主力连续分钟数据

df_fut = ak.futures_zh_minute_sina(symbol='RB0', period='5')

拿到数据后,先做清洗:去掉集合竞价时的异常成交,补全缺失分钟(用前值填充),时间戳统一为交易所当地时间。期货还要注意主力合约换月,换月当天价格跳空,回测时应该做后复权处理。

策略逻辑:均线突破+ATR止损

日内策略不能太复杂,参数越多越容易过拟合。一个经典框架是5分钟K线,价格上穿20周期均线做多,下穿做空。止损用ATR(平均真实波幅)的1.5倍。

如何通过Python实现股票日内交易策略?


df['ma20'] = df['close'].rolling(20).mean()

df['tr'] = np.maximum(df['high'] - df['low'], 

                      np.maximum(abs(df['high'] - df['close'].shift(1)),

                                 abs(df['low'] - df['close'].shift(1))))

df['atr'] = df['tr'].rolling(14).mean()

# 信号

df['signal'] = 0

df.loc[df['close'] > df['ma20'], 'signal'] = 1

df.loc[df['close'] < df['ma20'], 'signal'] = -1

# 止损止盈价位

df['stop_long'] = df['close'] - 1.5 * df['atr']

df['stop_short'] = df['close'] + 1.5 * df['atr']

收盘前5分钟强制平仓,避免隔夜风险。股票做T的话,只做多不做空,底仓不动,用现金仓位做日内波段。

回测引擎:别用现成框架乱套

很多人直接上backtrader或vnpy,但日内高频数据下这些框架容易卡顿。自己写一个简单的事件驱动回测反而更可控。核心循环如下:


positions = 0

entry_price = 0

for i in range(1, len(df)):

    row = df.iloc[i]

    if positions == 0:

        if row['signal'] == 1:

            positions = 1

            entry_price = row['close']

        elif row['signal'] == -1:

            positions = -1

            entry_price = row['close']

    elif positions == 1:

        if row['close'] < row['stop_long'] or row['signal'] == -1:

            positions = 0

            # 记录平仓盈亏

    elif positions == -1:

        if row['close'] > row['stop_short'] or row['signal'] == 1:

            positions = 0

注意滑点:股票按0.01元,期货按1个最小变动价位。手续费股票万二点五,期货按交易所标准。回测结果要看夏普比率、最大回撤、胜率,不是只看总收益。

实盘执行:接口与风控

股票实盘用easytrader或miniQMT,期货用CTP接口。实盘前必须做模拟盘至少一个月。关键风控:单笔亏损不超过总资金1%,日内最大亏损3%停止交易。代码里加一个全局变量记录当日盈亏:


daily_pnl = 0

max_daily_loss = -0.03 * total_capital

if daily_pnl < max_daily_loss:

    close_all_positions()

    disable_trading_today()

网络断线要有重连机制,订单状态要轮询确认。股票T+1下做T注意底仓数量,别把底仓卖飞了。期货注意保证金变动,临近交割月流动性变差。

常见坑与应对

  1. 过拟合:参数在样本内漂亮,样本外一塌糊涂。用滚动窗口优化,每季度重新调参。

  2. 未来函数:用了收盘价却当成盘中能知道。信号要用前一根K线确认,当前K线只用来执行。

  3. 流动性陷阱:小盘股或远月期货合约滑点巨大。只做成交额前100的股票或主力合约。

  4. 情绪干扰:机器执行了,人却手动干预。把策略跑在云服务器上,减少盯盘。

日内交易不是圣杯,长期稳定盈利靠的是纪律和风控。Python只是工具,逻辑清晰、执行果断才是根本。