Skip to content

feat(AccountInfoDisplay): add per-trade max open PnL rows - #176

Open
AlbertoAmadorBelchistim wants to merge 2 commits into
AtasPlatform:Developfrom
AlbertoAmadorBelchistim:feat/accountinfo-max-open-pnl
Open

AlbertoAmadorBelchistim wants to merge 2 commits into
AtasPlatform:Developfrom
AlbertoAmadorBelchistim:feat/accountinfo-max-open-pnl

Conversation

@AlbertoAmadorBelchistim

Copy link
Copy Markdown
Contributor

Summary

Adds two optional rows to the account info panel, both disabled by default so existing setups are unaffected:

  • Max open PnL — the highest open PnL reached during the current trade, shown while a position is open on the selected account/instrument.
  • Last trade max PnL — the same value for the last closed trade, kept visible while flat.

This makes it easy to see how much unrealized profit a trade reached before it was closed (maximum favorable excursion), directly on the panel traders already use to monitor PnL.

Implementation notes

  • Runtime-only tracking, no persistence: a small state machine follows flat → open → flat transitions of TradingManager.Position (matching account and instrument), seeds the baseline with the portfolio open PnL at entry, and updates the maximum on each render.
  • State resets whenever the selected portfolio changes.
  • Tracking only runs when at least one of the two toggles is enabled; with both off there is zero additional work per render.
  • The diff is additive-only (55 lines) on top of current Develop; no existing behavior is modified.

Localization

The two toggle names and row labels are declared inline, consistent with the existing row labels in this file ("Open PnL", "Balance", …). No matching keys exist in OFT.Localization yet, so they follow the same transitional pattern as the recently merged Half Gap settings in DailyLines, ready to be swapped once keys are added:

Text Where
Show max open PnL / Show the maximum open PnL reached during the current trade. toggle name / description
Show last trade max open PnL / Keep the maximum open PnL of the last closed trade visible while flat. toggle name / description
Max open PnL, Last trade max PnL row labels

Testing

Built against Alpha configuration with 0 errors. Smoke-tested on chart: row appears on position open and only increases; on close the value moves to "Last trade max PnL" and persists while flat; switching accounts clears the state; both toggles off reproduces the previous panel exactly.

@Stig4all

Stig4all commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

The tracked value does not currently match the advertised per-trade metric.
Position detection is scoped to the selected account and instrument, but the maximum is calculated from portfolio.OpenPnL, which includes other positions on that account. Their PnL can therefore change the reported maximum for this trade.
Tracking only inside OnRender can also miss PnL peaks and position transitions between frames. A direct position reversal is not recognized as a new trade by the current state machine.
Please use position-specific PnL and track updates independently of rendering, with explicit handling of trade boundaries and reversals. These issues need to be resolved before exposing the value as a per-trade maximum.

Adds two optional rows to the account info panel, both disabled by
default so existing setups are unaffected:

- Max open PnL: highest open PnL reached during the current trade,
  shown while a position is open on the selected account/instrument.
- Last trade max PnL: the same value for the last closed trade, kept
  visible while flat.

Useful to review how much unrealized profit a trade reached before it
was closed (maximum favorable excursion).

Tracking is runtime-only (no persistence): the state machine follows
flat -> open -> flat transitions of TradingManager.Position, seeds the
baseline with the portfolio open PnL at entry, and resets whenever the
selected portfolio changes.

The two toggle names and row labels are declared inline like the
existing row labels in this file; no localization keys exist for them
yet, so they follow the same transitional pattern as the Half Gap
settings in DailyLines.
… of rendering

The maximum was taken from Portfolio.OpenPnL, which also contains the PnL of
other positions on the same account, and it was only sampled in OnRender, so
peaks and position transitions between two frames were missed. A direct
reversal was not recognized as a new trade.

The value now comes from the chart position's own UnrealizedPnL. It is updated
from OnPositionChanged and from the position's PropertyChanged notifications
(raised on every PnL recalculation), not from rendering. The trade state follows
the sign of the position volume: opening starts a trade, closing ends it, and a
change of sign ends the current trade and starts a new one. Tracking is reset
when the portfolio or the security changes.
@AlbertoAmadorBelchistim

Copy link
Copy Markdown
Contributor Author

Thanks, reworked:

  • The value now comes from the chart position's own UnrealizedPnL (the position matched by account and security), not from Portfolio.OpenPnL.
  • Tracking no longer happens in OnRender. It is driven by OnPositionChanged and by the position's PropertyChanged notifications, which are raised on every PnL recalculation, so peaks between frames are captured.
  • Trade boundaries follow the sign of the position volume: opening starts a trade, closing ends it, and a sign change (direct reversal) ends the current trade and starts a new one from the new position's PnL. Scaling in or partially closing stays within the same trade. Tracking is reset when the portfolio or the security changes.
  • The state is shared between the trading thread and rendering under a lock.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants