如何使用Python实现一个简单的商品期货布林指标突破策略

发布时间:2021-11-12 10:35:48 作者:小新
来源:亿速云 阅读:343
# 如何使用Python实现一个简单的商品期货布林指标突破策略

## 一、策略概述

### 1.1 布林带指标简介
布林带(Bollinger Bands)是由约翰·布林格(John Bollinger)在1980年代发明的技术分析工具,由三条线组成:
- 中轨(Middle Band):N日移动平均线(通常为20日SMA)
- 上轨(Upper Band):中轨 + k倍标准差(通常k=2)
- 下轨(Lower Band):中轨 - k倍标准差

该指标通过计算价格的波动区间,反映市场的超买超卖状态。当价格突破上下轨时,往往预示着趋势的开始或反转。

### 1.2 突破策略原理
本策略的基本逻辑是:
1. 当价格**收盘价突破上轨**时,做多入场
2. 当价格**收盘价跌破下轨**时,做空入场
3. 当价格**回归中轨**时,平仓离场

## 二、环境准备

### 2.1 所需Python库
```python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tushare as ts  # 获取金融数据的库
import talib  # 技术指标计算库

2.2 数据获取

以螺纹钢期货(RB9999)为例,获取历史数据:

# 使用tushare pro获取数据(需要注册获取token)
pro = ts.pro_api('your_token_here')

# 获取螺纹钢主力合约日线数据
df = pro.fut_daily(ts_code="RB9999.SHF", start_date="20200101", end_date="20231231")
df = df.sort_values('trade_date').reset_index(drop=True)

三、布林带计算实现

3.1 手动计算布林带

def calculate_bollinger_bands(data, window=20, k=2):
    """
    计算布林带指标
    参数:
        data: 价格序列
        window: 移动平均窗口(默认20)
        k: 标准差倍数(默认2)
    返回:
        DataFrame包含中轨、上轨、下轨
    """
    data['MA'] = data['close'].rolling(window=window).mean()
    data['STD'] = data['close'].rolling(window=window).std()
    data['Upper'] = data['MA'] + k * data['STD']
    data['Lower'] = data['MA'] - k * data['STD']
    return data[['MA', 'Upper', 'Lower']]

3.2 使用TA-Lib计算

upper, middle, lower = talib.BBANDS(
    df['close'].values, 
    timeperiod=20, 
    nbdevup=2, 
    nbdevdn=2, 
    matype=0
)
df['Upper'] = upper
df['MA'] = middle
df['Lower'] = lower

四、策略信号生成

4.1 定义交易信号

def generate_signals(df):
    """
    生成交易信号
    1 表示做多,-1 表示做空,0 表示无信号
    """
    df['signal'] = 0
    
    # 突破上轨做多
    df.loc[(df['close'] > df['Upper']) & (df['close'].shift(1) <= df['Upper'].shift(1)), 'signal'] = 1
    
    # 突破下轨做空
    df.loc[(df['close'] < df['Lower']) & (df['close'].shift(1) >= df['Lower'].shift(1)), 'signal'] = -1
    
    # 回归中轨平仓
    df.loc[
        ((df['close'] <= df['MA']) & (df['close'].shift(1) > df['MA'].shift(1))) | 
        ((df['close'] >= df['MA']) & (df['close'].shift(1) < df['MA'].shift(1))),
        'signal'
    ] = 0
    
    return df

4.2 持仓状态管理

def manage_positions(df):
    """
    管理持仓状态
    """
    df['position'] = 0  # 持仓方向:1多仓,-1空仓,0无仓
    current_position = 0
    
    for i in range(len(df)):
        # 如果有信号且当前无持仓
        if df.at[i, 'signal'] != 0 and current_position == 0:
            current_position = df.at[i, 'signal']
        # 如果出现平仓信号
        elif df.at[i, 'signal'] == 0 and current_position != 0:
            current_position = 0
        
        df.at[i, 'position'] = current_position
    
    return df

五、策略回测实现

5.1 计算每日收益

def calculate_returns(df):
    """
    计算策略收益
    """
    df['daily_return'] = df['close'].pct_change()
    df['strategy_return'] = df['position'].shift(1) * df['daily_return']
    df['cumulative_return'] = (1 + df['strategy_return']).cumprod()
    return df

5.2 回测结果分析

def analyze_performance(df):
    """
    分析策略表现
    """
    total_return = df['cumulative_return'].iloc[-1] - 1
    annual_return = (1 + total_return) ** (252/len(df)) - 1
    max_drawdown = (df['cumulative_return'].cummax() - df['cumulative_return']).max()
    sharpe_ratio = df['strategy_return'].mean() / df['strategy_return'].std() * np.sqrt(252)
    
    print(f"总收益率: {total_return*100:.2f}%")
    print(f"年化收益率: {annual_return*100:.2f}%")
    print(f"最大回撤: {max_drawdown*100:.2f}%")
    print(f"夏普比率: {sharpe_ratio:.2f}")

六、可视化展示

6.1 绘制布林带与价格

plt.figure(figsize=(14, 7))
plt.plot(df['close'], label='Price', alpha=0.5)
plt.plot(df['MA'], label='Middle Band', linestyle='--')
plt.plot(df['Upper'], label='Upper Band', linestyle='--', color='red')
plt.plot(df['Lower'], label='Lower Band', linestyle='--', color='green')
plt.fill_between(df.index, df['Upper'], df['Lower'], color='grey', alpha=0.1)
plt.title('Bollinger Bands')
plt.legend()
plt.show()

6.2 绘制交易信号

plt.figure(figsize=(14, 7))
plt.plot(df['close'], label='Price', alpha=0.5)

# 标记买入信号
plt.scatter(
    df.index[df['signal'] == 1],
    df['close'][df['signal'] == 1],
    marker='^', color='green', label='Buy Signal'
)

# 标记卖出信号
plt.scatter(
    df.index[df['signal'] == -1],
    df['close'][df['signal'] == -1],
    marker='v', color='red', label='Sell Signal'
)

plt.title('Trading Signals')
plt.legend()
plt.show()

6.3 绘制收益曲线

plt.figure(figsize=(14, 7))
plt.plot(df['cumulative_return'], label='Strategy')
plt.plot((1 + df['daily_return']).cumprod() - 1, label='Buy & Hold')
plt.title('Cumulative Returns')
plt.legend()
plt.show()

七、策略优化方向

7.1 参数优化

可以通过网格搜索寻找最优参数组合:

def optimize_parameters(df):
    results = []
    
    for window in range(10, 50, 5):
        for k in [1.5, 2, 2.5]:
            temp_df = calculate_bollinger_bands(df.copy(), window, k)
            temp_df = generate_signals(temp_df)
            temp_df = manage_positions(temp_df)
            temp_df = calculate_returns(temp_df)
            
            total_return = temp_df['cumulative_return'].iloc[-1] - 1
            max_drawdown = (temp_df['cumulative_return'].cummax() - temp_df['cumulative_return']).max()
            
            results.append({
                'window': window,
                'k': k,
                'return': total_return,
                'max_drawdown': max_drawdown
            })
    
    return pd.DataFrame(results)

7.2 加入过滤器

可考虑加入以下改进: 1. 结合趋势过滤器(如200日均线方向) 2. 加入成交量确认 3. 设置止损止盈机制

八、实盘应用注意事项

8.1 实盘关键考虑

  1. 滑点处理:实际成交价与信号价有差异
  2. 手续费计算:期货交易的双边手续费
  3. 保证金管理:防止爆仓风险
  4. 交易频率:避免过度交易

8.2 风险控制建议

def add_risk_management(df, stop_loss=0.05, take_profit=0.1):
    """
    添加止损止盈逻辑
    """
    df['position'] = 0
    current_position = 0
    entry_price = 0
    
    for i in range(len(df)):
        # 开仓逻辑
        if df.at[i, 'signal'] != 0 and current_position == 0:
            current_position = df.at[i, 'signal']
            entry_price = df.at[i, 'close']
        
        # 止损止盈逻辑
        elif current_position != 0:
            pct_change = (df.at[i, 'close'] - entry_price) / entry_price
            
            if (current_position == 1 and (pct_change <= -stop_loss or pct_change >= take_profit)) or \
               (current_position == -1 and (pct_change >= stop_loss or pct_change <= -take_profit)):
                current_position = 0
        
        # 中轨平仓逻辑
        elif df.at[i, 'signal'] == 0 and current_position != 0:
            current_position = 0
        
        df.at[i, 'position'] = current_position
    
    return df

九、完整代码示例

# 完整策略实现
def run_bollinger_strategy(data, window=20, k=2, stop_loss=None, take_profit=None):
    # 计算布林带
    data = calculate_bollinger_bands(data, window, k)
    
    # 生成信号
    data = generate_signals(data)
    
    # 添加风险管理
    if stop_loss and take_profit:
        data = add_risk_management(data, stop_loss, take_profit)
    else:
        data = manage_positions(data)
    
    # 计算收益
    data = calculate_returns(data)
    
    return data

# 运行策略
result = run_bollinger_strategy(df.copy(), window=20, k=2, stop_loss=0.03, take_profit=0.06)
analyze_performance(result)

十、总结

本文实现了一个基于布林带突破的商品期货交易策略,主要特点包括: 1. 使用Python实现了布林带指标计算 2. 构建了完整的信号生成和持仓管理系统 3. 加入了基础的回测和绩效评估功能 4. 提出了策略优化和风险控制的改进方向

实际应用中需要注意: - 历史回测不能完全预测未来表现 - 需考虑交易成本和滑点影响 - 建议在模拟盘充分测试后再投入实盘

通过不断优化参数和加入更多过滤条件,可以进一步提高策略的稳定性和盈利能力。 “`

推荐阅读:
  1. 组策略跨林跨域迁移
  2. Python实现简单石头剪刀布游戏

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

python

上一篇:如何使用Python批量提取指定的站点空气质量数据

下一篇:Django中的unittest应用是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》