Latency in a Deriv bot is not a single number. It is a chain: the WebSocket round trip from your browser to Deriv’s servers, the platform’s processing of your request, the tick stream arriving on your subscription, and the moment your logic decides to send an order. Every link in that chain shifts the price context your bot believes it is acting on. This article breaks down where the time goes, how to measure it from the browser without inventing numbers, and how to adjust strategy parameters so that a strategy’s edge is not silently eaten by timing assumptions that only held in the backtest.
Trading involves significant risk and you can lose your entire stake. Test every strategy on a demo account first.
Where the time goes between a tick and an order
Deriv Bot runs in the browser and communicates with the Deriv API over a WebSocket connection. The relevant intervals are:
- Tick-to-decision: the time between a tick message arriving in the browser and your bot’s logic evaluating its conditions. This is local and usually small, but it grows with heavy block graphs, large state objects, and inefficient loops in custom blocks.
- Decision-to-send: the time to construct and serialize the `buy` (or `proposal` then `buy`) request. If your bot requests a fresh proposal for every trade, you pay an extra round trip before the buy is even sent.
- Send-to-acknowledgement: the WebSocket round trip to Deriv’s servers plus platform processing. This is the interval most people mean by “latency”, but it is only part of the story.
- Contract start offset: the difference between the tick your logic used and the tick at which the contract actually starts. For fixed-duration contracts this offset matters because entry price and expiry are set by the platform, not by your bot.
The key asymmetry: your bot sees ticks as a stream, but orders are discrete requests. Between the tick that triggered your condition and the contract actually opening, the market — including synthetic indices, which tick on fixed schedules — has moved. How much it moved depends on tick frequency and volatility, not on your intentions.
Measuring round-trip latency from the browser
You can measure the WebSocket round trip honestly using the API itself. The cleanest method is a `ping`/`pong` exchange, or any request whose response you can timestamp, sent repeatedly over the same connection your bot uses.
A minimal measurement loop in JavaScript, run in the browser console on a page with an open Deriv API WebSocket, looks like this:
const ws = new WebSocket('wss://ws.derivws.com/websockets/v3?app_id=1089');
const samples = [];
ws.onopen = () => {
let sentAt = 0;
const send = () => {
sentAt = performance.now();
ws.send(JSON.stringify({ ping: 1 }));
};
ws.onmessage = () => {
samples.push(performance.now() - sentAt);
if (samples.length < 50) setTimeout(send, 200);
else report(samples);
};
send();
};
function report(s) {
s.sort((a, b) => a - b);
const median = s[Math.floor(s.length / 2)];
const p95 = s[Math.floor(s.length * 0.95)];
console.log({ n: s.length, median, p95, min: s[0], max: s[s.length - 1] });
}
Notes on this method. The `app_id` shown is a public test identifier; use your own registered application ID for anything beyond a quick check. The `ping` request measures the request/response path, which is what your `buy` request will also traverse, but it does not include platform-side order matching. Run the loop at different times of day, because routing and server load vary. Report the median and the 95th percentile, not the mean: a single 800 ms outlier will distort an average and tell you nothing about typical behaviour.
For tick-to-order timing specifically, timestamp the tick handler and the `buy` send, then timestamp the buy acknowledgement. The difference between the first two is your local decision time; the difference between send and acknowledgement is your effective order latency. Log both. If your local decision time exceeds your network round trip, the bottleneck is your bot, not the connection.
Measurement caveat: browser timers are throttled in background tabs, and `performance.now()` resolution varies by browser. Keep the bot tab focused during measurement.
Worked example: how latency shifts entry context
This example is illustrative and uses round numbers to make the arithmetic visible. It is not a claim about any real instrument.
Suppose a synthetic index ticks once per second, and the tick size is 0.5 units on a price of 1000. Your strategy triggers on a tick and sends a buy. Assume a measured median round trip of 120 ms and a 95th percentile of 400 ms.
- At the median, the probability that at least one new tick arrives before your order is acknowledged is roughly 120 ms / 1000 ms = 0.12, or about 12% of triggers, if tick arrivals are independent of your order timing. This is an expected proportion under a simplifying assumption, not a guarantee.
- At the 95th percentile, that proportion rises to 400 / 1000 = 0.40, or about 40% of triggers.
Now suppose your strategy’s entry condition depends on the price being within 0.5 units of the triggering tick — one tick size. If a new tick arrives before acknowledgement, the price may have moved by one tick, and your effective entry is one tick worse than assumed. Over 1000 triggers at the median latency, the expected count of triggers affected is 0.12 × 1000 = 120. At the 95th percentile it is 0.40 × 1000 = 400.
The point is not the specific numbers. The point is that a backtest which assumes entry at the triggering tick is systematically optimistic whenever latency is non-zero, and the optimism scales with tick frequency and with how tightly your entry condition is defined. For contracts where the payout is small relative to stake movement — typical of short-duration Rise/Fall — a one-tick entry slippage can be a meaningful fraction of the edge you think you have.
Adjusting strategy parameters for measured latency
Once you have a latency distribution, you can make your strategy robust to it rather than pretending it does not exist.
- Widen entry tolerances. If your condition is “price equals X”, change it to “price within one tick of X” and record how often the wider condition fires. If the wider condition changes your backtest results materially, the original edge was a latency artefact.
- Pre-fetch proposals. Request a `proposal` before your condition fires, or cache the proposal ID, so the `buy` does not require an extra round trip. Check the API documentation for proposal expiry; stale proposals are rejected.
- Use duration buffers. For fixed-duration contracts, add a small buffer to the duration you backtested, or exclude the final ticks before expiry from your decision logic. The exact buffer depends on your measured p95 latency and the tick interval.
- Filter by tick interval. Strategies on instruments with sub-second ticks are more sensitive to latency than strategies on instruments with multi-second ticks. If your measured p95 round trip approaches the tick interval, the strategy is operating in a regime where entry timing is effectively random.
- Log latency alongside trades. Attach the measured round trip to each trade record. When you review results, you can check whether poor outcomes cluster at high-latency periods.
A minimal DBot rule set for the last point, expressed as block steps:
- On tick received: record `t_tick = now`.
- Evaluate entry condition.
- If condition true: record `t_send = now`, send buy request.
- On buy acknowledgement: record `tack = now`, store `tack – tsend` and `tsend – t_tick` with the contract ID.
- On session end: export the log and compute median and p95.
Limitations
This approach does not eliminate latency, and it does not tell you whether a strategy is profitable. It measures the timing of your own connection and logic; it cannot measure platform-side matching, queueing, or the internal state of Deriv’s servers, which are outside your observation. It also does not capture behavioural latency: the delay between your bot signalling a problem and you intervening, which is often far larger than any network round trip. And a latency-adjusted backtest is still a backtest — it is a filter, not proof. Large samples, out-of-sample tests, and a record of how many configurations you tried remain necessary. Finally, none of this changes the underlying risk: on fixed-stake contracts the stake is the maximum loss, and no amount of timing precision converts a negative-expectancy strategy into a positive one.
Frequently Asked Questions
Does lower latency make a strategy profitable? No. Lower latency reduces the gap between backtest assumptions and live execution, but it cannot create an edge that the strategy does not have.
Should I run my bot on a server instead of the browser? It can reduce local jitter, but it does not remove the network round trip to Deriv’s servers, and it changes the execution environment you tested in. Measure both before switching.
How often should I re-measure latency? Re-measure whenever you change network, browser, instrument, or bot logic, and periodically during long sessions, because routing and load vary over time.
Key Takeaways
- Latency is a chain: local decision time, request construction, network round trip, and contract start offset.
- Measure the median and p95 round trip from the browser using the API, not a single ping.
- Backtests that assume entry at the triggering tick are optimistic whenever latency is non-zero.
- Widen entry tolerances and add duration buffers proportional to your measured latency.
- Log latency with every trade so that execution timing is part of your record, not an assumption.
The ORSTAC repository hosts open-source bots you can inspect, adapt, and test on Deriv, where a free demo account is available to run them before any real stake is involved. Discussion of measurement methods and bot design happens in the ORSTAC Telegram group. Start on demo, record your sample, and define your maximum loss before you define your expected gain.
Trading involves significant risk and you can lose your entire stake. Test every strategy on a demo account first.
