Pharos
TAVolatility

TA.TRANGE() - 真实波幅

真实波幅 (True Range)

单根 K 线的真实波幅,ATR 是 TRANGE 的移动平均。

返回波动率指标目录


语法

python
TA.TRANGE(high, low, close)

参数

参数名类型必选默认值说明
highany-最高价数组
lowany-最低价数组
closeany-收盘价数组

返回值

返回真实波幅数组,单位与价格相同。

计算方法

真实波幅取以下三个值的最大值:

plaintext
True Range = MAX(
    High - Low,              # 当日最高最低价差
    |High - PrevClose|,      # 当日最高与前收盘价差
    |Low - PrevClose|        # 当日最低与前收盘价差
)

为什么需要 True Range?

普通的 High-Low 无法捕捉跳空缺口,而 True Range 考虑了:

  • 向上跳空:开盘价高于前收盘价
  • 向下跳空:开盘价低于前收盘价

信号解读

波动性判断

  • TRANGE 大:当日波动剧烈
  • TRANGE 小:当日波动平静
  • TRANGE 突增:市场出现重要变化
  • TRANGE 缩小:市场进入整理期

应用场景

  1. 日内波动:衡量单日价格波动幅度
  2. 异常检测:识别异常波动的交易日
  3. ATR 基础:ATR = MA(TRANGE)
  4. 风险预警:TRANGE 异常可能预示风险

基础示例

真实波幅计算

python
def main():
    while True:
        records = exchange.GetRecords()
        if len(records) < 30:
            Sleep(1000)
            continue
        
        highs = [r['High'] for r in records]
        lows = [r['Low'] for r in records]
        closes = [r['Close'] for r in records]
        
        trange = TA.TRANGE(highs, lows, closes)
        current_trange = trange[-1]
        current_price = closes[-1]
        
        # TRANGE 占价格的百分比
        trange_percent = (current_trange / current_price) * 100
        
        Log("最新真实波幅:", current_trange)
        Log("TRANGE 百分比:", trange_percent, "%")
        
        # 判断波动
        if trange_percent > 5:
            Log("⚠️ 当日剧烈波动")
        elif trange_percent < 1:
            Log("💤 当日波动很小")
        
        Sleep(60000)

高级应用

异常波动检测

python
def main():
    while True:
        records = exchange.GetRecords()
        if len(records) < 50:
            Sleep(1000)
            continue
        
        highs = [r['High'] for r in records]
        lows = [r['Low'] for r in records]
        closes = [r['Close'] for r in records]
        
        trange = TA.TRANGE(highs, lows, closes)
        current_trange = trange[-1]
        
        # 计算平均真实波幅
        avg_trange = sum(trange[-20:]) / 20
        
        # 检测异常波动
        if current_trange > avg_trange * 2:
            Log("⚠️ 检测到异常波动,TRANGE 是平均值的 2 倍以上")
            Log("可能有重要消息或事件发生")
            
            # 检查是否有跳空
            prev_close = closes[-2]
            current_open = records[-1]['Open']
            gap = abs(current_open - prev_close) / prev_close * 100
            
            if gap > 2:
                Log(f"存在 {gap:.2f}% 的跳空")
        
        elif current_trange < avg_trange * 0.5:
            Log("💤 波动异常缩小,市场非常平静")
        
        Sleep(60000)

TRANGE 与 ATR 对比

python
def main():
    while True:
        records = exchange.GetRecords()
        if len(records) < 50:
            Sleep(1000)
            continue
        
        highs = [r['High'] for r in records]
        lows = [r['Low'] for r in records]
        closes = [r['Close'] for r in records]
        
        # 真实波幅(当日)
        trange = TA.TRANGE(highs, lows, closes)
        current_trange = trange[-1]
        
        # 平均真实波幅(14 日均值)
        atr = TA.ATR(highs, lows, closes, 14)
        current_atr = atr[-1]
        
        # 对比
        ratio = current_trange / current_atr if current_atr != 0 else 0
        
        Log(f"当日 TRANGE: {current_trange:.2f}")
        Log(f"14 日 ATR: {current_atr:.2f}")
        Log(f"TRANGE/ATR 比率: {ratio:.2f}")
        
        # 判断当日波动
        if ratio > 1.5:
            Log("✅ 当日波动远高于平均,市场活跃")
        elif ratio < 0.5:
            Log("💤 当日波动远低于平均,市场平静")
        else:
            Log("📊 当日波动接近平均水平")
        
        Sleep(60000)

跳空缺口识别

python
def main():
    while True:
        records = exchange.GetRecords()
        if len(records) < 10:
            Sleep(1000)
            continue
        
        highs = [r['High'] for r in records]
        lows = [r['Low'] for r in records]
        closes = [r['Close'] for r in records]
        
        trange = TA.TRANGE(highs, lows, closes)
        
        # 当前 K 线
        current_high = highs[-1]
        current_low = lows[-1]
        prev_close = closes[-2]
        
        # 计算三个值
        high_low_range = current_high - current_low
        high_prev_close = abs(current_high - prev_close)
        low_prev_close = abs(current_low - prev_close)
        
        # TRANGE 是哪个值
        if trange[-1] == high_low_range:
            Log("无跳空,TRANGE = High - Low")
        elif trange[-1] == high_prev_close:
            Log(f"向上跳空,TRANGE = |High - PrevClose| = {high_prev_close:.2f}")
        elif trange[-1] == low_prev_close:
            Log(f"向下跳空,TRANGE = |Low - PrevClose| = {low_prev_close:.2f}")
        
        # 识别跳空类型
        if current_low > prev_close:
            gap_percent = ((current_low - prev_close) / prev_close) * 100
            Log(f"⬆️ 向上跳空 {gap_percent:.2f}%")
        elif current_high < prev_close:
            gap_percent = ((prev_close - current_high) / prev_close) * 100
            Log(f"⬇️ 向下跳空 {gap_percent:.2f}%")
        
        Sleep(60000)

TRANGE 波动率日历

python
def main():
    while True:
        records = exchange.GetRecords()
        if len(records) < 100:
            Sleep(1000)
            continue
        
        highs = [r['High'] for r in records]
        lows = [r['Low'] for r in records]
        closes = [r['Close'] for r in records]
        
        trange = TA.TRANGE(highs, lows, closes)
        
        # 统计最近 20 日的波动
        recent_trange = trange[-20:]
        
        # 找出高波动日
        avg_trange = sum(recent_trange) / len(recent_trange)
        high_vol_days = [i for i, tr in enumerate(recent_trange) if tr > avg_trange * 1.5]
        low_vol_days = [i for i, tr in enumerate(recent_trange) if tr < avg_trange * 0.5]
        
        Log("=== 波动率日历 (最近 20 日) ===")
        Log(f"平均 TRANGE: {avg_trange:.2f}")
        Log(f"高波动日数: {len(high_vol_days)}")
        Log(f"低波动日数: {len(low_vol_days)}")
        Log(f"最大 TRANGE: {max(recent_trange):.2f}")
        Log(f"最小 TRANGE: {min(recent_trange):.2f}")
        
        # 当前波动趋势
        last_5_avg = sum(trange[-5:]) / 5
        if last_5_avg > avg_trange * 1.2:
            Log("📈 近期波动性上升")
        elif last_5_avg < avg_trange * 0.8:
            Log("📉 近期波动性下降")
        
        Sleep(60000)

参数优化建议

TRANGE 无参数,但可以设置不同的分析周期:

分析周期推荐值说明
短期5-10 日近期波动趋势
中期20 日标准分析周期
长期50-100 日长期波动特征

与其他指标配合

TRANGE + ATR

python
trange = TA.TRANGE(highs, lows, closes)
atr = TA.ATR(highs, lows, closes, 14)

# 当日波动 vs 平均波动
if trange[-1] > atr[-1] * 2:
    Log("当日波动远超平均,注意风险")

TRANGE + 成交量

python
trange = TA.TRANGE(highs, lows, closes)
volumes = [r['Volume'] for r in records]

# 大波动 + 大成交量
if trange[-1] > sum(trange[-20:])/20 * 1.5:
    if volumes[-1] > sum(volumes[-20:])/20 * 1.5:
        Log("高波动 + 高成交量,重要信号")

TRANGE + 价格位置

python
trange = TA.TRANGE(highs, lows, closes)
resistance = max(highs[-20:])
support = min(lows[-20:])

# 在关键位置的波动
if closes[-1] > resistance and trange[-1] > sum(trange[-20:])/20 * 1.5:
    Log("突破阻力位 + 高波动,强势信号")

注意事项

  1. 单日数据:TRANGE 只反映单日波动,需结合均值分析
  2. 跳空处理:TRANGE 能正确处理跳空缺口
  3. 极端值:重大事件会导致 TRANGE 极端值
  4. ATR 关系:ATR = MA(TRANGE, period)
  5. 无方向性:TRANGE 只衡量波动幅度,不判断方向
  6. 时间周期:日线 TRANGE 比分钟线更有意义
  7. 币种差异:不同币种的 TRANGE 绝对值不可比

相关指标

实战要点

TRANGE 的最佳用途

异常检测:识别异常波动的交易日 ✅ 跳空识别:检测价格跳空缺口 ✅ ATR 理解:帮助理解 ATR 的计算原理 ✅ 日内分析:评估单日的波动特征

异常波动阈值

  • TRANGE > 2 倍平均:异常高波动
  • TRANGE > 3 倍平均:极端波动,可能有重大事件
  • TRANGE < 0.5 倍平均:异常低波动
  • TRANGE < 0.3 倍平均:极端平静,可能酝酿变化

实战经验

  • 重大新闻日 TRANGE 通常是平均值的 2-5 倍
  • 节假日 TRANGE 通常较小
  • TRANGE 连续缩小可能预示大行情
  • TRANGE 突增后通常伴随趋势变化

返回波动率指标目录 | 返回 TA 指标总目录