A fixed-range grid strategy in TradingView
A grid places orders at several price levels inside a chosen range. This tutorial builds a long-only arithmetic example: buy below the current price, then offer each filled leg one step higher. Repeated small exits can coexist with a large losing open position. The code is a backtest example, not an exchange bot or evidence of positive returns.
Define the inventory and exit rules first
For N interior buy levels, this example uses spacing = (upper − lower) / (N + 1). Buy level i is lower + i × spacing, for i = 1…N; its target is the next level. Prices are rounded to the chart’s minimum tick. The lower boundary is the common stop.
For example, lower 100, upper 140 and N = 3 give buys at 110, 120 and 130, with targets 120, 130 and 140. A buy is submitted only when it is below the current close. That matters: a limit buy above the market is marketable, not a resting order waiting for price to fall.
The grid adds inventory as price falls. Its capital check compares nominal level budgets with initial capital; it does not reserve cash for fees or guarantee sufficient equity after losses. Stops may fill beyond their price during gaps.
Order timing, pyramiding, currency conversion and broker-emulator limits are described in TradingView’s strategy documentation.
v6 Implementation
//@version=6
strategy("Pineify Fixed-Range Long Grid Example", overlay=true, initial_capital=10000, currency=currency.USD, pyramiding=20, close_entries_rule="ANY", commission_type=strategy.commission.percent, commission_value=0.1, slippage=1, margin_long=100)
lowerInput = input.float(40000, "Lower boundary", minval=0.000001)
upperInput = input.float(60000, "Upper boundary", minval=0.000001)
gridCount = input.int(10, "Interior buy levels", minval=1, maxval=20)
cashPerGrid = input.float(500, "USD notional per level", minval=1)
lower = math.round_to_mintick(lowerInput)
upper = math.round_to_mintick(upperInput)
spacing = (upper - lower) / (gridCount + 1)
if barstate.isfirst
if lower <= 0 or upper <= lower or spacing < 2 * syminfo.mintick
runtime.error("Use positive ordered bounds with at least two ticks per step.")
if gridCount * cashPerGrid > strategy.initial_capital
runtime.error("Combined level budgets must not exceed initial capital.")
inside = close > lower and close < upper
if barstate.isconfirmed
if not inside
strategy.cancel_all()
if strategy.position_size > 0
strategy.close_all(comment="Outside range: market exit")
else
for i = 0 to gridCount - 1
level = math.round_to_mintick(lower + (i + 1) * spacing)
target = math.round_to_mintick(lower + (i + 2) * spacing)
buyId = "Grid " + str.tostring(i + 1)
bool isOpen = false
if strategy.opentrades > 0
for t = 0 to strategy.opentrades - 1
if strategy.opentrades.entry_id(t) == buyId
isOpen := true
symbolCash = strategy.convert_to_symbol(cashPerGrid)
rawQty = symbolCash / (level * syminfo.pointvalue)
qty = math.floor(rawQty / syminfo.mincontract) * syminfo.mincontract
canPlace = not isOpen and close > level and not na(qty) and qty > 0
if canPlace
strategy.entry(buyId, strategy.long, qty=qty, limit=level)
else if not isOpen
strategy.cancel(buyId)
if isOpen or canPlace
strategy.exit("Exit " + str.tostring(i + 1), from_entry=buyId, limit=target, stop=lower)
plot(lower, "Lower boundary / stop", color=color.red)
plot(upper, "Upper boundary", color=color.green)
var gridLines = array.new_line()
if barstate.islastconfirmedhistory or (barstate.isrealtime and barstate.isconfirmed)
for gridLine in gridLines
line.delete(gridLine)
array.clear(gridLines)
for i = 0 to gridCount - 1
level = math.round_to_mintick(lower + (i + 1) * spacing)
array.push(gridLines, line.new(math.max(0, bar_index - 100), level, bar_index, level, color=color.new(color.gray, 60), style=line.style_dashed))What the example actually does
- 1
Each level has its own entry ID and bracket. close_entries_rule="ANY" lets the emulator associate the exit with the named entry; up to 20 long entries are allowed. An open level cannot add another leg under that ID.
- 2
Cash per level is in the USD strategy account currency. strategy.convert_to_symbol converts it to chart currency, then level × point value converts that notional to contracts or units. Quantity rounds down to syminfo.mincontract; a budget too small for one unit produces no order.
- 3
Orders are evaluated at confirmed bar closes. Inside the range, eligible limit buys rest below the close. Outside the range, all pending orders are cancelled and remaining inventory receives a market-close instruction, normally filled on the next available tick. This is not a guaranteed boundary-price exit.
- 4
The example uses fixed bounds, not a trailing or geometric grid. Default bounds are illustrative and must be changed for the selected symbol. It does not send exchange orders or manage a live bot.
Backtest Assumptions and Metrics
No reproducible performance dataset accompanies this example. The table lists code assumptions, not measured returns. To reproduce a test, record symbol and venue, chart type, timeframe, date range, session, inputs and all Strategy Properties.
| Metric | Value | Interpretation |
|---|---|---|
| Starting capital | USD 10,000 | Strategy account setting; not a suggested deposit. |
| Level budgets | 10 × USD 500 | Nominal USD 5,000 before fees; rounded contract sizes may use less. |
| Commission | 0.1% per fill | Illustrative entry and exit charge; replace with the applicable fee model. |
| Slippage | 1 tick | Emulator setting for applicable orders; not a complete spread or limit-fill model. |
| Performance | Not established | Inspect realized profit, open inventory and drawdown together. |
Use standard-price candles. Inspect individual entry IDs, quantities and exits in the Strategy Tester, especially bars that touch several levels or cross the lower boundary. Compare the default emulator with Bar Magnifier where available. Lower-timeframe data does not establish queue priority, liquidity, funding costs or executable live fills. Fix rules before evaluating a separate period; choosing bounds from the completed test range introduces hindsight.
Review the rules and exported trades
Pineify Backtest Deep Report imports a TradingView trade-list CSV for additional trade summaries. Check that prices, quantities, currency and fees match the Strategy Tester export. Closed-trade summaries cannot reconstruct missing intrabar exposure or establish live execution quality.
The AI Coding Agent can help draft changes. Compile the resulting script and inspect its orders in TradingView before treating a change as correct.
Strategy Optimization Suggestions
Check order costs against spacing
Compare a completed leg’s gross price difference with both fees and realistic execution costs. Narrower spacing is not automatically better.
Test a range break
Include persistent declines and gaps. Record maximum open inventory and account equity, not only the proportion of profitable closed legs.
Keep the evaluation period separate
Choose bounds and level count using only information available before evaluation. Report all tried settings rather than only the best historical result.
Frequently Asked Questions
Check a specific rule change
Keep the original settings, change one rule, and compare the orders and costs on a separate test period. A code draft or trade report does not establish profitability.
Disclaimer: Trading involves significant risk. The strategies and code provided are for educational purposes only and do not constitute financial advice. Past performance is not indicative of future results.
Related Strategy Tutorials
Vibe Coding a Trading Bot
Turn a plain-language bot idea into a bounded specification, reviewed source, realistic backtest, and paper-trading plan.
Mean Reversion Strategy Tutorial
Learn how to build, backtest, and optimize a Mean Reversion Strategy on TradingView using Bollinger Bands and RSI with Pine Script v5.
VWAP Strategy Tutorial
Build a daily-anchored VWAP reversion example in Pine Script v6. Review rolling price-deviation bands, independent stop and target controls, and fill-timing limits.
Bollinger Bands Breakout Strategy Tutorial
Master the Bollinger Bands Squeeze and Breakout strategy on TradingView. Learn the Pine Script v5 code and professional analysis with Pineify.
RSI Overbought Oversold Strategy Tutorial
Compare RSI threshold entries, recovery crosses and EMA trend filters. Test a Pine Script v6 strategy with explicit stops, costs and time exits on TradingView.