A trade is not always one entry and one exit
Pine strategy reports depend on entries, orders, pyramiding, reversals, and the way the script defines a position.
Traders talk about a trade as if it is obvious. “I took one trade.” In a Pine strategy, that sentence can hide several implementation choices. Was there one entry order or several? Was the position scaled? Did an opposite signal close the trade or reverse it? Was pyramiding enabled? Did partial exits split the position?
The reason this matters in real scripts is that strategy reports often look wrong when the real issue is that the script and the user define “trade” differently.
Why this catches people
The trap is making the visual marker the definition. One arrow on the chart feels like one trade. The strategy engine may see multiple orders, reserved exits, a reversal, or a pyramided position. The report is then accounting for the script’s orders, not the user’s simplified chart story.
This becomes important when users compare win rate, average trade, and drawdown. Changing the trade definition can change those numbers without changing the basic market idea.
The Pine bit
I like to define position lifecycle explicitly. Entry, add, reduce, exit, reverse, and flat are separate states. If the script allows scaling, the chart should show that state. If it does not allow scaling, the code should prevent accidental multiple entries.
The strategy.position_size, entry IDs, and pyramiding setting are not just implementation details. They are the strategy’s trade grammar.
isFlat = strategy.position_size == 0
isLong = strategy.position_size > 0
if isFlat and longSignal
strategy.entry("L", strategy.long)
How I handle it in builds
For client tools, I ask the plain question: when you say one trade, what counts? A full round trip? Each scale-out? A reversal? The answer decides how the strategy should be coded and how any custom performance display should be interpreted.
I avoid changing pyramiding or reversal behaviour casually during optimization. Those settings can make performance look different while the entry signal remains almost unchanged.
Where this shows up
A practical way to settle the definition is to draw position state rather than only entries. Full position, added position, reduced position, runner, and flat can each have a small marker or table value. Once the state is visible, the Strategy Tester table becomes less surprising because the chart is no longer pretending that every arrow is a full trade.
This also helps when converting an indicator into a strategy. An indicator signal may be a setup. A strategy trade requires rules for what happens if a setup appears while already long, while already short, or while partially exited. Those cases are the trade definition. Ignoring them does not make them disappear; it just lets Pine’s defaults make decisions the user may not have intended.
I decide whether the strategy is allowed to be flat by rule or only by exit. For example, if a long signal disappears, should the position close, or should it remain until a stop or opposite signal? That single choice changes trade duration, alert behaviour, and performance. It should not be left implicit.
Once the lifecycle is clear, the script can produce better labels too. Instead of marking every event as “Long” or “Short,” it can mark “Add,” “Reduce,” “Reverse,” or “Exit.” That makes the chart match the trade accounting.
How I test it
I test strategy behaviour by separating signal, order, fill, and report. A marker proves the signal condition. An order ID proves the strategy instruction. A fill proves the emulator accepted a path. A report proves only the model’s accounting. Those are related, but they are not interchangeable.
The final test is whether the user can explain the lifecycle without reading code. If they cannot, the script probably needs clearer states or simpler rules.
Checks before I trust it
- Define whether scaling is allowed.
- Use entry IDs consistently.
- Decide whether opposite signals close, reverse, or wait.
- Show position state when users read the chart manually.
- Compare performance only after the trade definition is stable.
The thing worth preserving is that “one trade” is a design choice. Pine will account for what the code says, not what the chart marker seems to imply.