🚀 AI 一键生成 joinquant 策略代码

JoinQuant 策略编程:威廉鳄鱼线(Alligator)指标实现与应用

joinquant | 发布时间: 2025/12/22
以下内容由 EasyQuant 生成。

问题描述

请帮我写一个威廉鳄鱼线指标的量化策略

解决方案

这是一个基于**威廉鳄鱼线(Williams Alligator)**指标的量化策略实现。

策略原理

鳄鱼线指标由比尔·威廉姆斯(Bill Williams)发明,旨在通过三条平滑移动平均线(SMMA)的组合来识别趋势的开始和结束。

  1. 鳄鱼的下巴 (Jaw - 蓝线): 13周期SMMA(平滑移动平均),向未来平移8个周期。
  2. 鳄鱼的牙齿 (Teeth - 红线): 8周期SMMA,向未来平移5个周期。
  3. 鳄鱼的嘴唇 (Lips - 绿线): 5周期SMMA,向未来平移3个周期。

交易逻辑:

  • 多头信号(张嘴进食): 嘴唇 > 牙齿 > 下巴 (绿 > 红 > 蓝),且价格收盘价高于嘴唇。这表示趋势向上。
  • 平仓/空头信号(闭嘴睡觉): 价格跌破牙齿(红线)或下巴(蓝线),或者均线缠绕(不再满足多头排列)。本策略简化为:当价格跌破下巴(蓝线)或均线不再呈多头排列时平仓。

策略代码

# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
from jqdata import *

def initialize(context):
    """
    初始化函数,设定基准、手续费、滑点等
    """
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开开启真实价格模式(动态复权)
    set_option('use_real_price', True)
    # 过滤掉order系列API产生的比error级别低的log
    log.set_level('order', 'error')
    
    # 设定手续费:股票买入万分之三,卖出万分之三加千分之一印花税
    set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
    
    # 设定要操作的股票池(这里示例使用沪深300成分股的前10只,避免回测过慢)
    g.security_pool = get_index_stocks('000300.XSHG')[:10]
    
    # 鳄鱼线参数
    g.N1, g.shift1 = 13, 8  # 下巴 (Jaw)
    g.N2, g.shift2 = 8, 5   # 牙齿 (Teeth)
    g.N3, g.shift3 = 5, 3   # 嘴唇 (Lips)
    
    # 每天开盘时运行策略
    run_daily(trade_func, time='open')

def get_smma(series, n):
    """
    计算平滑移动平均线 (SMMA)
    SMMA 等同于 alpha = 1/n 的指数移动平均 (EMA)
    """
    return series.ewm(alpha=1.0/n, adjust=False).mean()

def trade_func(context):
    """
    每日交易主逻辑
    """
    # 获取足够长的历史数据以计算指标 (取100天以保证MA计算稳定)
    # 注意:鳄鱼线需要向未来平移,所以我们需要回溯 (Max_N + Max_Shift) 以上的数据
    # 这里取100天足够覆盖
    hist_len = 100
    
    for stock in g.security_pool:
        # 获取历史数据:高、低、收
        data = attribute_history(stock, hist_len, '1d', ['high', 'low', 'close'], skip_paused=True)
        
        if len(data) < 30:
            continue
            
        # 1. 计算中价 (Median Price) = (High + Low) / 2
        median_price = (data['high'] + data['low']) / 2
        
        # 2. 计算三条SMMA轨道
        # 注意:这里计算的是基于历史数据的序列
        smma_jaw = get_smma(median_price, g.N1)   # 13周期
        smma_teeth = get_smma(median_price, g.N2) # 8周期
        smma_lips = get_smma(median_price, g.N3)  # 5周期
        
        # 3. 获取"当前"生效的指标值 (考虑平移)
        # 这里的逻辑是:今天的指标值 = (Shift)天前计算出来的SMMA值
        # data的最后一个数据索引是 -1 (昨天收盘),我们需要基于昨天的数据判断今天开盘的操作
        
        # 下巴 (Jaw): 13周期,平移8 --> 取倒数第 (1 + 8) 个数据
        jaw_value = smma_jaw.iloc[-(1 + g.shift1)]
        
        # 牙齿 (Teeth): 8周期,平移5 --> 取倒数第 (1 + 5) 个数据
        teeth_value = smma_teeth.iloc[-(1 + g.shift2)]
        
        # 嘴唇 (Lips): 5周期,平移3 --> 取倒数第 (1 + 3) 个数据
        lips_value = smma_lips.iloc[-(1 + g.shift3)]
        
        # 获取昨天的收盘价
        current_close = data['close'].iloc[-1]
        
        # 获取当前持仓
        position = context.portfolio.positions[stock]
        
        # --- 交易信号判断 ---
        
        # 多头排列条件:嘴唇 > 牙齿 > 下巴 (绿 > 红 > 蓝)
        is_long_trend = (lips_value > teeth_value) and (teeth_value > jaw_value)
        
        # 价格确认:收盘价在嘴唇之上 (表示动能强劲)
        price_confirm = current_close > lips_value
        
        # 买入逻辑
        if is_long_trend and price_confirm:
            if position.total_amount == 0:
                # 全仓买入 (这里简单均分资金,实际可调整仓位管理)
                cash_per_stock = context.portfolio.available_cash / (len(g.security_pool) / 2) # 假设同时持有一半的股票
                order_value(stock, cash_per_stock)
                log.info(f"买入 {stock}: 鳄鱼张嘴,趋势向上")
        
        # 卖出逻辑
        # 如果价格跌破下巴 (蓝线),或者均线不再呈多头排列,则平仓
        elif (current_close < jaw_value) or (not is_long_trend):
            if position.closeable_amount > 0:
                order_target(stock, 0)
                log.info(f"卖出 {stock}: 鳄鱼闭嘴或价格破位")

代码关键点解析

  1. SMMA 计算:

    • 标准的鳄鱼线使用的是 SMMA(Smoothed Moving Average)。在 Pandas 中,SMMA 可以通过 ewm(alpha=1/n) 来精确模拟。
    • 代码中定义了 get_smma 辅助函数来处理这个计算。
  2. 平移 (Shift) 的处理:

    • 这是鳄鱼线最容易出错的地方。指标定义是“向未来平移”。
    • 在回测或实盘中,这意味着:今天看到的“下巴”值,实际上是8天前计算出来的SMMA数值
    • 代码中使用 iloc[-(1 + g.shift)] 来获取正确的值。例如,shift=8,我们要取的是倒数第9个数据(因为倒数第1个是昨天,倒数第9个是8天前)。
  3. 中价 (Median Price):

    • 鳄鱼线不使用收盘价计算均线,而是使用 (最高价 + 最低价) / 2,代码中正确实现了这一点。
  4. 买卖逻辑:

    • 买入: 严格遵循 Lips > Teeth > JawClose > Lips,确保是在趋势爆发期介入。
    • 卖出: 当价格跌穿最下方的支撑线(下巴/蓝线)或者均线纠缠(趋势结束)时离场。

如何使用

  1. 登录聚宽官网 (JoinQuant)。
  2. 进入“我的策略” -> “新建策略”。
  3. 将上述代码复制粘贴到代码编辑区。
  4. 点击“编译运行”进行回测。

常见问题 (Q&A)

Q: 为什么使用 SMMA 而不是普通的 SMA 或 EMA?
A: 比尔·威廉姆斯在设计该指标时特意选择了平滑移动平均(SMMA),因为它比 SMA 更平滑,比 EMA 对旧数据的遗忘速度更慢,适合捕捉中长期趋势并过滤震荡噪音。

Q: 策略中的 shift 是如何实现的?
A: 在绘图中,shift 是将线条向右画。在量化逻辑中,这意味着当前的指标值等于 $N$ 天前的计算值。代码通过 iloc 索引回溯历史数据来实现这一逻辑,避免了未来函数。

Q: 这个策略适合什么行情?
A: 鳄鱼线是典型的趋势跟踪策略。它在单边大牛市或大熊市中表现优异(鳄鱼张嘴进食),但在震荡市(鳄鱼睡觉)中可能会频繁止损。建议结合其他过滤器(如分形指标 Fractals)使用以提高胜率。