This strategy identifies an equilibrium zone using a rolling average price range and looks for rejection when price moves into that zone but fails to hold inside it.
The idea is simple:
Markets often rotate around fair value
If price enters value and quickly rejects, it can signal directional intent
The strategy trades the move away from that rejected value area
How It Works
1. Build the Value Area
A rolling average price forms the center of value.
An ATR-based band creates:
- Upper Value Boundary
- Lower Value Boundary
2. Detect Rejection
A trade is considered when:
Bullish Rejection
- Price dips into/below lower value area
- Closes back above the lower boundary
Bearish Rejection
- Price moves into/above upper value area
- Closes back below the upper boundary
3. Risk Management
ATR-based stop-loss and take-profit:
- Adaptive to market volatility
- Fixed risk-to-reward structure
Logic Summary
- A rolling SMA acts as the value midpoint
- ATR bands create upper/lower value boundaries
- Long entries occur when price rejects below value and closes back inside
- Short entries occur when price rejects above value and closes back inside
Risk Handling
ATR-based stop-loss adapts to volatility
Fixed risk/reward target keeps trade structure consistent
Best Use Cases
Rotational markets
Pullback environments
Value-to-imbalance transitions
Notes
This is a simplified value-area model intended for testing and educational use. It approximates equilibrium behavior and is not a replacement for full market profile or exchange volume profile tools.
Pine Script v6 Code
//@version=6
strategy("Value Area Rejection Strategy", overlay=true, initial_capital=100000, default_qty_type=strategy.percent_of_equity, default_qty_value=5)
// ───── INPUTS ─────
valueLen = input.int(50, "Value Area Length")
atrLen = input.int(14, "ATR Length")
bandMult = input.float(1.0, "Value Area Width ATR")
stopMult = input.float(1.5, "Stop ATR Multiplier")
rr = input.float(2.0, "Risk Reward")
// ───── VALUE AREA CALCULATION ─────
basis = ta.sma(close, valueLen)
atrVal = ta.atr(atrLen)
upperVA = basis + atrVal * bandMult
lowerVA = basis - atrVal * bandMult
// ───── REJECTION LOGIC ─────
bullReject = low < lowerVA and close > lowerVA
bearReject = high > upperVA and close < upperVA
// ───── ENTRIES ─────
if bullReject and strategy.position_size == 0
strategy.entry("Long", strategy.long)
if bearReject and strategy.position_size == 0
strategy.entry("Short", strategy.short)
// ───── EXITS ─────
longStop = strategy.position_avg_price - atrVal * stopMult
longTarget = strategy.position_avg_price + atrVal * stopMult * rr
shortStop = strategy.position_avg_price + atrVal * stopMult
shortTarget = strategy.position_avg_price - atrVal * stopMult * rr
strategy.exit("Exit Long", from_entry="Long", stop=longStop, limit=longTarget)
strategy.exit("Exit Short", from_entry="Short", stop=shortStop, limit=shortTarget)
// ───── VISUALS ─────
plot(basis, title="Value Area Mid", color=color.orange)
plot(upperVA, title="Upper Value Area", color=color.red)
plot(lowerVA, title="Lower Value Area", color=color.green)
Top comments (0)