How to limit a number to a range of values in Pine Script?
How to limit a number to a range of values in Pine Script?
Section titled “How to limit a number to a range of values in Pine Script?”TL;DR
Usemath.clamp(value, min, max)(or pairmath.max/math.min) to enforce lower and upper bounds on any series so calculated values stay inside the range you set.
At a Glance
Section titled “At a Glance”| Difficulty | Beginner |
| Time to implement | 10-15 min |
| Category | Inputs |
Quick Actions
Section titled “Quick Actions”Quick Start
Section titled “Quick Start”//@version=5indicator("Clamp demo", overlay=false)
value = close - close[1]clamped = math.clamp(value, -1.5, 1.5)
plot(clamped, "Change clamped to ±1.5")Why It Matters
Section titled “Why It Matters”Indicators and strategies frequently calculate metrics that spike outside realistic bounds (ATR-derived position sizes, momentum readings, user inputs). Clamping keeps your logic stable: you avoid oversized orders, sanitize noisy signals, and guarantee downstream formulas receive valid ranges.
What You’ll Learn
Section titled “What You’ll Learn”- Apply lower-only, upper-only, or fully clamped ranges around any numeric series.
- Package clamps in helpers (
limitMin,limitMax,limitRange) for reuse. - Combine clamped values with plots, alerts, or order sizing.
- Inspect the before/after impact directly on chart.
Quick Reference
Section titled “Quick Reference”| Call | Purpose |
|---|---|
math.max(a, b) | Enforces a minimum by returning the larger of two values. |
math.min(a, b) | Enforces a maximum by returning the smaller of two values. |
math.clamp(value, min, max) | One-call clamp between lower and upper bounds. |
input.float(...) | Collects user-configurable limits. |
plot(series, ...) | Visualises clamped vs unclamped data. |
Implementation Blueprint
Section titled “Implementation Blueprint”-
Decide the limits
Hard-code them, retrieve them from inputs, or compute them from another indicator.minPct = input.float(-2.0, "Minimum % move", step=0.1)maxPct = input.float(2.0, "Maximum % move", step=0.1) -
Clamp the value
Use helpers for readability, especially when you reuse the logic across the script.limitMin(float value, float minVal) => math.max(value, minVal)limitMax(float value, float maxVal) => math.min(value, maxVal)limitRange(float value, float minVal, float maxVal) => math.clamp(value, minVal, maxVal) -
Apply the bounded result
Feed the clamped number into plots, calculations, or order sizing routines.rawChange = 100 * (close / close[1] - 1)boundedChange = limitRange(rawChange, minPct, maxPct)plot(boundedChange, "Bounded % change")
Example Playbook
Section titled “Example Playbook”//@version=5indicator("ATR-based sizing with clamps", overlay=false)
eosPct = input.float(1.5, "Equity at stake (%)", minval=0.1, step=0.1)minQty = input.float(0.2, "Minimum qty", minval=0.01, step=0.01)maxQty = input.float(5.0, "Maximum qty", minval=0.1, step=0.1)atrLen = input.int(14, "ATR length", minval=1)atrMult = input.float(1.2, "ATR multiplier", step=0.1)
atrValue = ta.atr(atrLen)positionRisk = atrValue * atrMultrawQty = strategy.equity * (eosPct * 0.01) / positionRisk
limitMin(float value, float minVal) => math.max(value, minVal)limitMax(float value, float maxVal) => math.min(value, maxVal)limitRange(float value, float minVal, float maxVal) => math.clamp(value, minVal, maxVal)
qtyBounded = limitRange(rawQty, minQty, maxQty)qtyCeiling = limitMax(rawQty, maxQty)qtyFloor = limitMin(rawQty, minQty)
plot(rawQty, "Raw quantity", color=color.new(color.orange, 0))plot(qtyBounded, "Clamped quantity", color=color.new(color.teal, 0), linewidth=2)plot(qtyCeiling, "Only max applied", color=color.new(color.red, 40))plot(qtyFloor, "Only min applied", color=color.new(color.blue, 40))- The helper functions make intent obvious: floor, ceiling, or full clamp.
- Plots contrast the raw quantity against each bounded version, making the clamp effect transparent.
- User inputs control bounds so traders can tighten risk without editing code.
Pro Tips & Pitfalls
Section titled “Pro Tips & Pitfalls”- Clamp before passing values into order functions (
strategy.entry,strategy.exit) to avoid rejections from brokers specifying min/max contract sizes. - Consider dynamic bounds (e.g., ATR percentile) instead of static numbers when markets evolve.
- Remember that
math.clampworks with series values; you can clamp per bar using prior calculations. - When only one side matters,
limitMinorlimitMaxkeeps logic lighter than a full clamp.
Troubleshooting & FAQ
Section titled “Troubleshooting & FAQ”Why do I still see values outside the range?
Section titled “Why do I still see values outside the range?”Check whether you use the clamped result everywhere. It’s easy to continue plotting or executing trades with the unclamped variable.
Can I clamp integers the same way?
Section titled “Can I clamp integers the same way?”Yes. Pine casts integers to float automatically inside math.* functions, but you can wrap the output with int() if you need an integer result afterwards.
How do I clamp conditionally?
Section titled “How do I clamp conditionally?”Wrap the clamp inside an if statement: only apply it when volatility spikes, or when user inputs signal strict mode.
Key Takeaways
Section titled “Key Takeaways”math.clamp(or pairedmath.max/math.min) keeps any number inside a desired range.- Helpers like
limitRangemake multiple clamps reusable and self-documenting. - Visualising the bounded and raw values helps confirm the limits behave as intended.
- Tight control over value ranges prevents runaway order sizes and keeps indicators robust.
Keep Going
Section titled “Keep Going”- Open AI Editor to apply the pattern with guided assistance
- Browse Strategy Examples for ready-to-run templates
- Connect to Live Trading when you are ready to automate
Adapted from tradingcode.net, optimised for Algo Trade Analytics users.