ATRIndicator
(Average True Range,平均真实波动幅度)是一个衡量市场波动性的技术指标,广泛用于确定止损、止盈位置以及仓位管理。以下是 ATRIndicator
的详细解释,并结合你的策略(15分钟K线 + 20MA上方做多)给出具体用法。
一、ATRIndicator 的核心逻辑
计算步骤:
- True Range (TR):计算单根K线的波动幅度,取以下三者中的最大值:
- 当前最高价 - 当前最低价
- 当前最高价 - 前一收盘价的绝对值
- 当前最低价 - 前一收盘价的绝对值
- ATR:对TR进行移动平均(默认周期14),得到平滑后的波动幅度。
- True Range (TR):计算单根K线的波动幅度,取以下三者中的最大值:
核心作用:
- 衡量波动性: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);
}
}
四、实战注意事项
ATR周期选择:
- 默认14周期适用于大多数场景,可根据币种特性调整(如高波动币种可缩短至10)。
止损/止盈倍数优化:
- 通过历史回测确定最佳倍数(如1.5倍ATR止损,0.3倍ATR止盈)。
结合更高周期确认趋势:
- 使用4小时或日线图确认趋势方向,避免逆势交易。
通过将 ATRIndicator
融入你的策略,可以实现更科学的动态止损、止盈和仓位管理,从而在币圈合约交易中更好地控制风险、捕捉趋势。
2. 当前波动率显著高于历史平均水平
定义
- 波动率:价格的变化幅度,通常用标准差或ATR(平均真实波动幅度)来衡量。
- 历史波动率:过去N根K线的波动率均值。
- 显著高于:当前波动率超过历史波动率的某个阈值(例如50%)。
量化方法
计算过去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线的平均收益率。
计算当前波动率:
- 当前波动率可以用最近M根K线(例如M=5)的收益率标准差来衡量。
判断是否显著高于:
- 如果当前波动率 > 历史波动率 × 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)
(简单移动平均)。
- True Range =
核心作用:
衡量价格波动幅度,与方向无关(无论上涨还是下跌,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×ATR
或3×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. 注意事项
- 价格单位影响:
- ATR 的绝对值需结合价格理解(如股票 ATR=2 可能是 2 元,而外汇是 2 点)。
- 周期选择:
- 短周期(如 ATR(7))反应更快,但噪音多;长周期(如 ATR(21))更平滑但滞后。
- 结合其他指标:
- 与趋势指标(如 MACD、均线)配合使用,避免在震荡市中误判。
总结
ATR(14) 的值直接量化了市场的波动强度:
- 小值 → 低波动 → 适合区间交易或观望。
- 大值 → 高波动 → 适合趋势跟踪或严格风控。
通过 TA4J 计算 ATR 后,可动态调整交易策略,显著提升风险控制能力。