TAVolatility
TA.TRANGE() - 真实波幅
真实波幅 (True Range)
单根 K 线的真实波幅,ATR 是 TRANGE 的移动平均。
语法
python
TA.TRANGE(high, low, close)参数
| 参数名 | 类型 | 必选 | 默认值 | 说明 |
|---|---|---|---|---|
| high | any | 否 | - | 最高价数组 |
| low | any | 否 | - | 最低价数组 |
| close | any | 否 | - | 收盘价数组 |
返回值
返回真实波幅数组,单位与价格相同。
计算方法
真实波幅取以下三个值的最大值:
plaintext
True Range = MAX(
High - Low, # 当日最高最低价差
|High - PrevClose|, # 当日最高与前收盘价差
|Low - PrevClose| # 当日最低与前收盘价差
)为什么需要 True Range?
普通的 High-Low 无法捕捉跳空缺口,而 True Range 考虑了:
- 向上跳空:开盘价高于前收盘价
- 向下跳空:开盘价低于前收盘价
信号解读
波动性判断
- TRANGE 大:当日波动剧烈
- TRANGE 小:当日波动平静
- TRANGE 突增:市场出现重要变化
- TRANGE 缩小:市场进入整理期
应用场景
- 日内波动:衡量单日价格波动幅度
- 异常检测:识别异常波动的交易日
- ATR 基础:ATR = MA(TRANGE)
- 风险预警: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("突破阻力位 + 高波动,强势信号")注意事项
- 单日数据:TRANGE 只反映单日波动,需结合均值分析
- 跳空处理:TRANGE 能正确处理跳空缺口
- 极端值:重大事件会导致 TRANGE 极端值
- ATR 关系:ATR = MA(TRANGE, period)
- 无方向性:TRANGE 只衡量波动幅度,不判断方向
- 时间周期:日线 TRANGE 比分钟线更有意义
- 币种差异:不同币种的 TRANGE 绝对值不可比
相关指标
- ATR - 平均真实波幅 - TRANGE 的移动平均
- NATR - 标准化 ATR - ATR 的百分比形式
- BBANDS - 布林带 - 基于标准差的波动指标
实战要点
TRANGE 的最佳用途
✅ 异常检测:识别异常波动的交易日 ✅ 跳空识别:检测价格跳空缺口 ✅ ATR 理解:帮助理解 ATR 的计算原理 ✅ 日内分析:评估单日的波动特征
异常波动阈值
- TRANGE > 2 倍平均:异常高波动
- TRANGE > 3 倍平均:极端波动,可能有重大事件
- TRANGE < 0.5 倍平均:异常低波动
- TRANGE < 0.3 倍平均:极端平静,可能酝酿变化
实战经验
- 重大新闻日 TRANGE 通常是平均值的 2-5 倍
- 节假日 TRANGE 通常较小
- TRANGE 连续缩小可能预示大行情
- TRANGE 突增后通常伴随趋势变化