How I Build a TradingView Strategy That Matches My Broker’s Constraints

Learn how I adapt a TradingView strategy to match real broker constraints using FTMO US100.cash as an example, including lot step, minimum volume, session windows, execution, and position sizing.

A strategy is not ready just because it backtests well in TradingView. This guide shows how I make a strategy more execution-aware by mirroring broker constraints such as minimum volume, lot step, session windows, and trading costs inside Pine Script.

A strategy is not ready just because it backtests well in TradingView.

That is one of the biggest gaps between research and execution. A strategy can look excellent on the chart, produce a neat equity curve, and still be poorly matched to the broker it will actually trade through. The entry logic might be fine, but the volume sizing may ignore the broker's minimum lot and volume step. The stop logic may make sense in Pine Script, but not reflect the symbol's execution reality. The backtest may assume frictionless trading, even though the live instrument uses market execution, floating spreads, commissions, and broker-specific sessions.

When I build a strategy I intend to trade through a prop-firm environment, that matters even more. A good-looking backtest is not enough. I want the TradingView model to respect the real constraints of the platform that will execute it.

For this article, I am using FTMO's US100.cash MetaTrader specification as the worked example. FTMO explicitly tells traders to check instrument specification directly in the platform, which makes this a practical exercise in making a strategy behave more like something I could actually deploy.

Why this matters more than another indicator tweak

Most traders spend too much time improving entries and not enough time improving realism.

They will test one more moving average. They will add RSI confirmation. They will try to increase the win rate by stacking filters. Meanwhile, the strategy may still be assuming things that do not line up with the broker at all.

That is the real issue. A strategy can fail live because:

MetaTrader exposes these symbol constraints directly through symbol properties such as minimum volume, maximum volume, volume step, tick size, contract size, and stop-related settings.

That is why I see this as a strategy-engineering problem, not just a signal-design problem.

The key shift is this: TradingView does not know your broker specification automatically. If you want your backtest to behave more like the live environment, you need to mirror the broker's constraints manually in Pine Script.

The first rule: TradingView does not know my broker specification

This is the most important practical point in the article.

Pine Script cannot read the FTMO MetaTrader symbol specification window. TradingView does not automatically know my broker's minimum volume, lot step, filling mode, or trading session. If I want the backtest to reflect FTMO more closely, I have to mirror those constraints manually inside the script.

That changes how I think about Pine code.

The script is no longer just describing an entry condition. It also has to encode:

That is the difference between a strategy idea and an execution-aware strategy model.

I start with volume, because that is where realism usually breaks first

For FTMO US100.cash, the specification window shows:

That means my TradingView strategy should not assume it can trade any arbitrary size. If my risk model calculates 1.734, I need to round that to the nearest valid broker increment. If my risk model calculates a size below 0.01, the strategy should reject the trade rather than pretend it is tradable.

In Pine Script, that logic looks like this:

//@version=6
minQty  = input.float(0.01, "Broker Minimum Volume", minval=0.01, step=0.01)
qtyStep = input.float(0.01, "Broker Volume Step", minval=0.01, step=0.01)
maxQty  = input.float(1000.0, "Broker Maximum Volume", minval=0.01, step=0.01)

posSizeRaw = cashRiskPerTrade / definedSL
posSizeRounded = math.floor(posSizeRaw / qtyStep) * qtyStep
posSize = math.max(minQty, math.min(posSizeRounded, maxQty))

canTradeSize = posSize >= minQty and posSize <= maxQty

That block of code is doing a lot of work.

It is saying: my strategy is not allowed to behave as though any size is tradable. It has to live inside the broker's rules.

This matters even more for prop-firm traders because fixed-risk sizing is only “fixed” up to the point where the broker's size increments allow it. If the lot step is coarse, the actual risk will drift slightly after rounding. That is not a Pine bug. That is a broker constraint.

This ties directly into Risk Management & Position Sizing and ATR Position Sizing.

Then I map the pricing mechanics

The FTMO specification also tells me the symbol is quoted to 2 digits, with contract size = 1.

This is where a lot of strategies become sloppy. Traders often assume that a point in TradingView automatically translates to the same monetary movement in the broker account. Sometimes that is close enough. Sometimes it is not.

The safest way for me to think about this in Pine is:

  1. define stop loss and take profit as price distances
  2. convert those distances to valid tick distances
  3. size the trade consistently from that same stop distance
  4. then validate the behaviour against the symbol's actual MetaTrader behaviour

For example:

//@version=6
definedSL = atrValue * slFactor
definedTP = atrValue * tpFactor

stopTicks = math.round(definedSL / syminfo.mintick)
targetTicks = math.round(definedTP / syminfo.mintick)

That does not make TradingView identical to FTMO, but it does force the strategy to respect the chart's minimum price increment more carefully.

I would also avoid treating display values like Tick size = 0.00 and Tick value = 0 as literal practical zeros. It is safer to anchor the explanation to observed symbol pricing behaviour, the 2-digit quote format, and the actual tradable outcome.

For the volatility and unit side of this discussion, ATR (Average True Range) and Risk Reward are natural follow-ons.

Broker session windows should be built into the strategy

The FTMO specification window also gives me something many traders ignore: an actual session window.

For this symbol, the visible trade session is 01:05–23:50, Monday to Friday.

That matters because a lot of TradingView strategies quietly backtest across all available bars without asking whether the symbol is actually tradable, liquid, or even open in the same way at that time.

So if I want a backtest that better resembles FTMO execution, I should build the broker session into the Pine logic:

//@version=6
brokerSession = input.session("0105-2350:12345", "Broker Session")
inBrokerSession = not na(time(timeframe.period, brokerSession))

longCondition = signalCondition and inBrokerSession and strategy.position_size == 0

The exact session string may need timezone care depending on the chart context I am using, but the principle is clear:

I do not want the strategy trading as though the broker is available all the time if the real symbol is not.

That principle aligns well with 7 Rules for Backtesting in TradingView, where the goal is to make the test environment more honest rather than simply more flattering.

Market execution changes how I interpret backtests

FTMO's US100.cash spec also shows:

That combination tells me something important immediately: I should not treat the backtest as though fills are perfect, spread is static, or cost is negligible.

That means when I review the TradingView result, I should be honest about what it is and what it is not.

It is:

It is not:

That distinction alone makes the strategy research better.

Respecting the broker does not make the backtest perfect. It makes it more honest. TradingView is still a research environment, not a full replication of live broker-side execution.

The Pine Script mindset changes once I respect the broker

Once I have all of that in view, my development process changes.

I stop asking only:

And I start asking:

That is a much better set of questions.

This is also why Strategy Order Types Explained and Higher Timeframe Confirmation fit well next to this topic.

A broker-aware Pine structure

This is the kind of structure I want inside the script when I am building with FTMO's US100.cash constraints in mind:

//@version=6
strategy("Broker-Aware US100 Strategy", overlay=true, process_orders_on_close=true)

// Broker constraints mirrored from MT5 specification
minQty  = input.float(0.01, "Broker Minimum Volume", minval=0.01, step=0.01)
qtyStep = input.float(0.01, "Broker Volume Step", minval=0.01, step=0.01)
maxQty  = input.float(1000.0, "Broker Maximum Volume", minval=0.01, step=0.01)
brokerSession = input.session("0105-2350:12345", "Broker Session")
stopsLevelPts = input.float(0.0, "Broker Stops Level", minval=0.0, step=0.01)

// Example strategy inputs
cashRiskPerTrade = input.float(100.0, "Cash Risk Per Trade", minval=1)
atrLength = input.int(14, "ATR Length", minval=1)
slFactor = input.float(0.5, "Stop ATR Factor", minval=0.1, step=0.1)
tpFactor = input.float(2.5, "Target ATR Factor", minval=0.1, step=0.1)

atrValue = ta.atr(atrLength)
inBrokerSession = not na(time(timeframe.period, brokerSession))

definedSL = atrValue * slFactor
definedTP = atrValue * tpFactor

posSizeRaw = cashRiskPerTrade / definedSL
posSizeRounded = math.floor(posSizeRaw / qtyStep) * qtyStep
posSize = math.max(minQty, math.min(posSizeRounded, maxQty))

stopTicks = math.round(definedSL / syminfo.mintick)
targetTicks = math.round(definedTP / syminfo.mintick)

stopIsValid = definedSL >= stopsLevelPts
canTrade = inBrokerSession and posSize >= minQty and stopIsValid

The important thing here is not the exact strategy logic. It is the fact that the script is now explicitly carrying broker assumptions inside it.

That is the real upgrade.

What TradingView still cannot fully replicate

Even with all of those improvements, TradingView is still not the broker.

I can mirror:

But I cannot perfectly replicate:

That does not make TradingView useless. It just means I need to keep it in the right role. It is a research and design environment, not a one-click proof that a live FTMO deployment will behave identically.

Why this matters so much for prop-firm traders

This article resonates particularly well in the FTMO context because prop-firm traders are not just trying to find profitable entries. They are trying to find robust execution under constraints.

That means the question is not simply:

“Does this strategy make money in TradingView?”

The better question is:

“Does this strategy still make sense once it is forced to obey the actual symbol, session, volume, and cost rules of the environment I want to trade in?”

That is a much harder question, but it is also the right one.

Final thoughts

The most important lesson here is that a TradingView strategy is incomplete until it is checked against the broker that will actually execute it.

For FTMO US100.cash, that means I should care about:

That is not glamorous work, but it is exactly the kind of work that makes the difference between a nice-looking backtest and a strategy I can take seriously.

If I ignore the broker, I am only testing half the system.

If I bring the broker constraints into the strategy design, the backtest stops being just a chart exercise and starts becoming something much closer to a tradable model.

One cost most traders miss: overnight swaps

Commission is visible. Swap is not.

For instruments like US100.cash, MetaTrader applies a rollover charge (swap) for every night a position is held open. Depending on direction and the broker's overnight rate, this can be a meaningful cost for strategies that hold through sessions or across days.

TradingView does not model swaps by default. If my strategy holds positions overnight on a regular basis, I should estimate the swap cost and factor it into my cost assumptions. Ignoring it produces a backtest that flatters strategies with overnight exposure.

The practical check is simple: look at the swap rate on the FTMO MT5 specification window for the instrument, calculate how often the strategy holds overnight based on bar data, and add a rough swap approximation to your commission input.

This is a small detail that separates thorough research from surface-level backtesting.

On commission types in Pine Script

Pine Script's `strategy()` function offers two commission types:

For FTMO US100.cash, the commission is listed as a percentage (0.0005% per lot). In that case, `strategy.commission.percent` is the natural mapping. But many brokers charge a fixed amount per lot or per side — for example, $5 per lot round-turn. In those cases, `strategy.commission.cash_per_contract` is more accurate.

Always check which model matches your broker. Using the wrong commission type can understate costs on small trades or overstate them on large ones, distorting the backtest P&L in subtle ways.

FTMO instrument specifications change over time. The values shown in this guide — minimum volume, volume step, session hours, commission rate — reflect a specific snapshot. Always verify the current specification directly in your MetaTrader 5 platform via View → Symbols → [instrument] → Properties before building or deploying a strategy. Relying on outdated specs is a common source of sizing and cost errors.

Partial fills and FOK/IOC: what the backtest cannot model

The FTMO US100.cash specification shows Fill or Kill (FOK) and Immediate or Cancel (IOC) as the filling modes for market execution.

In practice, this means if the full order size is not available at the requested price, the broker either rejects the order entirely (FOK) or fills as much as possible and cancels the rest (IOC). For small retail lot sizes on a liquid index, this rarely causes issues. But it is a real constraint that Pine Script cannot model — TradingView assumes every order fills completely at the expected bar-close price.

This is another reason to treat the TradingView backtest as a research model, not a live simulation. The execution assumptions are cleaner than the real broker environment in ways that matter at the margin.

Broker-constraint checklist before deploying

Before treating any strategy as ready to deploy through a broker or prop firm, I run through this checklist:

None of these items individually will transform a losing strategy into a winning one. Together, they make the difference between a backtest that is honest about what it is and one that quietly flatters itself.