老帅李华杰
管理员
管理员
  • UID2
  • 粉丝35
  • 关注0
  • 发帖数464
  • 社区居民
  • 忠实会员
  • 喜欢达人
  • 原创写手
阅读:79回复:0

经典期货策略及 Python 实现

楼主#
更多 发布于:2026-03-17 22:21
一、经典期货策略及 Python 实现
1. 趋势跟踪策略(突破型)
核心逻辑:捕捉大趋势,截断亏损,让利润奔跑(胜率通常 40% 左右,但盈亏比高)。

用 ATR(平均真实波幅)确定止损和仓位,避免固定点位止损的弊端
突破 N 日高低点开仓,均线过滤减少假突破
import pandas as pd
import numpy as np
import talib

# 读取期货数据(需包含:datetime, open, high, low, close, volume)
# 数据格式示例:
# datetime      open    high    low     close   volume
# 2023-01-01    4500    4550    4480    4520    10000
def load_futures_data(file_path):
    df = pd.read_csv(file_path)
    df['datetime'] = pd.to_datetime(df['datetime'])
    df = df.set_index('datetime')
    return df

# 趋势跟踪策略实现
def trend_following_strategy(df, breakout_days=20, atr_period=14, risk_ratio=0.02):
    # 计算技术指标
    df['atr'] = talib.ATR(df['high'], df['low'], df['close'], timeperiod=atr_period)
    df['ma20'] = talib.MA(df['close'], timeperiod=20)  # 均线过滤
    df['high_20'] = df['high'].rolling(window=breakout_days).max()  # N日高点
    df['low_20'] = df['low'].rolling(window=breakout_days).min()    # N日低点
    
    # 初始化信号和仓位
    df['signal'] = 0  # 0:无仓位, 1:多仓, -1:空仓
    df['position'] = 0
    df['stop_loss'] = 0  # 止损价
    df['pnl'] = 0  # 盈亏
    
    # 遍历计算信号
    for i in range(breakout_days, len(df)):
        current_close = df.iloc['close']
        current_atr = df.iloc['atr']
        current_ma = df.iloc['ma20']
        prev_position = df.iloc[i-1]['position']
        
        # 开多仓:突破20日高点 + 价格在均线上方
        if (current_close > df.iloc['high_20']) and (current_close > current_ma) and prev_position == 0:
            df.iloc[i, df.columns.get_loc('signal')] = 1
            df.iloc[i, df.columns.get_loc('position')] = 1
            # 止损:开仓价 - 2*ATR
            df.iloc[i, df.columns.get_loc('stop_loss')] = current_close - 2 * current_atr
        
        # 开空仓:跌破20日低点 + 价格在均线下方
        elif (current_close < df.iloc['low_20']) and (current_close < current_ma) and prev_position == 0:
            df.iloc[i, df.columns.get_loc('signal')] = -1
            df.iloc[i, df.columns.get_loc('position')] = -1
            # 止损:开仓价 + 2*ATR
            df.iloc[i, df.columns.get_loc('stop_loss')] = current_close + 2 * current_atr
        
        # 止损平仓
        elif prev_position == 1 and current_close < df.iloc[i-1]['stop_loss']:
            df.iloc[i, df.columns.get_loc('signal')] = -1
            df.iloc[i, df.columns.get_loc('position')] = 0
        elif prev_position == -1 and current_close > df.iloc[i-1]['stop_loss']:
            df.iloc[i, df.columns.get_loc('signal')] = 1
            df.iloc[i, df.columns.get_loc('position')] = 0
        
        # 持有仓位时,更新止损(移动止盈)
        elif prev_position == 1:
            df.iloc[i, df.columns.get_loc('position')] = 1
            # 移动止损:前一日止损价 和 现价-2*ATR 取最大值
            new_sl = max(df.iloc[i-1]['stop_loss'], current_close - 2 * current_atr)
            df.iloc[i, df.columns.get_loc('stop_loss')] = new_sl
        elif prev_position == -1:
            df.iloc[i, df.columns.get_loc('position')] = -1
            # 移动止损:前一日止损价 和 现价+2*ATR 取最小值
            new_sl = min(df.iloc[i-1]['stop_loss'], current_close + 2 * current_atr)
            df.iloc[i, df.columns.get_loc('stop_loss')] = new_sl
        
        # 计算盈亏(假设每手合约价值为固定值,这里以螺纹钢为例,1手=10吨)
        if prev_position != 0:
            price_change = df.iloc['close'] - df.iloc[i-1]['close']
            df.iloc[i, df.columns.get_loc('pnl')] = prev_position * price_change * 10  # 10吨/手
    
    # 计算累计盈亏
    df['cum_pnl'] = df['pnl'].cumsum()
    return df

# 策略回测
if __name__ == "__main__":
    # 替换为你的期货数据文件路径
    df = load_futures_data('futures_data.csv')
    # 运行策略
    result = trend_following_strategy(df)
    
    # 输出关键回测指标
    total_trades = len(result[result['signal'] != 0]) // 2  # 开仓+平仓算一次交易
    win_trades = len(result[result['pnl'] > 0])
    win_rate = win_trades / total_trades if total_trades > 0 else 0
    total_pnl = result['cum_pnl'].iloc[-1]
    
    print(f"总交易次数:{total_trades}")
    print(f"胜率:{win_rate:.2%}")
    print(f"累计盈亏:{total_pnl:.2f}元")
    print(f"最大回撤:{result['cum_pnl'].expanding().max() - result['cum_pnl']}.max():.2f}元")
好的指标等于至高的阵地,明察秋毫自然马到成功; 微信手机同号:15907742318 老帅李华杰
游客

返回顶部