Author Message:
The Adaptive Mean Reversion Indicator is a tool for identifying mean reversion trading opportunities in the market. The indicator employs a dynamic approach by adapting its parameters based on the detected market regime, ensuring optimal performance in different market conditions.
To determine the market regime, the indicator utilizes a volatility threshold. By comparing the average true range (ATR) over a 14-period to the specified threshold, it determines whether the market is trending or ranging. This information is crucial as it sets the foundation for parameter optimization.
The parameter optimization process is an essential step in the indicator's calculation. It dynamically adjusts the lookback period and threshold level based on the identified market regime. In trending markets, a longer lookback period and higher threshold level are chosen to capture extended trends. In ranging markets, a shorter lookback period and lower threshold level are used to identify mean reversion opportunities within a narrower price range.
https://www.tradingview.com/v/UWITlMWj/
CODE:
CSS:
#// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
# https://www.tradingview.com/v/UWITlMWj/
#// © LeafAlgo
#indicator("Adaptive Mean Reversion Indicator", overlay=false)
# Converted and mod by sam4Cok@Samer800 - 06/2023
declare lower;
#// Market Regime Detection
input ColorBars = yes;
input source = close;
input smoothing = yes;
input smoothingLength = 3;
input LookbackPeriodTrending = 40;
input LookbackPeriodRanging = 20;
input ThresholdLevelTrending = 2.0;
input ThresholdLevelRanging = 1.5;
input atrLength = 14;
input rsiLength = 14;#, "RSI Length")
def na = Double.NaN;
def pos = Double.POSITIVE_INFINITY;
def neg = Double.NEGATIVE_INFINITY;
#// Volatility function
def x = Exp(StDev(Log(close / close[1]), atrLength) * atrLength);
def h = source * Power(x, 2);
def l = source / Power(x, 2);
def vol = 100 * (close - lowest(l, atrLength)) / (highest(h, atrLength) - lowest(l, atrLength));
#// ATR
def len = Min(2000, AbsValue(Floor(106 * (if IsNaN(vol) then 1 else vol / 100))));
def hh = Highest(high, atrLength);
def ll = Lowest(low, atrLength);
def tr = TrueRange(hh, close, ll);
def modATR = (tr + (len - 1) * modATR[1]) / len;
def nATR = ATR(LENGTH = atrLength);
def isTrending = nATR > modATR;
#// Parameter Optimization
def thresholdLevel = if isTrending then ThresholdLevelTrending else ThresholdLevelRanging;
#// Calculate Mean Reversion
def preMean = if isTrending then Average(source, LookbackPeriodTrending) else Average(source, LookbackPeriodRanging);
def mean = if smoothing then ExpAverage(preMean, smoothingLength) else preMean;
def deviation = if isTrending then StDev(source, LookbackPeriodTrending) else StDev(source, LookbackPeriodRanging);
def upperBand = mean + (deviation * thresholdLevel);
def lowerBand = mean - (deviation * thresholdLevel);
#// Real-Time Parameter Adjustment
def adaptiveMean = if isTrending then mean else Average(source, 3);
def adaptiveUpperBand = if isTrending then upperBand else mean + (deviation * thresholdLevel * 0.75);
def adaptiveLowerBand = if isTrending then lowerBand else mean - (deviation * thresholdLevel * 0.75);
#// Plotting
plot AdptMean = adaptiveMean; # "Adaptive Mean"
plot AdptUpperBand = adaptiveUpperBand; # "Adaptive Upper Band"
plot AdptLowerBand = adaptiveLowerBand; # "Adaptive Lower Band"
AdptMean.SetDefaultColor(Color.WHITE);
AdptUpperBand.SetDefaultColor(Color.GREEN);
AdptLowerBand.SetDefaultColor(Color.RED);
AdptMean.SetLineWeight(2);
#// Signal Generation
def isAboveUpperBand = source > adaptiveUpperBand;
def isBelowLowerBand = source < adaptiveLowerBand;
def signal = if isAboveUpperBand then -1 else if isBelowLowerBand then 1 else 0;
#// RSI Calculation
def nRSI = RSI(PRICE = source, LENGTH = rsiLength);
#// Confluence Condition
def confluenceCondition = nRSI > 70 or nRSI < 30;
#// Background Color
AddCloud(adaptiveUpperBand, adaptiveLowerBand, Color.DARK_GRAY);
AddCloud(if signal == -1 and confluenceCondition then pos else na, neg, Color.DARK_GREEN);
AddCloud(if signal == 1 and confluenceCondition then pos else na, neg, Color.DARK_RED);
AssignPriceColor(if !ColorBars then Color.CURRENT else
if signal == -1 and confluenceCondition then Color.GREEN else
if signal == -1 then Color.DARK_GREEN else
if signal == 1 and confluenceCondition then Color.RED else
if signal == 1 then Color.DARK_RED else Color.GRAY);
#-- END of CODE