Skip to content

ATRIndicator(Average True Range,平均真实波动幅度)是一个衡量市场波动性的技术指标,广泛用于确定止损、止盈位置以及仓位管理。以下是 ATRIndicator 的详细解释,并结合你的策略(15分钟K线 + 20MA上方做多)给出具体用法。


一、ATRIndicator 的核心逻辑

  1. 计算步骤

    • True Range (TR):计算单根K线的波动幅度,取以下三者中的最大值:
      • 当前最高价 - 当前最低价
      • 当前最高价 - 前一收盘价的绝对值
      • 当前最低价 - 前一收盘价的绝对值
    • ATR:对TR进行移动平均(默认周期14),得到平滑后的波动幅度。
  2. 核心作用

    • 衡量波动性:ATR值越大,市场波动越剧烈。
    • 动态调整止损/止盈:根据当前波动性调整止损和止盈位置,避免被短期波动洗出。

二、ATRIndicator 在你的策略中的具体用法

1. 动态止损(段永平“不亏钱”)

  • 规则
    开仓后,设置初始止损为开仓价下方 2 × ATR,随着价格上涨,逐步上移止损线(追踪止损)。

  • 代码实现

java
// 计算ATR(14周期)
ATRIndicator atr = new ATRIndicator(series, 14);

// 动态止损规则
Rule stopLossRule = new StopLossRule(closePrice, atr.multipliedBy(2), true); // 2倍ATR止损
// 计算ATR(14周期)
ATRIndicator atr = new ATRIndicator(series, 14);

// 动态止损规则
Rule stopLossRule = new StopLossRule(closePrice, atr.multipliedBy(2), true); // 2倍ATR止损
  • 示例
    假设当前ATR为200美元,开仓价为30,000美元,则:
    • 初始止损 = 30,000 - (2 × 200) = 29,600
    • 价格上涨至31,000时,止损上移至31,000 - (2 × 200) = 30,600

2. 入场信号过滤(段永平“安全边际”)

  • 规则
    价格上穿20MA时,需满足价格低于20MA + 1倍ATR,确保入场点具备安全边际。

  • 代码实现

java
// 计算20MA和ATR
SMAIndicator sma20 = new SMAIndicator(closePrice, 20);
ATRIndicator atr = new ATRIndicator(series, 14);

// 买入规则:价格上穿20MA + 价格低于20MA的1倍ATR
Rule buyRule = new CrossedUpIndicatorRule(closePrice, sma20)
    .and(new UnderIndicatorRule(closePrice, sma20.plus(atr)));
// 计算20MA和ATR
SMAIndicator sma20 = new SMAIndicator(closePrice, 20);
ATRIndicator atr = new ATRIndicator(series, 14);

// 买入规则:价格上穿20MA + 价格低于20MA的1倍ATR
Rule buyRule = new CrossedUpIndicatorRule(closePrice, sma20)
    .and(new UnderIndicatorRule(closePrice, sma20.plus(atr)));
  • 示例
    假设20MA为30,000,ATR为200,则:
    • 价格需低于30,000 + 200 = 30,200
    • 价格上穿30,000时入场

3. 动态止盈(段永平“长期持有”)

  • 规则
    价格每上涨1倍ATR,止盈线上移0.5倍ATR,确保在趋势中锁定利润。

  • 代码实现

java
// 动态止盈规则
Rule takeProfitRule = new TrailingStopLossRule(closePrice, atr.multipliedBy(0.5), true); // 0.5倍ATR止盈
// 动态止盈规则
Rule takeProfitRule = new TrailingStopLossRule(closePrice, atr.multipliedBy(0.5), true); // 0.5倍ATR止盈
  • 示例
    假设开仓价为30,000,ATR为200,则:
    • 价格上涨至30,200时,止盈线上移至30,200 - (0.5 × 200) = 30,100
    • 价格上涨至30,400时,止盈线上移至30,400 - (0.5 × 200) = 30,300

4. 仓位管理(段永平“聚焦本质”)

  • 规则
    根据ATR值动态调整仓位,波动性越大,仓位越小。

  • 代码实现

java
// 计算仓位比例(ATR越大,仓位越小)
Num positionSize = series.numOf(100).dividedBy(atr); // 假设100为基准仓位
// 计算仓位比例(ATR越大,仓位越小)
Num positionSize = series.numOf(100).dividedBy(atr); // 假设100为基准仓位
  • 示例
    假设ATR为200,则仓位 = 100 / 200 = 0.5(即50%仓位)
    若ATR为100,则仓位 = 100 / 100 = 1(即100%仓位)

三、完整策略代码示例

java
// 创建价格序列
BaseBarSeries series = ...; // 加载K线数据

// 计算指标
ClosePriceIndicator closePrice = new ClosePriceIndicator(series);
SMAIndicator sma20 = new SMAIndicator(closePrice, 20);
ATRIndicator atr = new ATRIndicator(series, 14);

// 买入规则:价格上穿20MA + 价格低于20MA的1倍ATR
Rule buyRule = new CrossedUpIndicatorRule(closePrice, sma20)
    .and(new UnderIndicatorRule(closePrice, sma20.plus(atr)));

// 止损规则:2倍ATR动态止损
Rule stopLossRule = new StopLossRule(closePrice, atr.multipliedBy(2), true);

// 止盈规则:0.5倍ATR动态止盈
Rule takeProfitRule = new TrailingStopLossRule(closePrice, atr.multipliedBy(0.5), true);

// 构建策略
Strategy strategy = new BaseStrategy(buyRule, stopLossRule.or(takeProfitRule));

// 运行回测
TradingRecord tradingRecord = new BaseTradingRecord();
for (int i = series.getBeginIndex(); i <= series.getEndIndex(); i++) {
    if (strategy.shouldEnter(i)) {
        // 计算仓位比例
        Num positionSize = series.numOf(100).dividedBy(atr.getValue(i));
        tradingRecord.enter(i, series.getBar(i).getClosePrice(), positionSize);
    } else if (strategy.shouldExit(i)) {
        tradingRecord.exit(i, series.getBar(i).getClosePrice(), positionSize);
    }
}
// 创建价格序列
BaseBarSeries series = ...; // 加载K线数据

// 计算指标
ClosePriceIndicator closePrice = new ClosePriceIndicator(series);
SMAIndicator sma20 = new SMAIndicator(closePrice, 20);
ATRIndicator atr = new ATRIndicator(series, 14);

// 买入规则:价格上穿20MA + 价格低于20MA的1倍ATR
Rule buyRule = new CrossedUpIndicatorRule(closePrice, sma20)
    .and(new UnderIndicatorRule(closePrice, sma20.plus(atr)));

// 止损规则:2倍ATR动态止损
Rule stopLossRule = new StopLossRule(closePrice, atr.multipliedBy(2), true);

// 止盈规则:0.5倍ATR动态止盈
Rule takeProfitRule = new TrailingStopLossRule(closePrice, atr.multipliedBy(0.5), true);

// 构建策略
Strategy strategy = new BaseStrategy(buyRule, stopLossRule.or(takeProfitRule));

// 运行回测
TradingRecord tradingRecord = new BaseTradingRecord();
for (int i = series.getBeginIndex(); i <= series.getEndIndex(); i++) {
    if (strategy.shouldEnter(i)) {
        // 计算仓位比例
        Num positionSize = series.numOf(100).dividedBy(atr.getValue(i));
        tradingRecord.enter(i, series.getBar(i).getClosePrice(), positionSize);
    } else if (strategy.shouldExit(i)) {
        tradingRecord.exit(i, series.getBar(i).getClosePrice(), positionSize);
    }
}

四、实战注意事项

  1. ATR周期选择

    • 默认14周期适用于大多数场景,可根据币种特性调整(如高波动币种可缩短至10)。
  2. 止损/止盈倍数优化

    • 通过历史回测确定最佳倍数(如1.5倍ATR止损,0.3倍ATR止盈)。
  3. 结合更高周期确认趋势

    • 使用4小时或日线图确认趋势方向,避免逆势交易。

通过将 ATRIndicator 融入你的策略,可以实现更科学的动态止损、止盈和仓位管理,从而在币圈合约交易中更好地控制风险、捕捉趋势。


2. 当前波动率显著高于历史平均水平

定义

  • 波动率:价格的变化幅度,通常用标准差或ATR(平均真实波动幅度)来衡量。
  • 历史波动率:过去N根K线的波动率均值。
  • 显著高于:当前波动率超过历史波动率的某个阈值(例如50%)。

量化方法

  1. 计算过去N根K线的波动率(以标准差为例):

    • 计算每根K线的收益率: [ \text{Return}i = \frac{\text{Close}i - \text{Close}{i-1}}{\text{Close}{i-1}} ]
    • 计算收益率的标准差: [ \text{HistoricalVolatility} = \sqrt{\frac{\sum_{i=1}^{N} (\text{Return}_i - \text{AvgReturn})^2}{N}} ]
      • ( \text{AvgReturn} ):过去N根K线的平均收益率。
  2. 计算当前波动率:

    • 当前波动率可以用最近M根K线(例如M=5)的收益率标准差来衡量。
  3. 判断是否显著高于:

    • 如果当前波动率 > 历史波动率 × 1.5(即当前波动率比历史波动率高50%),则认为波动率显著高于。

代码示例(Java)

java
public boolean isVolatilitySignificantlyHigh(double[] closes, double[] recentCloses) {
    int N = closes.length;
    double[] returns = new double[N - 1];
    for (int i = 1; i < N; i++) {
        returns[i - 1] = (closes[i] - closes[i - 1]) / closes[i - 1];
    }
    double avgReturn = Arrays.stream(returns).average().orElse(0);
    double historicalVolatility = Math.sqrt(Arrays.stream(returns)
            .map(r -> Math.pow(r - avgReturn, 2))
            .average()
            .orElse(0));

    int M = recentCloses.length;
    double[] recentReturns = new double[M - 1];
    for (int i = 1; i < M; i++) {
        recentReturns[i - 1] = (recentCloses[i] - recentCloses[i - 1]) / recentCloses[i - 1];
    }
    double currentVolatility = Math.sqrt(Arrays.stream(recentReturns)
            .map(r -> Math.pow(r - Arrays.stream(recentReturns).average().orElse(0), 2))
            .average()
            .orElse(0));

    return currentVolatility > historicalVolatility * 1.5; // 阈值设为1.5(50%)
}
public boolean isVolatilitySignificantlyHigh(double[] closes, double[] recentCloses) {
    int N = closes.length;
    double[] returns = new double[N - 1];
    for (int i = 1; i < N; i++) {
        returns[i - 1] = (closes[i] - closes[i - 1]) / closes[i - 1];
    }
    double avgReturn = Arrays.stream(returns).average().orElse(0);
    double historicalVolatility = Math.sqrt(Arrays.stream(returns)
            .map(r -> Math.pow(r - avgReturn, 2))
            .average()
            .orElse(0));

    int M = recentCloses.length;
    double[] recentReturns = new double[M - 1];
    for (int i = 1; i < M; i++) {
        recentReturns[i - 1] = (recentCloses[i] - recentCloses[i - 1]) / recentCloses[i - 1];
    }
    double currentVolatility = Math.sqrt(Arrays.stream(recentReturns)
            .map(r -> Math.pow(r - Arrays.stream(recentReturns).average().orElse(0), 2))
            .average()
            .orElse(0));

    return currentVolatility > historicalVolatility * 1.5; // 阈值设为1.5(50%)
}

3. 参数选择与优化

  • 波动率阈值:1.5(50%)是一个常用值,但可以根据历史数据回测找到最优值。
  • 周期长度
    • 波动率:N=20(历史波动率),M=5(当前波动率)。

在金融技术分析中,ATR(Average True Range,平均真实波幅) 是一个衡量市场波动性的关键指标。当使用 14周期 的 ATR 时,其数值大小直接反映了价格波动的剧烈程度。以下是不同 ATR 值的具体含义及其应用场景:


1. ATR 的基本含义

  • 计算公式
    ATR(14) 是过去 14个交易日 的「真实波幅(True Range, TR)」的移动平均值。

    • True Range = max(当日最高价 - 当日最低价, |当日最高价 - 前日收盘价|, |当日最低价 - 前日收盘价|)
    • ATR(14) = SMA(TR, 14) (简单移动平均)。
  • 核心作用
    衡量价格波动幅度,与方向无关(无论上涨还是下跌,ATR 只关注波动大小)。


2. ATR(14) 数值的解读

(1)绝对值的大小

ATR(14) 值市场波动性典型场景
< 1%极低波动盘整行情(如窄幅震荡的股票或外汇市场)。
1%~3%低波动稳定趋势(如蓝筹股或成熟市场)。
3%~5%中等波动正常趋势行情(如活跃的股票或商品期货)。
> 5%高波动剧烈波动(如小盘股、加密货币、突发事件后的市场)。

示例

  • 若某股票的 ATR(14) = 2.5,表示过去 14 天平均每日价格波动约 2.5%。
  • 若加密货币的 ATR(14) = 15,表明每日波动极大(需结合价格单位理解,如比特币的 15 美元 vs. 山寨币的 15%)。

(2)相对变化

  • ATR 上升:波动性增加,可能预示趋势加速或反转(如突破、新闻事件)。
  • ATR 下降:波动性减弱,可能进入盘整或趋势衰竭。

3. 实际应用场景

(1)设定止损/止盈

  • 止损:常用 2×ATR 作为动态止损距离。例如 ATR(14)=3,则止损设为当前价格 ±6。
  • 止盈:在趋势交易中,目标可设为 1×ATR3×ATR(根据风险偏好调整)。

(2)过滤虚假信号

  • 低 ATR 环境:避免在 ATR < 1% 时交易,因盈利空间有限。
  • 高 ATR 环境:需警惕滑点和流动性风险(如加密货币)。

(3)仓位管理

  • 波动调整仓位:ATR 越大,单笔交易仓位应越小(控制风险)。
    公式:仓位 = 固定风险金额 / (ATR × 合约乘数)

4. 不同市场的典型 ATR(14) 范围

资产类型典型 ATR(14) 范围说明
大盘股(如苹果)1%~3%流动性高,波动稳定。
小盘股/生物科技5%~10%高风险高波动。
黄金(XAU/USD)1.5%~2.5%避险资产,波动适中。
比特币(BTC)3%~8%7×24 小时交易,波动剧烈。
外汇(EUR/USD)0.5%~1%主要货币对流动性极强。

5. 在 TA4J 中监控 ATR 变化

java
// 示例:检测 ATR(14) 是否突破阈值
ATRIndicator atr = new ATRIndicator(series, 14);
double currentATR = atr.getValue(series.getEndIndex()).doubleValue();

if (currentATR > 5.0) {
    System.out.println("警告:高波动市场!");
} else if (currentATR < 1.0) {
    System.out.println("低波动,谨慎交易。");
}
// 示例:检测 ATR(14) 是否突破阈值
ATRIndicator atr = new ATRIndicator(series, 14);
double currentATR = atr.getValue(series.getEndIndex()).doubleValue();

if (currentATR > 5.0) {
    System.out.println("警告:高波动市场!");
} else if (currentATR < 1.0) {
    System.out.println("低波动,谨慎交易。");
}

6. 注意事项

  1. 价格单位影响
    • ATR 的绝对值需结合价格理解(如股票 ATR=2 可能是 2 元,而外汇是 2 点)。
  2. 周期选择
    • 短周期(如 ATR(7))反应更快,但噪音多;长周期(如 ATR(21))更平滑但滞后。
  3. 结合其他指标
    • 与趋势指标(如 MACD、均线)配合使用,避免在震荡市中误判。

总结

ATR(14) 的值直接量化了市场的波动强度:

  • 小值 → 低波动 → 适合区间交易或观望。
  • 大值 → 高波动 → 适合趋势跟踪或严格风控。
    通过 TA4J 计算 ATR 后,可动态调整交易策略,显著提升风险控制能力。