Skip to content
ChartTailor
WorkServicesPricingField NotesAbout Start a build
← Pine Discoveries

Partial exits change the meaning of a trade report

Scaling out in Pine strategies is useful, but the performance table needs to be read with order reservations and trade definitions in mind.

Partial exits make a strategy feel more realistic because many traders do not close everything at once. They scale out, move stops, trail a remainder, or take profit at several targets. Pine can model a lot of that, but the trade report becomes harder to read. One idea may produce several orders, several fills, and performance numbers that do not match the user’s mental model of “one trade.”

This is worth writing down because partial exits are a common source of confusion in client scripts. The chart labels may look right while the Strategy Tester table feels wrong, or the table looks right while the order logic is quietly reserving quantity in a way the user did not expect.

Why this catches people

The tempting shortcut is thinking of strategy.exit() calls as independent instructions that can all freely close the same position. In practice, exit orders are attached to entries, quantities matter, and one exit can reserve part of a position. If the code asks several exits to manage the same size without understanding those reservations, later exits may have less quantity available than expected.

The second mistake is comparing a scaled trade to a single-entry single-exit report. A partial take-profit can improve win rate, reduce average trade size, change drawdown, and alter the distribution of closed trades. The table is not wrong just because it no longer matches the simple story.

The Pine bit

I prefer to name exits by their role: TP1, TP2, Runner, Stop, TimeExit. The IDs should make the trade plan visible. I calculate quantities deliberately instead of leaving the script to imply the plan. If the user wants 50 percent off at target one and the rest trailed, that should be visible in the code and on the chart.

It is also useful to separate signal performance from execution-plan performance. A good signal with a poor scale-out plan can look mediocre. A mediocre signal with aggressive partial exits can look smoother than it really is.

strategy.exit("TP1", "L", qty_percent = 50, limit = tp1, stop = stopPrice)
strategy.exit("Runner", "L", qty_percent = 50, stop = trailStop)

How I handle it in builds

For reporting, I like to add simple chart annotations or a small table that shows the intended position state. The Strategy Tester has its own terminology, but a user often needs to know something plainer: full size, half size, runner only, flat. If the script exposes that state, the report becomes easier to interpret.

I test exits in isolation. First the stop. Then target one. Then the runner. Then all of them together. Partial-exit bugs are easier to catch before every order is active at once.

Where this shows up

The cleanest partial-exit scripts also expose the remaining position. After target one fills, the user should be able to see that the script is managing a runner, not a full original position. If the chart still paints the trade as fully active, the visuals and the accounting disagree.

I watch for accidental overfitting through scale-out design. A strategy can be made to look smoother by taking tiny early profits and leaving a small runner. That may or may not be a good trade plan. The table alone cannot decide. The exits should match the user’s actual execution intent, not just the combination that makes the historical curve prettiest.

Implementation-wise, I prefer to write exits so each one has a single job. One exit should not be both a partial target and an emergency stop unless the relationship is intentional and easy to inspect. Separate order IDs make the chart, the report, and the alert messages easier to connect.

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.

Checks before I trust it

  • Name exit IDs by their trade-plan role.
  • Set quantities or percentages deliberately.
  • Check whether earlier exits reserve quantity needed by later exits.
  • Separate signal quality from scale-out plan quality.
  • Add plain position-state visuals when users will read the chart manually.

The useful rule is that partial exits are not just smaller exits. They change the accounting story. The script needs to make that story visible before the performance table can be trusted.