Where prices come from, which instruments each way can serve, what each accuracy tier actually replays, and what happens when the data is not there.
Sources
There are three ways to get real bars into the engine, and a generator for when you have none.
Dukascopy, built in. Downloaded on demand from the toolbar under Data, This machine. It serves every instrument in OrionQuant's archive: forex pairs, gold and silver, cash indices, US shares, energy, copper and ten coins, and nothing else. Asking it for anything else returns a successful download of nothing, so the view warns you when the symbol is not one it serves, though it does not stop you pressing the button.
Every download comes from OrionQuant's data archive and never from the vendor directly. A range the archive already holds arrives in seconds. A range it does not hold yet is fetched there first, and the download counts the files the archive has fetched so far. The first download of years nobody has asked for before can take minutes, and everybody after that gets them in seconds. If the wait ends before the archive is done, the archive keeps going, and downloading the same range again later picks up the rest.
Bars arrive as minute bars, plus the timeframe you downloaded for. Each bar keeps its bid and its ask beside the mid price, which strategies and indicators read, so fills can use the spread the market showed. On a plan with the Tick tier the download also keeps raw ticks, one file per UTC day in a ticks folder beside the bar files, which is what makes the Tick tier reachable. A range already downloaded is not asked for again unless you press Refresh range.
London Strategic Edge, for what Dukascopy does not carry. Shares worldwide, ETFs and most crypto come from London Strategic Edge through the same archive, as minute bars, with every timeframe above them built from those. They are in the instrument picker under Stocks and ETFs, Crypto and the other groups, marked London Strategic Edge. They need a paid plan: on Free, an order for one is refused. Share prices are split adjusted. There are no ticks for them in the archive, so the Tick and L2 tiers do not apply: a download with ticks brings the bars and says why the ticks are missing. Forex, metals and everything else Dukascopy serves stay with Dukascopy.
Plugin data sources. A plugin can add one. Every enabled one appears in the Data source menu on This machine's toolbar, which is shown once there is more than one source to pick between. The Yahoo Finance plugin, which earlier versions installed on their own and which keeps working where it is installed, registers a source called Yahoo Finance Daily, which serves daily bars for the symbols Yahoo carries: stocks, ETFs, crypto pairs like BTC-USD, currency pairs written as EURUSD=X. A plugin source returns bars rather than ticks, so nothing it downloads can feed the Tick tier. Its bars are written under the timeframe the download names, so choose D1 for a daily source; the whole range is fetched every time rather than resuming from what is cached, and Cancel does not interrupt it.
The server's own copy. Data, then Server in the rail, in both the desktop app and the browser. This is one shared cache rather than a folder on your machine: a server run replays it, everybody sees the same instruments, and nothing you read from it costs you anything. It is also the only market data the browser build has, since a browser has no folder to keep a cache in.
When the instrument you want is not there, Download to server asks for it. The download happens on the server, takes minutes to hours depending on the period, and you can leave the page while it runs. What arrives stays for everybody, which is why the allowance is small and why a request is counted rather than a gigabyte:
| Plan | Requests a month |
|---|---|
| Free | 1 |
| Pro | 5 |
| Max | 10 |
| Enterprise | Unlimited |
A request that fails costs nothing. A symbol the vendor does not carry, a period with no data behind it, or a download that runs out of time all leave the allowance where they found it, and the row says which of those happened. Asking for something the server already holds is refused rather than queued, for the same reason. Two people asking for the same thing at the same time is one download and one charge, for whoever asked first.
CSV import. Data, then Instruments in the rail. Define the symbol first, with its contract size and its price increment, then drop in a file. Comma, semicolon and tab separated files are all read, the columns are detected and can be mapped by hand, and a timestamp is accepted as ISO 8601 (a naive one is treated as UTC), the MT4 dotted form, or a unix epoch in seconds or milliseconds. The timeframe is detected from the spacing of the bars and can be overridden. This is the way in for anything the two sources above do not serve.
Synthetic generator. The engine has one for its own tests, and the guest preview shows fixed synthetic runs. No run you start in the app uses it: a range with no data is fetched from the archive or refused, never made up.
| Way in | What it covers | Keeps ticks |
|---|---|---|
| Dukascopy | Every archive instrument: forex pairs, gold and silver, cash indices, US shares, energy, copper, ten coins | Yes |
| Yahoo Finance Daily | Stocks, ETFs, crypto and currency pairs, daily bars only | No |
| Another plugin | Whatever that plugin serves | No |
| CSV import | Anything you have a file for | No |
A symbol may hold -, . and = as well as letters and digits, up to 16 characters, so BTC-USD, BRK.B and EURUSD=X all reach the cache. Anything else in the name is refused, which includes the ^ Yahoo puts in front of an index. Holding the data is not the same as the engine knowing how to price it. The engine places a six letter currency pair and a six letter crypto pair by their shape, and its properties table also covers the two metals, eleven cash indices and three energy CFDs by name. A symbol it cannot place is refused before the run starts unless the run declares an asset class or a custom symbol defines it, and the result records the class it used.
Downloads and imports are desktop only. The browser build has no local cache.
Accuracy tiers
| Tier | What it replays | Needs on disk | Spread |
|---|---|---|---|
| OHLC | The bars of your chosen timeframe | Bars at that timeframe | The bar's bid and ask |
| M1 proxy | One minute bars inside each chosen bar | Ticks, or M1 bars | Each minute's bid and ask |
| Tick | Every tick | Ticks | Each quote's bid and ask |
| L2 | Every tick, with the order book | Ticks and order book files | Each quote's bid and ask, and the book's levels |
Bars with one price, from an import, a plugin or a download made before the engine kept both sides, draw their spread from the average spread on the custom symbol instead, or the run is refused as spread_missing. See Costs and Fills.
Higher tiers answer the intrabar question more honestly and take longer. L2 is not in the picker: a tick run whose strategy reads the order book gets it on its own.
A tier you have no data for is not an error. The run happens on plain bars, and the result records the tier it actually achieved beside the source it actually used. Look at both before comparing two runs: asking for Tick on a range with no cached ticks gives an OHLC run, and until the engine reported this there was no way to tell one from the other.
A range downloaded from Dukascopy supports OHLC and M1 proxy on every plan, because every download keeps its minute bars, and Tick as well on a plan with the Tick tier, because there the download keeps its ticks. Bars from a plugin source or a CSV import support OHLC, and M1 proxy as well when what is cached is M1 bars and the run is on a higher timeframe.
When the range is not fully cached
Press Start and the app first looks at what this machine holds for the range. What is missing is fetched from the archive, with the progress in the time bar, as far as your plan allows it. A range that ends up half there runs on that half. Nothing is filled in, nothing synthetic is mixed with real bars, and the bar count is lower than you expected. The bar count is the thing to read.
When none of the range arrives, the run does not start. The page says so and has an Open Data button. A server run fetches what the server lacks the same way before it starts, about a minute per year of minute bars the first time, and that wait is not counted as server minutes. What cannot be had stops it with data_missing. The coverage table under Data is what to check first.
Holidays and gaps
The engine replays the bars it has. It has no trading calendar, so a market holiday is simply a stretch with no bars, and a half day is a short one. Nothing marks either as special, and a strategy that counts bars rather than time will behave differently across one. Where a gap matters is the fill: a bar that opens beyond your stop never traded at the stop level, so it fills at the open and the gap costs what it cost.
Timeframes
M1, M5, M15, M30, H1, H4, D1. Bars are stored one file per instrument and timeframe, and an OHLC run reads the file for the timeframe it asks for. It does not aggregate one timeframe from another: a range downloaded as M15 has no H1 bars, and an OHLC run at H1 over it finds nothing, and the run stops for want of data. Two paths do aggregate. On the Tick and M1 proxy tiers cached ticks build bars at any timeframe, and cached M1 bars build any higher timeframe on the M1 proxy tier. Every Dukascopy download keeps its M1 bars, so a Dukascopy range serves any timeframe on M1 proxy, and downloading the same range again at another timeframe builds that timeframe from the M1 already on disk without fetching anything. A plugin download or a CSV import serves the timeframe it was written at, plus every higher one on the M1 proxy tier when it was written at M1.