🚀 AI 一键生成 joinquant 策略代码
立即体验

聚宽平台如何用最高最低价区间计算一目均衡表(Ichimoku)?(附 Python 策略源码)

joinquant | 发布时间: 2026/8/7
以下内容由 EasyQuant 生成。

问题描述

聚宽自定义指标:如何用最高最低价区间计算一目均衡表?
如何在聚宽策略中使用历史 high、low、close 数据计算 Tenkan-sen、Kijun-sen、Senkou Span A/B,并将价格位于云层上方作为趋势过滤条件?

解决方案

一目均衡表(Ichimoku Kinko Hyo)是一种经典的趋势跟踪指标,它通过不同周期内的最高价(High)和最低价(Low)的中点来寻找市场的支撑、阻力及趋势方向。在聚宽(JoinQuant)平台上,我们可以通过 attribute_historyget_bars 获取历史的 highlow 数据,并自定义计算出该指标的各个轨道。

一、一目均衡表核心公式

  1. 转换线 (Tenkan-sen / Conversion Line): (过去9日最高价 + 过去9日最低价) / 2
  2. 基准线 (Kijun-sen / Base Line): (过去26日最高价 + 过去26日最低价) / 2
  3. 先行带A (Senkou Span A / Leading Span A): (转换线 + 基准线) / 2,并向后(未来)平移26期
  4. 先行带B (Senkou Span B / Leading Span B): (过去52日最高价 + 过去52日最低价) / 2,并向后(未来)平移26期
  5. 云层 (Kumo / Cloud): 先行带A与先行带B之间的区域。价格在云层上方代表强势多头趋势。

注:在回测的当前时刻(T日),我们对比的是「当前价格」与「T日显现的云层」(即T-26日计算并平移至T日的先行带A和B)。

二、聚宽策略源码实现

以下是一个完整的聚宽策略,展示了如何计算一目均衡表,并在价格位于云层上方时进行买入,低于基准线时卖出的趋势过滤策略:

import jqdata
import numpy as np
import pandas as pd

def initialize(context):
    # 设定操作的股票:平安银行
    g.security = '000001.XSHE'
    # 设定沪深300作为基准
    set_benchmark('000300.XSHG')
    # 开启动态复权模式(真实价格)
    set_option('use_real_price', True)
    
    # 运行频率:每天运行
    run_daily(market_open, time='every_bar')

def market_open(context):
    security = g.security
    
    # 1. 获取计算一目均衡表所需的最大历史数据(52 + 26 = 78天,确保平移后有足够数据)
    hist = attribute_history(security, 80, '1d', ['high', 'low', 'close'])
    
    if len(hist) < 80:
        return
        
    # 2. 计算转换线 (Tenkan-sen): 9日中点
    tenkan_sen = (hist['high'].rolling(window=9).max() + hist['low'].rolling(window=9).min()) / 2
    
    # 3. 计算基准线 (Kijun-sen): 26日中点
    kijun_sen = (hist['high'].rolling(window=26).max() + hist['low'].rolling(window=26).min()) / 2
    
    # 4. 计算先行带A (Senkou Span A) - 需向后平移26天
    # 在当前T时刻,我们看到的Senkou Span A是26天前计算出来的结果
    senkou_span_a = ((tenkan_sen + kijun_sen) / 2).shift(26)
    
    # 5. 计算先行带B (Senkou Span B) - 52日中点,向后平移26天
    senkou_span_b = ((hist['high'].rolling(window=52).max() + hist['low'].rolling(window=52).min()) / 2).shift(26)
    
    # 获取当前最新值(即hist的最后一行,对应昨日收盘或当前最新价)
    current_price = hist['close'].iloc[-1]
    current_kijun = kijun_sen.iloc[-1]
    current_span_a = senkou_span_a.iloc[-1]
    current_span_b = senkou_span_b.iloc[-1]
    
    # 获取当前可用现金
    cash = context.portfolio.available_cash
    
    # 6. 趋势过滤与交易信号
    # 趋势过滤条件:价格位于云层上方(即价格大于Senkou Span A和B的较大值)
    cloud_top = max(current_span_a, current_span_b)
    is_bullish = current_price > cloud_top
    
    # 持仓状态
    has_position = context.portfolio.positions[security].closeable_amount > 0
    
    # 买入信号:处于多头趋势(云层上方),且当前无持仓
    if is_bullish and not has_position:
        order_value(security, cash)
        log.info("价格 %.2f 突破云层顶 %.2f,全仓买入 %s" % (current_price, cloud_top, security))
        
    # 卖出信号:价格跌破基准线(Kijun-sen),且当前有持仓
    elif current_price < current_kijun and has_position:
        order_target(security, 0)
        log.info("价格 %.2f 跌破基准线 %.2f,清仓卖出 %s" % (current_price, current_kijun, security))
        
    # 记录指标曲线
    record(price=current_price, span_a=current_span_a, span_b=current_span_b, kijun=current_kijun)

三、策略逻辑解析

  1. 数据获取: 策略使用 attribute_history 获取了 80 天的 highlowclose 数据。由于一目均衡表的先行带需要向后平移 26 期,因此必须获取至少 52 + 26 = 78 天的数据,才能计算出当前时刻有效的 Senkou Span A/B
  2. Pandas 滚动计算: 利用 rolling(window=N).max()min() 快速计算出指定周期内的最高价和最低价,并通过 .shift(26) 实现指标向未来平移的效果。
  3. 云层趋势过滤: 通过 max(current_span_a, current_span_b) 确定云层的上轨。只有当最新价格高于云层上轨时,策略才允许买入,从而有效过滤了震荡市和下跌趋势中的假突破。