Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions guides/api-and-header-contracts.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,19 +299,22 @@ Contract rules:
inclusive millisecond range. `range_complete` is an explicit completeness
assertion; successful observations with `false` must not be used as proof of
continuity. Equal timestamps are valid, and exact duplicate removal remains
provider/consumer policy.
provider/consumer policy. `TickHistoryRequest::source` selects one source for
the operation; providers must not silently fall back to or merge another
source. `TickSequence::source` reports the source that was actually used.
- `BaseMarketDataProvider::provider_time_ms()` and
`BaseMarketDataProvider::tick_history_interval_ms()` are optional metadata
hooks for providers whose history backend has its own clock or sampling grid.
A zero value means that Router should use its local clock or event-oriented
range semantics.

### Intrade observed tick history
### Intrade tick history sources

`platforms::IntradeBarPlatform::fetch_tick_history()` reads a bounded in-memory
archive populated by the platform's `/price_now` polling path. These are
observed quote snapshots, not a historical tick endpoint supplied by the
broker:
`platforms::IntradeBarPlatform::fetch_tick_history()` supports two explicit,
isolated sources. `LOCAL_OBSERVED` is the default and reads the bounded
in-memory archive populated by `/price_now`. `BROKER_HISTORICAL` uses the
authenticated `/quotes` execution-second history. There is no fallback or
automatic merge between them.

- `Tick::time_ms` keeps the broker timestamp, whose effective granularity is
one second.
Expand All @@ -324,6 +327,16 @@ broker:
- `range_complete=true` is returned only for aligned requests where every
expected one-second sample is retained. Missing, unaligned, or evicted
samples leave it false while the returned observations remain usable.
- Broker history returns one neutral `Tick::reference` value per available
whole-second timestamp; bid, ask, and last remain unspecified. Its
`range_complete=true` means every whole-second timestamp inside the original
inclusive request is present, not that every sub-second market event is
represented.
- Broker history uses the authenticated `/quotes` GET contract, limits each
broker request to 30 minutes, splits at broker-local midnight, rejects known
future-period and login HTML responses returned with HTTP 200, and reports
`TickSequence::source=BROKER_HISTORICAL`. The public request is conservatively
limited to two broker-local dates.
- `trade_check2.php` is a trade settlement/result check keyed by deal ID. It
is not the implementation of `fetch_tick_history()`.
- `BarSubscriptionRequest::continuity` enables Router-owned bar prefill and
Expand Down
32 changes: 26 additions & 6 deletions guides/market-data-router.md
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,11 @@ live-only routes without treating them as continuity-verified.
The provider contract now has a separate `fetch_tick_history(...)` operation:

```cpp
md::TickHistoryRequest request("EURUSD", 1700000000000, 1700000060000);
md::TickHistoryRequest request(
"EURUSD",
1700000000000,
1700000060000,
md::TickHistorySource::BROKER_HISTORICAL);
provider.fetch_tick_history(
request,
[](md::TickHistoryResult result) {
Expand All @@ -656,6 +660,12 @@ The adapter validates symbol, range, and ordering. Exact duplicate handling
and any provider sequence identity remain a consumer/provider policy; the
base `Tick` DTO currently has no universal sequence field.

The source is selected per request. `LOCAL_OBSERVED` is the backward-compatible
default; `BROKER_HISTORICAL` asks the provider for its broker archive. Providers
must reject an unsupported source rather than silently falling back or merging
sources. A successful `TickSequence::source` identifies the source actually
used, independently from `TickSequence::provider`.

`MarketDataContinuityService::request_tick_history_batch()` is a thin adapter
for providers that implement the operation. It validates symbol, range, and
ordering, converts `TickSequence` into a `TickDataBatch`, and marks items as
Expand All @@ -674,11 +684,11 @@ service.request_tick_history_batch(
true); // require_complete_range
```

`MarketDataRouter` also applies the history contract to tick routes. The
Intrade Bar provider implements `fetch_tick_history()` as a bounded,
session-scoped archive of observed `/price_now` snapshots. This is useful for
short prefill and reconnect windows, but it is not an authoritative broker tick
archive:
`MarketDataRouter` also applies the history contract to tick routes. Its
generated requests use the backward-compatible `LOCAL_OBSERVED` default. The
Intrade Bar provider also accepts explicit `BROKER_HISTORICAL` requests backed
by `/quotes`; those observations are not automatically mixed with the bounded,
session-scoped `/price_now` archive:

- broker timestamps have one-second granularity;
- the archive starts empty for a new authenticated session and evicts old data;
Expand All @@ -688,6 +698,16 @@ archive:
snapshots are removed;
- `trade_check2.php` remains a settlement/trade-result API and is not used for
range history.
- `/quotes` supplies one broker-published value on a whole-second grid. That
value uses `Tick::reference` because bid/ask/last semantics are not proven;
complete coverage means every requested grid timestamp is present, not every
sub-second market event. The authenticated request is a GET with
`symbol/date/from/to`. The current authenticated page accepted exactly 30
minutes (`1,801` rows) and rejected 30 minutes plus one second with its
visible maximum-period validation page and no quote rows. Longer ranges are
split by the provider at non-overlapping whole-second boundaries and local
midnight. Future periods are returned as broker validation failures, not as
empty history.

Providers may expose optional history-clock metadata through
`BaseMarketDataProvider::provider_time_ms()` and
Expand Down
33 changes: 27 additions & 6 deletions guides/market-data-router.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,11 @@ if (state && state->enabled) {
В provider contract появилась отдельная операция `fetch_tick_history(...)`:

```cpp
md::TickHistoryRequest request("EURUSD", 1700000000000, 1700000060000);
md::TickHistoryRequest request(
"EURUSD",
1700000000000,
1700000060000,
md::TickHistorySource::BROKER_HISTORICAL);
provider.fetch_tick_history(
request,
[](md::TickHistoryResult result) {
Expand All @@ -808,6 +812,13 @@ timestamps разрешены: поток тиков событийный, а н
конкретного provider/consumer; у базового `Tick` сейчас нет универсального
sequence field.

Источник выбирается для каждого запроса отдельно. `LOCAL_OBSERVED` является
обратно совместимым значением по умолчанию, а `BROKER_HISTORICAL` запрашивает
архив брокера. Provider обязан отклонить неподдерживаемый источник, а не делать
скрытый fallback или объединять источники. В успешном результате
`TickSequence::source` указывает фактически использованный источник независимо
от `TickSequence::provider`.

`MarketDataContinuityService::request_tick_history_batch()` — тонкий adapter
для provider, который реализует операцию. Он проверяет symbol, range и order,
превращает `TickSequence` в `TickDataBatch` и помечает items как `HISTORICAL`
Expand All @@ -826,11 +837,11 @@ service.request_tick_history_batch(
true); // require_complete_range
```

`MarketDataRouter` теперь также применяет history contract к tick routes.
Intrade Bar реализует `fetch_tick_history(...)` через ограниченный
session-scoped архив наблюдаемых snapshots из `/price_now`. Это полезно для
короткого prefill и reconnect recovery, но не является authoritative broker
tick archive:
`MarketDataRouter` также применяет history contract к tick routes. Создаваемые
им запросы используют обратно совместимый источник `LOCAL_OBSERVED`. Intrade
Bar дополнительно принимает явный `BROKER_HISTORICAL`, основанный на `/quotes`;
эти наблюдения автоматически не объединяются с ограниченным session-scoped
архивом `/price_now`:

- broker timestamps имеют гранулярность в одну секунду;
- архив пуст для новой authenticated session и вытесняет старые данные;
Expand All @@ -840,6 +851,16 @@ tick archive:
snapshots удаляются;
- `trade_check2.php` остаётся settlement/trade-result API и не используется
для range history.
- `/quotes` возвращает одно опубликованное брокером значение на секундной
сетке. Оно хранится в `Tick::reference`, поскольку семантика bid/ask/last не
подтверждена; полное покрытие означает наличие каждой запрошенной секундной
отметки, а не каждого внутрисекундного события рынка. Аутентифицированный
запрос использует GET-параметры `symbol/date/from/to`. Текущая
аутентифицированная страница приняла ровно 30 минут (`1 801` строку) и
отклонила 30 минут плюс одну секунду страницей проверки максимального
периода без строк котировок. Более длинные диапазоны провайдер разбивает по
неперекрывающимся целым секундам и локальной полуночи. Будущий период
возвращается как ошибка валидации брокера, а не как пустая история.

Провайдер может дополнительно реализовать метаданные времени через
`BaseMarketDataProvider::provider_time_ms()` и
Expand Down
12 changes: 10 additions & 2 deletions guides/platform-api-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ Subscription rules:
- `TickHistoryRequest` and `TickHistoryResult` use inclusive millisecond ranges.
A successful result may be useful even when `range_complete=false`; that
flag is the provider's proof that the requested range is fully accounted for.
`TickHistoryRequest::source` explicitly selects one history source and
`TickSequence::source` reports the source used. Providers do not silently
fall back to or merge another source.
- `BarSubscriptionRequest::continuity` lets `MarketDataRouter` request initial
bar history before live delivery and optionally recover timestamp gaps. Live
batches are buffered while history is in flight. Route-scoped progress is
Expand All @@ -151,8 +154,13 @@ Subscription rules:
recovery. Tick routes can use `TickSubscriptionRequest::continuity` with the
same history-first lifecycle when the provider implements
`fetch_tick_history()`.
- Router continuity supports bars and tick routes. Intrade additionally exposes
a bounded, session-scoped observed-tick archive populated by `/price_now`.
- Router continuity supports bars and tick routes. Intrade exposes a bounded,
session-scoped `LOCAL_OBSERVED` archive populated by `/price_now` and an
explicit `BROKER_HISTORICAL` source backed by the authenticated `/quotes` GET
contract. Each broker request is limited to 30 minutes; longer ranges are
split by the provider.
The local archive remains the default, so Router-generated requests preserve
their existing behaviour. The sources are never merged automatically.
Its timestamps have one-second broker granularity, and `range_complete=true`
means every expected observed second is present in the retained archive, not
that every broker micro-event was captured. The archive is non-persistent and
Expand Down
Loading
Loading