Prices you can prove.
Two kinds of markets trade on TFC Global Markets: real forex, indices, metals, and crypto CFDs, priced by external liquidity providers we do not control — and synthetic instruments generated by an in-house engine that reads only its own configuration and its own random-number cursor. This page explains, in plain English, how both are kept honest.
01 · Two markets, one standard
One rule: the market has to be honest before the trade can be honest.
We run two families of markets. The first is the real one: currency pairs, indices, metals, and major crypto pairs, priced by a tier-1 liquidity aggregator on the interbank side. We publish the spread, we pass the price through, and we take a fixed commission per lot. We do not run a dealing desk against you.
The second is synthetic. These are markets we build ourselves — volatility indices, boom-crash pairs, tick and step markets — that exist only inside the TFC platform. They are priced by an engine we wrote and can point you at in the codebase. Every trader sees the same tick at the same moment. The engine cannot see your account.
This page walks through both sides. If either one feels vague, tell us and we will rewrite it.
02 · Real-market execution
The price comes from outside. We do not shape it.
For CFDs on real underlying markets, our platform receives quotes from an aggregator that combines feeds from tier-1 liquidity providers. We overlay a fixed per-symbol markup that funds the desk (the “spread” you see is the aggregate best bid/ask plus our markup) and, on some accounts, a per-lot commission. That is our revenue.
We do not:
- Requote you when the market moves faster than your click.
- Widen your specific spread while narrowing another trader’s.
- Slow your fills because your account has been profitable.
- Trade against your book from a dealing desk we hide from you.
What we do: pass the aggregated best bid/ask through, plus the disclosed markup, and let the LP fill you. Slippage happens in both directions during fast markets, because the price you clicked is not the price the LP could fill at — that is a real market cost, and it applies whether we are involved or not.
03 · The synthetic engine
Deterministic seed → PRNG → per-symbol rule → tick.
Our synthetic instruments are generated by the same engine that powers TFC Funder’s prop terminal. The engine is deterministic. Every symbol starts with two numbers: a hash of its ticker string (so different symbols get different starting seeds) and a platform-wide seed constant. XOR them and you have the initial state for that symbol’s pseudo-random number generator (a Mulberry32 PRNG). Every tick is produced by advancing that PRNG one step and applying the symbol’s family rule.
In pseudocode:
// Per-symbol tick loop, once every tickIntervalMs
function stepSymbol(config, previousState, now):
(nextPrng, u) = mulberry32(previousState.prngState)
candidateMid = rule[config.family](config, previousState, u)
newMid = clamp(candidateMid, config.basePrice)
halfSpread = config.spread / 2
bid = newMid - halfSpread
ask = newMid + halfSpread
return { symbol, bid, ask, mid: newMid, timestamp: now }
Three inputs: the symbol’s static configuration, the symbol’s prior price state, the wall clock. That is the whole surface. No trader identity, no balance, no open positions, no stop losses. The engine cannot see them because the function is never given them.
04 · The fairness boundary
What we cannot do, by design.
The engine’s public interface is five functions: start, stop, getMid, getBidAsk, and asMidLookup. That surface is defined in the codebase as a TypeScript type. The type has no method for reading a trader’s position, taking a trader-derived input, or overriding a tick after broadcast. Adding one would fail the type checker and the build would not ship.
“MidLookup is what the trading engine receives to price a fill or evaluate SL / TP. It is a pure read side of the price engine; it cannot mutate price. The trading engine may NOT be given the price engine instance itself.”
— lib/synthetic/types.ts
The part of the system that sees your account (the trading engine) can only read the current bid and ask. The part of the system that decides what the next tick is (the price engine) can only see its own configuration and its own random-number cursor. Neither can touch the other side’s data.
Concretely, the price engine has no ability to:
- Read your position size, direction, entry, stop loss, or take profit.
- Read your balance, equity, drawdown, or account tier.
- Read your account age, country, IP, or any other identity attribute.
- Skew the next tick to trigger a stop or bypass a take-profit.
- Widen the spread on a specific trader while narrowing it for another.
None of those knobs exist in the codebase. They were never written.
05 · The audit trail
Every tick lands in a table you can query.
Every tick the engine produces is persisted to a Postgres table called synthetic_ticks in our Supabase database, with the symbol, bid, ask, mid, and a millisecond timestamp. It is the source of truth for anything the platform needs to know about historical prices — charts, fill prices, stop evaluations, and the retroactive reconstruction of any trade.
If you dispute a fill, you can request the tick sequence covering the trade. We publish the sequence, timestamps included, and you can verify the fill against the tick record. If we deviated from our own feed, the discrepancy shows up in the row. For real-market CFD trades, execution reports include the LP quote at fill time and can be reconciled the same way.
A public replay endpoint is on the roadmap: pick a minute of history, get back every tick that fired in that minute across every synthetic symbol. When it ships we will link it here.
06 · What this doesn’t cover
Fair execution is not the same as a risk-free trade.
We would rather be honest about the limits of this page than have a trader assume it guarantees more than it does.
- Execution latency. Network latency between your device and our servers can put a few hundred milliseconds between the tick you see and the tick that fills your order. Fast markets can move against you inside that window.
- Leverage and margin. CFDs are leveraged. A small move against you can wipe out your margin. Losses can exceed deposits on accounts without negative balance protection. Read the risk disclosure before opening a live account.
- Model risk on synthetics. The synthetic engine draws from a normal distribution and applies clamps. Real markets show fatter tails, longer trends, and dislocations that a deterministic model does not fully replicate. The delta family adds spikes to approximate this, but no synthetic is a full mirror of the real thing.
- Spreads and commission. Every symbol has a published spread and, where applicable, a per-lot commission. Both favor the house on aggregate over a long enough sample. That is the broker’s economic model, not a fairness violation — but it is a real cost.
- Risk-mode overrides. An operator can put a symbol into
close_onlyorpausedmode, or apply a spread multiplier during unusual events. These are audited (every change writes a row with actor, before, after, reason) and cannot be applied per trader — only to the symbol universe.
We built the platform so we would not have to cheat, and we are showing you the shape of it so you do not have to take our word for it. Read the file. Read the type. If the surface has a hidden knob, tell us and we will fix it.