Forex & Multi-Asset Trading 6.0.1

29 July 2026

This release has upgrade notes. Read them before updating — they describe behaviour changes that need your attention.

ORDERSMONEYMARGINNOTIFICATIONSA-BOOKADMINCOMPLIANCEAUDITTERMINALECONOMIC CALENDARMARKET NEWSIB REBATESPROVIDERSMOBILEKYCBREAKING

Forex & Multi-Asset Trading v6.0.1

Release Date: July 29, 2026 Tags: ORDERS, MONEY, MARGIN, NOTIFICATIONS, A-BOOK, ADMIN, COMPLIANCE, AUDIT, TERMINAL, ECONOMIC CALENDAR, MARKET NEWS, IB REBATES, PROVIDERS, MOBILE, KYC, BREAKING

Overview

A full review of the dealing desk — every screen, the execution and risk engines, the external-execution stack, the scheduled jobs, and both the terminal and the admin surface.

Most of what was checked held. The ledger never drifted once, stop-out and negative balance protection do what they claim, and every admin screen refuses a plain trader. What did not hold was the pending-order feature, which could not be used at all, a set of money-path edges around retries and allowances, and the fact that the addon never told a trader anything.

The terminal also gained an economic calendar, a market-news feed and a dedicated phone layout, and the rest of the workspace was rebuilt onto the Pro trading look the header adopted in 6.0.0.

Two things want an operator's attention on upgrade: introducing-broker rebates are a new program and ship switched off, and the standalone account page was removed, so any existing link to it no longer resolves. Both are in Upgrade Notes.

Requires Core v6.5.8.

Update Instructions

pnpm updator

No schema change and no operator action. One new user endpoint (GET /api/forex-trading/deal) is added, and four notification templates are created automatically on the first boot after the upgrade.


Upgrade Notes

Compatibility

One breaking change, described below: the standalone account page was removed, so any saved link to it no longer resolves. Nothing else breaks. Limit, stop and stop-limit orders are now accepted. A repeated deposit or withdrawal now answers with "already completed / already requested" instead of an error. A partial close that would leave less than the instrument minimum is now refused rather than accepted. The admin instrument list now opens A to Z rather than Z to A, which changes what a "select all" on the first page covers. Both introducing-broker conditions ship switched off and pay nothing until an operator enables them.

The account page was removed; accounts, funding and statements now live in the terminal

The standalone account dashboard is gone, and with it the addon's own Accounts menu entry. Any bookmark, shared link or saved shortcut to that page now dead-ends.

Accounts, deposits and withdrawals, and the account statement are now full views that open over the chart from the terminal header, and the addon's landing address goes straight to the terminal. Accounts are no longer somewhere you navigate to — they open where you trade. Deposit and withdrawal notifications now link to the terminal, since the page they used to point at no longer exists.


Added

Economic calendar

The terminal now carries a macro-release calendar, opened from the header. Each release shows actual, forecast and previous figures with a Low / Medium / High impact badge, and the list can be filtered by currency and by impact.

  • Provider sync. Releases are refreshed from the active market-data provider every 15 minutes.
  • Operator-authored releases. A new admin screen — Admin -> Forex Trading -> Market Data -> Economic Calendar — lets an operator enter releases by hand. Those entries are badged Manual, and the sync never reads, updates, prunes or deletes them. A desk whose data plan does not sell a calendar feed can run the entire calendar this way.
  • Hide, do not delete. To take a provider-synced release off the calendar, hide it. Deleting one only lasts until the next sync puts it back. Manual entries are the operator's to delete.
  • Window. One request covers at most 60 days, defaulting to the last 24 hours and the next 7. A release whose country maps to no currency is always shown, never filtered out — an unmapped country still moves the market.

Market news feed

The terminal also gains a news pane, opened from the header, which can be scoped to the instrument on the chart.

  • Per-symbol filtering. A scoped feed matches either leg of the pair, or the pair written closed up (EURUSD), against the story's headline and summary. It deliberately returns nothing rather than falling back to the unfiltered feed, so an empty pane means "no story mentions this pair" — not "the feed is broken".
  • Desk commentary. Operators publish their own stories from Admin -> Forex Trading -> Market Data -> Market News. They are badged Desk, the sync never overwrites them, and they can be tagged to symbols so a note reaches a scoped feed without having to name the pair in its prose.
  • Freshness. Stories older than 30 days never appear, and the feed refreshes every 15 minutes alongside the calendar. An operator's own story can take up to a minute to show, which is the cost of the feed answering instantly rather than re-reading on every open.

Introducing-broker rebates on the native dealing desk

Partner rebates can now be paid on the native forex dealing desk. This is a new program rather than a repaired one: before this release the native desk paid no rebates at all, and the only forex condition that existed belonged to the separate legacy forex investment addon. Two conditions ship, both under Admin -> Affiliate -> Conditions:

  • Forex IB Commission Share. Pays the partner a percentage of the commission their referred trader pays on each trade — the classic IB split.
  • Forex IB Volume Rebate. Pays a flat rebate per lot of referred volume, measured on the size actually filled rather than the size left open. Sizing it on the remainder is precisely backwards for the high-turnover clients an introducing broker is paid to bring: a position opened and closed between two ten-minute sweeps would earn the partner nothing, and a partly closed position would pay on what was left rather than on the volume actually traded.
  • Off by default. Both ship switched off and must be enabled by hand. Nothing starts paying money on upgrade.
  • Live accounts only. Demo volume is excluded. It is free to manufacture, and paying rebates on it would be a direct payout exploit.
  • Paid once, off the hot path. Rebates are awarded every ten minutes from commission that has already settled, so a rebate failure can never slow down or reject a client order, and the same trade can never pay twice — including after a cache wipe. A commission that lands in the same second as a sweep is picked up by the next one rather than dropped.

A phone and small-tablet layout for the terminal

Below 768px the terminal switches to a dedicated phone layout: one full-width view at a time — Chart, Trade, Positions, Markets — behind a bottom tab bar, with a compact header carrying the account strip, and bottom sheets for choosing an instrument, switching account, and reaching the extra surfaces (news, calendar, funding, statement, history).

  • The chart is never rebuilt. It stays mounted while another tab is showing and is re-measured the moment it comes back, so moving between tabs does not reload the series.
  • Between 768 and 1024 the desktop frame is kept and the side rails narrow instead. That band is wide enough for the three-column workspace to still be the better answer.
  • Landscape on a phone still gets the desktop frame, because the switch is on width alone. It is cramped rather than broken — every panel there collapses to a strip and hands the space back to the chart — and it is the same answer the crypto Pro terminal gives.

Live order tickets ask for verification before the ticket is filled in

Identity verification is enforced when a live order is submitted, but nothing said so beforehand. An unverified trader chose a size, prices, stops and an expiry, pressed Buy or Sell, and got a bare permission error.

On a live account the ticket now shows the verification requirement in place of the form, so the trader is told up front. Demo accounts stay completely open — practice never needs verification — and switching back to a demo account restores the ticket immediately.

The deals ledger can be filtered to one user from the CRM

Opening a user in the CRM and looking at their forex deals returned a server error: the deals ledger is recorded against a trading account rather than against a user, so there was nothing to match one against directly. A user filter now resolves through that user's trading accounts, so the CRM's forex view returns exactly that user's deals.

Traders could not see what they had been charged

Every movement on a trading account is recorded — commission on each fill, the swap charged at each rollover, deposits, withdrawals, negative balance protection, and any manual operator adjustment — and none of it was ever shown to the trader. They could see what their balance is and never how it got there.

Each account now has its own statement: paged, filterable by kind and date, each line carrying the balance it left behind. It opens from the terminal header, alongside accounts and funding.

The desk never told a trader anything

There was not one email and not one notification anywhere in the addon. Every consequential event happened in silence:

  • A withdrawal was approved and real money left the platform — the trader's only way to find out was to re-read their balance.
  • A withdrawal was rejected and the funds were returned — likewise invisible, including the operator's reason for refusing it.
  • A deposit landed on the trading account with no confirmation.
  • Positions were liquidated at stop-out. The engine force-closes the largest losing position when margin runs out; the trader discovered this by noticing an empty positions tab.
  • A margin call — the one warning that gives a trader a chance to add funds or cut exposure before the engine starts closing things — was never sent at all.

All four now notify: in-app always, plus email where an address is on file. The two engine notices can never delay a stop-out round, and the margin call is limited to one per breach and re-armed only when the account climbs back above the level.

The templates are created automatically on the first boot after upgrading, so an operator who upgrades without running the seeder still gets them.


Changed

The terminal's panels, dock and badges were rebuilt on the Pro trading look

v6.0.0 moved the terminal header onto the Pro trading header's geometry. The rest of the workspace has now followed, built to a trading density rather than borrowing the platform's page-sized controls.

Every region of the terminal is now a real panel with a compact 32px header, and badges and empty states follow one contract across the whole workspace. The markets rail was restyled to match.

A heavy accent halo also latched around the active Positions / Orders / History tab after every click, and the dock's edge clipped it square. Clicking a dock tab no longer leaves a ring latched on it, and the ring it draws when tabbed to is a hairline drawn inside the control.

The Text Size setting now scales the whole workspace, including the new accounts, funding, statement, news and calendar views.


Fixed

Pending orders could not be placed

Every limit, stop and stop-limit order was rejected with "Type must be one of the following: MARKET" before it reached the code that handles it.

Everything behind that was built and working: the trigger scan, limit-or-better fill pricing, stop-leg activation, good-till-date and day expiry — and, in the terminal, the ticket's Market / Limit / Stop / Stop-Limit tabs, trigger and limit price inputs, time-in-force selector and expiry picker. None of it could be reached from the product. Pending orders now place, rest, trigger and fill.

The pending path skipped the checks the market path applies

A pending order is not an inert record: when it triggers it opens a real position, and the trigger path runs no checks of its own. Whatever placement did not enforce was not enforced anywhere.

  • Both kill switches were bypassable. An account with trading disabled, and a platform with the master trading switch off, both refused market orders and both accepted pending ones — which then opened live positions the moment the market reached them. A freeze that only covers one of two doors is not a freeze.
  • The size step was not applied, so a pending order could be placed at a size the instrument does not deal in.
  • Attached stops were not checked at all. A pending buy whose stop loss sat above its own entry was accepted; the position it opened closed itself on the very next tick. Exits are now checked against the price the order will actually enter at, rather than against the current market.
  • Delayed instruments were refused outright instead of respecting the operator's real-time opt-in, unlike the market path.

Modifying a resting order bypassed its placement rules

Editing a resting order wrote the new prices straight through:

  • Non-numeric input was stored as an invalid number.
  • The minimum stop distance was never re-checked, so an order placed at a legal distance could be walked to one point off the market — bypassing the distance guarantee the desk makes on every placement.
  • Attached exits were not re-checked against the new entry.

All three are enforced on modify now.

The margin gate charged less leverage than the account was measured at

Opening an order calculated its margin from the account and symbol-group leverage, while the engine that then measures the account also applies a third setting — the account group's maximum leverage, the regulatory cap (an ESMA-style 1:30 tier, say).

On any platform using account groups the two disagreed. An order was admitted against margin calculated at 1:500 and the account was then margined at 1:30 — sixteen times more — so a trade that passed the free-margin check could put the account below stop-out the instant it opened, and be liquidated on the next tick. All three places now use the same three settings.

Retrying a transfer moved money twice

A safety token exists so that a client whose response never arrived can retry safely. It did not work on either money door.

Deposits answered a repeat with an error. No money moved, but the trader was told their deposit had failed when it had already succeeded — and the natural response to that is to deposit again. A repeat now returns the settled balance.

Withdrawals were worse. On a repeat the debit was correctly skipped — and then a second pending withdrawal was created for a single debit, counting the amount against the rolling allowance twice. Repeated with a larger amount, it queued a payout for money that had never been taken. A repeat now returns the original request.

The terminal minted a brand-new token on every click. Both the Deposit and Withdraw buttons generated a fresh one per press, which turns "the page hung, let me try again" into a second real transfer. The token is now held until the server gives a definite answer.

Rejecting a withdrawal cost the trader their allowance

A withdrawal request consumes the account's rolling daily and monthly allowance when it is made. Rejecting it refunded the money but never the allowance, so an operator's "no" silently cost the trader a day — or a month — of withdrawal headroom for money they never received. Both counters are now restored.

An approve and a reject arriving at the same moment would also both have applied — crediting the wallet and refunding the trading account for one withdrawal. Only one can now win.

Negative balance protection never ran on a desk with no external brokers

The sweep that pulls a negative account back to zero ran at the end of the external-execution reconciliation pass — and that pass stopped immediately when no execution providers were configured. A pure B-book desk, or any install where execution providers were never set up, had no negative-balance backstop at all. Such an account holds no open position either, so no price tick reached it on the way in: nothing anywhere brought it back to zero.

The sweep now runs on that path too. It is unconditional by design — it is the last line of defence on a balance that has already gone below zero, so it cannot be conditional on how the desk happens to be configured.

One data vendor's rate limit blacked out the whole desk

The cool-off applied after a provider refused a request was held under a single shared key. A rate-limit refusal from any provider — including one the operator had already switched off — stopped live quoting for every provider on the install. Cool-offs are now held per provider, and it is the active provider's own state that decides whether it can be used.

Refusals are also told apart now. A rate limit backs off for one to fifteen minutes and clears itself. A rejected key or an exhausted quota stops that vendor for an hour instead of being retried on every single call. A plan that simply does not sell a particular timeframe pauses that vendor's history only, and can never take the live price feed down.

And when a vendor did not say how long to wait, the cool-off was computed as zero and expired the instant it was set, so the intended one-minute back-off never actually happened. A missing wait now falls back to the real minimum.

Admin changes to an instrument took half a minute to apply

Instrument settings are cached for 30 seconds, and nothing was clearing that cache when an admin saved.

So every instrument change was stale for up to 30 seconds: swap points, contract size, size limits, stop distance, the delayed flag, group leverage/markup/commission, session calendars, a freshly imported catalogue — and, most seriously, status. HALTED is the emergency freeze control; it did not freeze anything for up to half a minute. CLOSE_ONLY kept accepting new positions for the same window. Every change now takes effect immediately.

Unsettled swap rollovers were silent revenue loss

An overnight swap charge has to be converted into the account's currency, which needs the pair's US-dollar hub legs priced. Only trending and hot symbols, plus those carrying an open position or a resting order, are subscribed to the price feed — so a EUR-denominated account holding GBP/JPY left both legs the conversion needed unsubscribed. The rollover was retried hourly, quietly expired after seven days and was never charged at all. The same missing rate also left that account's equity stale, so its stop-out level stopped moving.

The hourly job now pins the missing legs into the price feed so the next run can settle them, and raises a critical alert naming what failed and what it pinned. An unsettled rollover can no longer expire unnoticed, and only legs whose instrument is active are pinned. This affects accounts whose currency is neither leg of the pair being traded.

The terminal could load forever, or tell a funded trader to open an account

A failed accounts request looked exactly like an empty account list. A brief server outage left the header spinning indefinitely while the same screen said "No accounts", and a trader with a funded live account could be invited to open one. Loading and failure are now tracked apart: the header, the order ticket and the accounts view show a real error and keep retrying.

The retry cadence was wrong too. Loading the account list is what creates a trader's first demo account, so every attempt is a potential write — and it was repeating every 5 seconds for the life of the tab. It now retries five times quickly, then once a minute, and returns to the fast cadence the moment a productive answer arrives.

Ledger drift on an account with no open position was never checked

The integrity job only examined accounts holding an open position. But the things that break the balance-matches-ledger guarantee — a rolled-back close, an operator adjustment, a half-applied deposit — typically leave the account flat. Exactly the accounts most likely to have drifted were the ones never looked at.

Each run now also checks fifty further accounts on a rotating basis, so drift on a flat account is found within a bounded number of runs however large the book grows. Drift alerts are also no longer waited on one at a time: a burst of them could overrun the run and stall the order-expiry and equity work the same job owns.

This is separate from the summation fix in Smaller corrections below, which changed how the total is added up rather than which accounts are examined.

Bulk-enabling instruments activated the wrong end of the catalogue

The admin instrument list opened sorted Z to A, showing the alphabetical tail of the catalogue. "Select all" only covers the visible page, so a single Enable (Activate) bulk action switched on the last tickers in the alphabet and left every FX major inactive — while reporting full success. The list now opens A to Z. A symbol catalogue has to read in alphabetical order.

Provider failures flooded the log with identical lines

A misconfigured or unentitled market-data provider fails on every call, and the place that reported it ran once per provider, per symbol, per chart interval, per request. A key that can serve no candles at all printed several identical lines a second, indefinitely, burying every other message on the server.

Each provider state is now reported at most once every fifteen minutes, and the chart back-fill no longer repeats what the provider failure already reports. Nothing is suppressed — the cool-off is still recorded and the caller still sees the failure. Only the repetition is capped.

A doubled hedge at the broker could be hidden by an unrelated alert

The alert raised when the venue reports a second fill for an already-filled order shared one throttle window with the far more common unmatched-fill alert. The throttle claims its window before the inbox entry is written, so whichever fired first suppressed the other for fifteen minutes — silently hiding real doubled exposure at the broker.

Duplicate fills now throttle on their own. The alert inbox still offers the Flatten action for them, which matters because it is the most action-urgent alert the reconciliation job raises. This applies to installs routing to an external execution provider.

The execution reconciliation job re-read the whole day's swap ledger every minute

The basis calculation loaded every swap entry booked that day, unrestricted and in full, once a minute, holding a database connection while it did. The movement ledger is append-only and never pruned, so that cost grew forever. The scan is now limited to the provider's own positions and reads only the two figures it needs from each entry.

Matching an instrument to a position was also a fresh scan of the whole catalogue, repeated for every open external position on every run. It is now looked up directly.

Smaller corrections

  • Negative balance protection could pay twice when two sweeps overlapped. It cannot now.
  • The integrity job loaded every movement an account had ever made into memory, every five minutes, to add them up. That got slower forever — which is how an operator ends up disabling the one job that guards the balance. It now adds up in the database.
  • A partial close could strand an unclosable remainder. Closing all but a sliver left a position below the instrument's minimum size — too small to close in another partial — reported as open forever. A partial close must now leave a dealable size. Engine closes (stop-out, stop loss) are exempt: a liquidation must never be blocked by a size rule.
  • A resting order that triggered ignored the account's state. An account frozen while its order rested still opened a live position, and an order could fill on a fifteen-minute-old price after the operator withdrew the real-time opt-in. Both are re-checked at the fill.
  • Withdrawal limits were saved unchecked. A negative daily or monthly limit was accepted and blocked every withdrawal from then on. Limits must now be zero or above, or empty for no limit.
  • Admin account edit accepted non-boolean trading and swap-free flags. Alongside the withdrawal-limit validation above, the per-account trading switch and the swap-free flag were written straight through whatever their value was. Both are now refused unless they are true or false.
  • Attaching a stop to a position was not safe against a simultaneous close. It now is.
  • The per-type account cap could be exceeded by two submissions arriving at the same moment.
  • Admin forex screens now follow the site theme. The risk desk, providers, withdrawals, the execution desk and every admin table moved off fixed palette colours onto the platform's theme colours, and status badges are now coloured the same way as everywhere else in the platform — so these screens read correctly in both light and dark mode.
  • Admin navigation now leads with the day-to-day screens. The Market Data group — providers, instruments, symbol groups and trading-hours calendars — moved from second position to below Trading, Finance and Execution. It is configured once at setup, while the risk desk, the book and the ledger are opened all day.
  • The terminal tour points at the in-terminal account views. Its account-switcher step no longer says that "Manage accounts" opens the account dashboard — that page no longer exists. It now describes the menu items that open accounts, deposits and withdrawals, and account history without leaving the terminal.