Outcome Tracking

After a signal is approved and stored, outcome tracking revisits it against future candles to record whether price reached take profit, stop loss, or expired without resolution.

Outcome tracking runs separately from the scan pipeline described in Signal Workflow. Only signals that passed risk approval are candidates. Rejected signals are not tracked.

Runs on a scheduleWatch mode updates outcomes on a timer; you can also trigger updates manually.
Bar-by-bar resolutionEach candle after the signal is checked using high and low prices.
Four final statesPending, take profit, stop loss, or expired after the bar limit.

Trigger outcome updates manually or let watch mode run them on a timer:

python -m src.main outcomes update --limit 50

Related settings are documented under Outcome Tracking in configuration (OUTCOME_MAX_BARS, OUTCOME_FETCH_LIMIT, and OUTCOME_UPDATE_INTERVAL_SECONDS for watch mode).

Resolution Logic

For each approved signal, the tracker loads candles that formed after the signal timestamp and walks forward up to OUTCOME_MAX_BARS bars (default 100).

  • Long — stop loss triggers if low ≤ stop; take profit triggers if high ≥ target. Stop is checked before target on each bar.
  • Short — stop loss triggers if high ≥ stop; take profit triggers if low ≤ target. Stop is checked before target on each bar.
  • If neither level is hit within the bar limit, the signal expired at the last bar's close price.
  • If fewer than OUTCOME_MAX_BARS candles exist after the signal and neither level was hit, the outcome stays pending.

This is a simplified backtest-style resolution — it assumes stop and target fills at the exact configured prices when a candle's range touches those levels. It does not model slippage, partial fills, or order-book behavior.

Outcome Fields

When an outcome resolves or is updated, these values are stored alongside the original signal record.

FieldDescription
statusCurrent resolution state: pending, take_profit, stop_loss, or expired.
exit_pricePrice used to close the outcome — stop, target, or last close when expired.
realized_return_pctPercentage return from entry to exit_price, signed for long or short direction.
bars_to_resolutionHow many candles after the signal timestamp were evaluated before resolution.
resolved_atTimestamp of the candle bar where the outcome was determined.

Outcome Statuses

  • pending — Not resolved yet; fewer than OUTCOME_MAX_BARS candles have passed or price has not hit stop or target.
  • take_profit — Price reached the take-profit level before the stop within the bar window.
  • stop_loss — Price reached the stop-loss level before the target within the bar window.
  • expired — Neither level was hit within OUTCOME_MAX_BARS; closed at the last candle's close for return calculation.