How to make a tick-based input option in Pine Script?
How to make a tick-based input option in Pine Script?
Section titled “How to make a tick-based input option in Pine Script?”TL;DR
Take a tick count frominput.int, convert it to price by multiplying withsyminfo.mintick, and feed the result anywhere you need a distance that respects the chart’s tick size.
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("Tick input demo", overlay=true)
ticks = input.int(8, "Offset (ticks)", minval=0)priceStep = syminfo.mintickoffset = ticks * priceStep
plot(close + offset, "Offset up")plot(close - offset, "Offset down")Why It Matters
Section titled “Why It Matters”Traders think in ticks; code runs in raw price units. Translating tick distances inside Pine keeps strategies portable across instruments—no more editing scripts when moving from ES to NQ or to a micro contract. Inputs let users control risk without touching code.
What You’ll Learn
Section titled “What You’ll Learn”- Gather tick distances with integer inputs and helpful tooltips.
- Convert ticks to price offsets that respect the instrument’s minimum tick.
- Apply the translated distance to bands, stops, and labels.
- Provide optional multipliers for scaling tick values dynamically.
Quick Reference
Section titled “Quick Reference”| Call | Purpose |
|---|---|
input.int(defval, title, minval, step) | Collects the tick count from the user. |
syminfo.mintick | Returns the instrument’s minimum tick size. |
math.max(a, b) | Guards against zero or negative tick inputs. |
| `strategy.exit(…, stop | limit)` |
plot(series, title) | Visualises bands or markers built from tick offsets. |
Implementation Blueprint
Section titled “Implementation Blueprint”-
Create the tick input
Keep the UI clear by naming the unit and enforcing sensible bounds.tickGroup = "Order distances"stopTicks = input.int(12, "Stop (ticks)", minval=1, group=tickGroup)targetTicks = input.int(18, "Target (ticks)", minval=1, group=tickGroup) -
Convert ticks to price
Multiply bysyminfo.mintickonce per bar (or cache inside a function) for reuse.toPrice(int ticks) => ticks * syminfo.mintickstopOffset = toPrice(stopTicks)targetOffset = toPrice(targetTicks) -
Use the price offsets
Apply them to plots, strategy exits, or annotation labels.if strategy.position_size > 0strategy.exit("Long OCO", from_entry="Long", stop=strategy.position_avg_price - stopOffset, limit=strategy.position_avg_price + targetOffset)
Example Playbook
Section titled “Example Playbook”//@version=5strategy("Tick-aware breakout", overlay=true, initial_capital=50_000)
length = input.int(30, "Breakout lookback", minval=2)entryBuffer = input.int(2, "Entry buffer (ticks)", minval=0)stopTicks = input.int(10, "Stop distance (ticks)", minval=1)targetTicks = input.int(16, "Target distance (ticks)", minval=1)
float toPrice(int t) => t * syminfo.mintick
highestHigh = ta.highest(high, length)lowestLow = ta.lowest(low, length)
entryOffset = toPrice(entryBuffer)stopOffset = toPrice(stopTicks)limitOffset = toPrice(targetTicks)
longTrigger = ta.crossover(high, highestHigh + entryOffset)shortTrigger = ta.crossunder(low, lowestLow - entryOffset)
if longTrigger strategy.entry("Long", strategy.long) strategy.exit("Long OCO", from_entry="Long", stop=strategy.position_avg_price - stopOffset, limit=strategy.position_avg_price + limitOffset)
if shortTrigger strategy.entry("Short", strategy.short) strategy.exit("Short OCO", from_entry="Short", stop=strategy.position_avg_price + stopOffset, limit=strategy.position_avg_price - limitOffset)
plot(highestHigh, "Breakout high", color=color.new(color.green, 60))plot(lowestLow, "Breakout low", color=color.new(color.red, 60))- Users choose distances in ticks—the script adapts them to whichever instrument it runs on.
- One conversion function supplies both stops and targets, keeping calculations consistent.
- Offsets make breakout levels realistic by accounting for slippage or buffer ticks.
Pro Tips & Pitfalls
Section titled “Pro Tips & Pitfalls”- For instruments quoted in points (e-mini futures), remind users in tooltips that 4 ticks = 1 point.
- Inverse instruments (e.g., bonds) still obey
syminfo.mintick; no special handling needed. - Allow fractional steps (
step=0.5) if a market supports half-tick increments. - When pyramiding, compute offsets per fill using
strategy.position_avg_priceto maintain consistency.
Troubleshooting & FAQ
Section titled “Troubleshooting & FAQ”The tick input seems to do nothing on stocks
Section titled “The tick input seems to do nothing on stocks”Stocks have a penny tick size (0.01). If you expected larger moves, increase the tick input or expose a multiplier.
Why are my stop prices invalid on crypto?
Section titled “Why are my stop prices invalid on crypto?”Some exchanges use very small tick sizes. Clamp the minimum ticks to ensure the resulting price offset exceeds exchange-imposed limits.
Can I reuse this for indicator-based alerts?
Section titled “Can I reuse this for indicator-based alerts?”Absolutely—calculate the price offset once, then feed it into plot, hline, or alertcondition to highlight tick-based thresholds.
Key Takeaways
Section titled “Key Takeaways”- Gather tick distances via inputs and convert them with
syminfo.mintickfor chart-agnostic behaviour. - Encapsulate the conversion in a helper to reuse across stops, targets, and overlays.
- Ensure tooltips and bounds communicate the unit clearly to end users.
- Tick-based inputs keep strategies portable without hard-coded price constants.
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.