Settings and reference
Every Forex & Multi-Asset Trading setting key with its default and consequence, every environment variable, every permission key, the scheduled jobs, the database tables and the WebSocket endpoints.
Everything on this page is read from the running code. Where a value differs between the admin form and the API, both are stated.
Where settings live
The extension's settings are flat key/value rows in the core settings table,
edited at Admin → Forex Trading → Settings across five tabs.
Two encoding details that catch people out. Settings are stored as text, so
a boolean off is the string "false", not a SQL false. And list values are
accepted in two shapes — the extension's own form writes JSON arrays, the shared
core settings form writes raw comma-separated text — because both writers exist
and the reader normalises either.
Trading
Off, and: live accounts cannot be created, funded, withdrawn from or traded, and a pending order placed on a live account is refused. Demo accounts are entirely unaffected — that is the funnel and it is meant to work before you open for business.
The seed catalog flags every STOCK and INDEX instrument as delayed. While
this is off they render prices and refuse orders with "display-only". Turn it on
only if your provider plan genuinely serves real-time equity quotes;
otherwise you are filling against a 15-minute-old price, which is guaranteed
latency arbitrage against your own book.
Risk and data
Past the threshold the symbol moves to QUOTING_HALTED and every open and close
on it is refused until the feed recovers. Both accept 1 to 3600.
Raising these does not make a dead feed work — it makes you fill against older prices. If symbols halt constantly, the provider is the problem, not the threshold.
Accounts
The currency is fixed at account creation and never changes, because the deals ledger is denominated in it. The first entry in the list is what an auto-provisioned demo account gets.
Before adding a currency, check that your catalog can convert into it. Margin,
swap and realised P&L all convert through a USD hub pair, and those legs must be
listed ACTIVE and quoting — otherwise orders on affected symbols are refused
with "Currency conversion unavailable" and rollovers silently fail to settle.
Execution — A-book routing
Any attempt to write it through PUT /api/admin/forex-trading/settings returns
a 403, no matter what permissions the caller holds. It is writable only through
the core system settings page, where the protected-keys check enforces Super
Admin. It still has to be listed in the extension's key set, because the
reader has to be able to read it.
Off, every new order fills on the B-book. Turning it off never touches existing external positions — they stay hedged and keep closing at their broker until drained. See External execution.
INTERNAL or EXTERNAL. An unrecognised value degrades to INTERNAL rather
than silently routing external.
INTERNAL fills on the B-book and alerts. REJECT refuses the order
synchronously.
Compliance
The acknowledgment is stored server-side per account, so it survives a device change. The order ticket also carries a persistent risk notice while this is on.
US, CA is a deliberate compliance default and it applies whenever no
settings row is persisted — on fresh installs and on upgrades from builds that
predate enforcement alike. To block nobody you must explicitly save an empty
list. Deleting the row resurrects the default.
Enforced server-side at account creation, order placement, pending-order modification and deposits. Never enforced on closing a position, cancelling an order or withdrawing — a policy change must not trap funds.
Country resolution checks approved KYC data, the self-declared profile country
and the CDN cf-ipcountry header. A match on any signal blocks. ISO-3 codes are
normalised on both sides, so a KYC value of USA matches a list entry of US
and vice versa. A user with no resolvable country is allowed, deliberately.
For airtight blocking, also geo-block at your edge or CDN. This gate is application-level.
Environment variables
Market-data credentials — you add these by hand. They are not in
.env.example.
| Variable | Provider |
|---|---|
APP_TWELVEDATA_API_KEY |
Twelve Data |
APP_FINNHUB_API_KEY |
Finnhub |
APP_TRADERMADE_API_KEY |
TraderMade |
APP_POLYGON_API_KEY |
Polygon / Massive |
A-book execution credentials — these are pre-listed in .env.example,
blank. Leave them blank for pure B-book operation.
| Variable | Venue |
|---|---|
APP_OANDA_API_KEY |
OANDA v20 |
APP_METAAPI_TOKEN |
MetaApi (MT4/MT5) |
None of these are readable through the admin API. Endpoints report only whether the variable is present. The backend must be restarted after any change.
Permission keys
Grant under Users → Roles & Permissions. Nothing is granted by default; Super Admin bypasses the check.
| Area | Keys |
|---|---|
| Risk desk | view.forex_trading.risk |
| Accounts | view.forex_trading.account, edit.forex_trading.account, create.forex_trading.adjustment |
| Positions | view.forex_trading.position, edit.forex_trading.position |
| Orders | view.forex_trading.order |
| Deals ledger | view.forex_trading.deal |
| Withdrawals | view.forex_trading.withdraw, edit.forex_trading.withdraw |
| Providers | view.forex_trading.provider, edit.forex_trading.provider |
| Instruments | view.forex_trading.instrument, create.forex_trading.instrument, edit.forex_trading.instrument |
| Symbol groups | view.forex_trading.group, create.forex_trading.group, edit.forex_trading.group, delete.forex_trading.group |
| Calendars | view.forex_trading.calendar, create.forex_trading.calendar, edit.forex_trading.calendar, delete.forex_trading.calendar |
| Economic calendar | view.forex_trading.economic_event, create.forex_trading.economic_event, edit.forex_trading.economic_event, delete.forex_trading.economic_event |
| Market news | view.forex_trading.news, create.forex_trading.news, edit.forex_trading.news, delete.forex_trading.news |
| A-book execution | view.forex_trading.execution, create.forex_trading.execution, edit.forex_trading.execution, delete.forex_trading.execution |
| Settings | view.forex_trading.settings, edit.forex_trading.settings |
Note that edit.forex_trading.execution covers enabling a hedge venue, changing
its knobs, flattening an orphan and booking a late fill — all of which move real
money at a real broker. Treat it as a Super-Admin-adjacent grant.
Scheduled jobs
Registered under the forex_trading category and visible at
Admin → System → Cron.
| Job | Period | What it does |
|---|---|---|
processFxSwaps |
1 hour | Settles overnight financing at the 17:00 New York cutoff, triple on the group's triple-swap day, weekdays only for FX, metals and stocks, seven days for crypto CFDs. Idempotent per position per rollover date; every run also catches up any cutoff missed in the last 7 days. |
reconcileFxAccounts |
5 minutes | Expires due GTD and DAY orders the tick path missed on quiet symbols, verifies that the deals ledger sums to the account balance and alerts on drift, and refreshes denormalised equity and used margin. |
runFxExecutionReconciler |
60 seconds | A-book. Replays each enabled venue's broker ledger through the idempotent booking paths, detects orphans in both directions (alert-only), sweeps stale in-flight rows, watches financing basis and cursor stalls, and auto-suspends new routing on a stall. Silent no-op with no provider rows. |
runFxHedgeMonitor |
60 seconds | A-book. Syncs each enabled venue's account state onto the provider row and alerts when margin used over NAV breaches marginAlertRatio or the sync repeatedly fails. |
processFxAffiliateRebates |
10 minutes | Awards IB and partner rebates on committed commission deals. LIVE accounts only, exactly-once. Silent no-op until a rebate condition is enabled. |
syncFxCalendarAndNews |
15 minutes | Refreshes the economic calendar and news feed. Provider rows are upserted; operator-authored MANUAL rows are never touched. Silent no-op when no provider serves either feed. |
It is hourly on purpose. Every tick settles the most recent elapsed cutoff plus any missed ones. A daily period would land at an arbitrary hour, and any restart that shifts it past a cutoff loses that day's rollover for every open position.
Database tables
| Table | Holds |
|---|---|
fx_provider |
Market-data vendors. One row may have status = true |
fx_execution_provider |
A-book hedge venues. Many may be enabled |
fx_instrument |
The catalog — unique on (currency, pair), with contract specs and per-provider symbol mappings |
fx_symbol_group |
Dealing-desk economics per group |
fx_session_calendar |
Trading-hours windows and holidays |
fx_account_group |
Account tiers — margin call, stop out, NBP, leverage cap |
fx_account |
Customer trading accounts |
fx_order |
Orders, market and pending |
fx_position |
Open and closed positions |
fx_deal |
The immutable money ledger |
fx_routing_rule |
Placement-time routing overrides |
fx_execution_alert |
The operator alert inbox |
fx_economic_event |
Economic calendar rows |
fx_market_news |
Terminal news feed |
Everything is MySQL. ScyllaDB is not used by this extension.
WebSocket endpoints
| Route | Carries |
|---|---|
/api/forex-trading/ticker |
Bulk ticker stream for the markets rail — a snapshot on subscribe, then per-symbol deltas |
/api/forex-trading/market |
Per-symbol market data and chart updates for the selected instrument |
/api/forex-trading/order |
The caller's own order and position updates |
All three are behind the same reverse-proxy /api route as the REST API. If
your proxy does not upgrade WebSocket connections, the terminal renders once and
then stops moving.
Notification templates
Editable under Admin → System → Notifications. All four are seeded.
| Template | Sent when |
|---|---|
FxTradingDepositConfirmation |
A trading account is funded from a platform wallet |
FxTradingWithdrawalStatus |
A withdrawal is approved or rejected |
FxTradingMarginCall |
An account crosses its margin-call level |
FxTradingStopOut |
A position is force-closed by stop-out |
Operator alerts are a separate channel: they fan out in-app and by email to holders of the Super Admin role only, and also land in the execution alert inbox.