Prop Trading API¶
The Prop Trading manager API is used by BackOffice to configure prop challenge products.
This API belongs to the TCP manager layer. Client-facing challenge browsing and purchase endpoints are documented in the HTTP Client API section.
Lifecycle¶
Current implementation covers the configuration layer and the client purchase activation flow:
- BackOffice creates a program aggregate with settings and steps.
- BackOffice opens the full program card with
MngGetPropProgram. - BackOffice updates settings and steps with one
MngUpdatePropProgramrequest. - BackOffice can activate/disable a program through
MngUpdatePropProgram.status. - BackOffice can delete a program and all linked prop records through
MngDeletePropProgram. - BackOffice can view current challenges through
MngGetPropChallangesByFilter. - BackOffice can open challenge runtime details through
MngGetPropChallenge,MngGetPropChallengeMetrics, andMngGetPropChallengeBreaches. - BackOffice can view and manage purchase lifecycle metadata through
MngGetPropPurchasesByFilter,MngGetPropPurchase,MngUpdatePropPurchase, andMngDeletePropPurchase. - Client requests available active programs.
- Client starts a purchase with
BuyPropChallenge. - Server creates a
prop_purchase, enqueues the payer fee withdrawal, opens the first phase account insteps[0].account_group, enqueues the initial balance from that group'sGroupRecord.default_deposit, and creates an activeprop_challenge. - Server creates an active
prop_challenge_phasesrow for the current phase. PropManagerevaluates active phases in its own loop by reading margin data in batches throughAccountManager::GetMarginsByLoginsList.
Funded support is modelled as a phase type. A program can contain at most one funded phase, and it must be the last phase. The funded phase must use a REAL trading group.
The Prop evaluator does not run inside the trading mainLoop. It checks active phase accounts from the PropManager cache, writes throttled metric snapshots, creates rule breaches, and moves a phase/challenge to failed or passed state.
Heavy side effects are executed by a separate PropManager worker queue. The evaluator only enqueues jobs. The worker can set failed accounts read-only, create the next phase account, enqueue the phase initial balance, update current_phase_index/account_login, and execute funded profit payout.
PropManager is cache-first. SQLite is used for startup load and persistence, while runtime/API read paths use in-memory indexes for purchases, challenges, challenge phases, metrics, breaches and daily snapshots. Metric snapshots and rule breaches are kept in memory newest-first and capped to the latest 1000 rows per challenge; SQLite keeps the full history.
If the passed phase is the last phase, the challenge becomes passed. If a next phase exists, the current runtime phase becomes passed and the worker creates the next phase account.
Status Values¶
Program Status¶
| Value | Name | Description |
|---|---|---|
0 |
active | Available for use |
1 |
disabled | Not available for new purchases |
2 |
archived | Hidden/legacy record |
MngUpdatePropProgram can activate a program with status = 0 or disable it with status = 1.
Purchase Status¶
| Value | Name |
|---|---|
0 |
pending |
1 |
paid |
2 |
account_created |
3 |
active |
4 |
failed |
5 |
refunded |
Challenge Status¶
| Value | Name |
|---|---|
0 |
pending |
1 |
active |
2 |
passed |
3 |
failed |
4 |
cancelled |
Challenge Phase Status¶
| Value | Name |
|---|---|
0 |
pending |
1 |
active |
2 |
passed |
3 |
failed |
4 |
cancelled |
Program Object¶
| Field | Type | Description |
|---|---|---|
id |
int | Program id |
brand |
string | Brand namespace |
name |
string | Program name shown to BackOffice/client |
description |
string | Program description |
price |
double | Challenge purchase price |
price_currency |
string | Purchase currency |
profit_split |
double | Trader profit share derived from the funded phase. 0.8 means 80%. Returns 0.0 when the program has no funded phase |
status |
int | Program status |
sort_index |
int | UI ordering value |
created_time |
int | Unix timestamp |
updated_time |
int | Unix timestamp |
Aggregate Save Model¶
MngCreatePropProgram requires a nested steps array. MngUpdatePropProgram can replace steps by sending steps. Each step contains phase settings, rule values and the phase account_group. demo_group is deprecated and is not used by new prop flows.
{
"steps": [
{
"phase_index": 1,
"phase_type": 0,
"name": "Evaluation",
"account_group": "PROP_DEMO_USD",
"initial_balance": 100000,
"duration_days": 30,
"max_daily_loss_pct": 5,
"max_total_loss_pct": 10,
"max_daily_profit_pct": 0,
"profit_target_pct": 8,
"profit_split": 0,
"min_trading_days": 5,
"max_trading_days": 30,
"max_positions": 10
},
{
"phase_index": 2,
"phase_type": 1,
"name": "Funded",
"account_group": "PROP_REAL_USD",
"initial_balance": 100000,
"duration_days": 30,
"max_daily_loss_pct": 5,
"max_total_loss_pct": 10,
"max_daily_profit_pct": 5,
"profit_target_pct": 0,
"profit_split": 0.8,
"min_trading_days": 0,
"max_trading_days": 30,
"max_positions": 10
}
]
}
On update, if steps is sent, the server replaces nested program steps as one aggregate.
Delete Flow¶
MngDeletePropProgram removes the program and all linked prop-domain records:
- program steps/phases
- purchases
- challenges
- challenge phase runtime rows
- daily snapshots
- rule breaches
- metric snapshots
- the program row
The delete operation is transactional and writes the deleted counters to the server log.
Phase Object¶
| Field | Type | Description |
|---|---|---|
id |
int | Phase id |
program_id |
int | Parent program id |
phase_index |
int | Phase order starting from 1 |
phase_type |
int | 0 evaluation, 1 funded |
name |
string | Phase name |
account_group |
string | Trading group used for the phase account. Funded phases must use a REAL group |
initial_balance |
double | Computed from account_group -> GroupRecord.default_deposit |
duration_days |
int | Phase duration, 0 means not configured |
max_daily_loss_pct |
double | Maximum daily loss percent |
max_total_loss_pct |
double | Maximum total loss percent |
max_daily_profit_pct |
double | Maximum daily profit percent, mostly used for funded phases |
profit_target_pct |
double | Profit target percent |
profit_split |
double | Trader profit share for funded phase. 0.8 means 80%. Must be 0 for non-funded phases |
min_trading_days |
int | Minimum trading days |
max_trading_days |
int | Maximum trading days, 0 means not configured |
max_positions |
int | Maximum open positions, 0 means not configured |
created_time |
int | Unix timestamp |
updated_time |
int | Unix timestamp |
Funded Phase Rules¶
phase_type = 1marks a funded phase.- A program can have only one funded phase.
- The funded phase must be the last phase by
phase_index. - The funded phase
account_groupmust point to a REAL group. - Non-funded phases must use DEMO groups in the current implementation.
profit_splitis stored on the funded phase and exposed on the program object as a computed field.
Runtime Evaluation¶
When a challenge is activated, the server creates a runtime phase row with the starting balance/equity snapshot.
The evaluator currently checks:
max_total_loss_pctmax_daily_loss_pctmax_daily_profit_pctduration_daysprofit_target_pctmin_trading_daysmax_trading_daysmax_positions
Metrics are written to prop_metric_snapshots at most once per minute per challenge, and immediately on pass/fail events. Rule violations are written to prop_rule_breaches.
On breach the worker sets the failed phase account to read-only and emits prop.challenge.failed. On phase advance it emits prop.challenge.phase_changed. On final pass it emits prop.challenge.passed.
Daily loss/profit use prop_daily_snapshots.daily_start_equity as the daily boundary basis. The first evaluator pass in a local calendar day creates the daily snapshot, then updates current balance/equity and min/max equity.
Current limitation: trading days are counted from daily snapshots, not strictly from trade activity.
Runtime Detail Commands¶
MngGetPropChallengereturns challenge, purchase, program, runtime phases, current phase, latest metric and latest breach. Each phase includeslatest_metricand calculatedprogress.MngGetPropChallengeMetricsreturnsprop_metric_snapshotsrows, newest first.MngGetPropChallengeBreachesreturnsprop_rule_breachesrows, newest first.
Purchase Commands¶
MngGetPropPurchasesByFilterreturns purchases in the BackOffice table format.MngGetPropPurchasereturns one purchase card with linked program and challenges.MngUpdatePropPurchaseupdates only lifecycle/meta fields.MngDeletePropPurchasedeletes an unlinked purchase, or a linked purchase only when it is alreadyfailedorrefunded.