Skip to content

ChallengeManager

Handles prop-firm style paper trading challenge lifecycle including start, pass/fail detection, criteria evaluation, and leaderboard integration.

Purpose

ChallengeManager owns the challenge state machine (ACTIVE -> PASSED/FAILED/INACTIVE) and evaluates the three pass criteria: profit target, consistency score, and trading days. It also coordinates with MllRiskManager for Maximum Loss Limit monitoring and with AccountValueTrackerManager for real-time account value tracking.

Pass criteria:

  • C1 - Profit Target: totalRealizedPnL >= profitTarget
  • C2 - Consistency: bestDayPnL / totalRealizedPnL <= 0.5 AND !madeNegativeMovement
  • C3 - Trading Days: completed UTC days with closed trades >= target

Failure: account value at or below capital - mllThreshold.

Challenge plans: FREE, STARTER, STANDARD, PRO -- each with different capital, targets, and MLL thresholds.

The pass validation flow is eventually consistent: when all criteria are met with open positions, a scheduled task fetches real market prices to validate account value against MLL before marking PASSED. This prevents bypassing MLL validation with stale entry prices.

Edge Cases & Error Handling

  • Pass validation with open positions is eventually consistent: prices fetched asynchronously.
  • If price fetch fails during pass validation, challenge stays ACTIVE (safety nets will catch MLL breaches).
  • Missing prices during validation: challenge stays ACTIVE rather than passing with incomplete data.
  • revertPassedToFailed handles the edge case where price volatility causes MLL breach between validation and completion.
  • Stale callbacks rejected by accountId comparison.
  • Leaderboard updates use exponential backoff retry (3 attempts: 100ms, 200ms, 400ms).
  • Trade fund application creation is fire-and-forget (non-critical).
  • madeNegativeMovement prevents consistency exploitation via negative-PnL days.
  • Contender status (within 2% of consistency target) is notification-only.

See Also