|
阅读:84回复:0
经典期货策略及 Python 实现
一、经典期货策略及 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}元") |
|
|