Quantisentry

Telemetry

contract · SentinelTelemetryV1

A contract strict enough to be worth trusting.

Your expert advisor posts one JSON object. The server validates it against fixed rules, normalises it, and keys it by identity. Anything that doesn’t fit is rejected with a reason.

The payload

29 fields in. 31 stored.

Grouped as they are defined in the wire model. The two extra stored fields are added by the server: a composite identityKey and the lastSeenUtc receipt timestamp.

Field groups — SentinelTelemetryV1
GroupCountCarries
identity 10 accountKey, accountLogin, brokerServer, terminalName, magic, name, family, symbol, timeframe, contractVersion
version & time 3 timestampUtc, telemetryVersion, guardVersion
lot & risk 5 baseLot, requestedLot, finalLot, appliedMultiplier, riskMultiplierSource
decision 5 allowTrading, blockReason, lastDecision, sentinelAction, dashboardAction
execution quality 4 spread, slippage, positionLots, expectedLots
tickets 2 orderTicket, positionTicket
POST /api/ea-telemetry/v1/ingest 200 OK
X-Sentinel-Telemetry-Key: ••••••••

{
  "contractVersion": "SentinelTelemetryV1",
  "accountKey": "broker::184422",
  "magic": 184422,
  "symbol": "EURUSD",
  "family": "breakout",
  "telemetryVersion": "1.4.0",
  "guardVersion": "10D.4",
  "baseLot": 0.10,
  "requestedLot": 0.10,
  "finalLot": 0.0750,
  "appliedMultiplier": 0.75,
  "allowTrading": true
}

Identity key. Rows are keyed by accountKey|magic|SYMBOL|family. If accountKey is absent it is derived as {brokerServer}::{accountLogin}.

Validation

Six rules that must hold.

Fail any of them and the payload is rejected with 400 — it never reaches the store, and it never quietly becomes a half-row you’d have to debug later.

Hard-required validation rules
RuleConstraintWhy
contractVersion= SentinelTelemetryV1Version drift between fleet and platform is caught immediately, not months later.
magic> 0An expert without a magic number cannot be attributed to a strategy.
symbolrequiredUppercased on arrival so broker casing never splits one instrument into two.
familyone of 5A closed vocabulary keeps cross-account comparison meaningful.
appliedMultiplier0.0 – 5.0A bounded range means a bad input can never look like a plausible risk instruction.
versionsnon-emptyBoth telemetryVersion and guardVersion, so every row is attributable to a build.
  • breakout
  • meanreversion
  • trendpullback
  • cs28
  • unknown

Common aliases are normalised on arrival — brk → breakout, mr → meanreversion, trd → trendpullback, cs → cs28. Lot values are rounded to four decimal places, away from zero.

Freshness

Five states, and honesty about what they measure.

A row is stale five minutes after the last time the API heard from that expert. The clock is server-side: lastSeenUtc is stamped on receipt, not taken from the terminal. So freshness means “time since we heard from it”, which is exactly the thing you want to alert on — a terminal that stops talking is the failure mode that matters.

Legacy rows. Fleet rows derived from older, non-V1 sources use a wider 10-minute window and are labelled as such. We don’t blend the two.

  1. OK / FULL

    Full contract satisfied and seen within the window.

  2. PARTIAL

    Recent, but version fields are incomplete — the row is usable, not authoritative.

  3. STALE

    Full contract, but nothing received inside the window. The expert has gone quiet.

  4. LEGACY

    Derived from a pre-V1 source. Held to the wider window, never mixed with V1 rows.

  5. MISSING

    Expected by the registry, never seen. The absence is itself a signal.

Surface

One write. Three reads.

Telemetry routes
MethodRouteReturns
POST/api/ea-telemetry/v1/ingestAccepts one validated payload. Every attempt — allowed or denied — writes an audit entry with endpoint, actor, reason and accountKey.
GET/api/ea-telemetry/v1/latestLatest row per identity, optionally filtered by accountKey.
GET/api/ea-telemetry/v1/magic/{magic}Everything reporting under one magic number.
GET/api/ea-telemetry/v1/summaryCounts by state, including how many rows are past the freshness window.

Ingest is deliberately outside the blocked-route table: telemetry keeps flowing while every apply, override and config route returns 403.

Obedience

Did the terminal actually do it?

Instruction and execution are different things, and the gap between them is where fleets quietly drift. The lot audit closes it arithmetically: baseLot × expectedMultiplier against the lot the broker really filled, with a 5% tolerance.

  • OK
  • MISMATCH
  • MISSING_DATA

Evidence-bound. The audit is only as good as what the expert reports. Terminals that don’t send lot and multiplier fields resolve to MISSING_DATA — they are never scored as obedient by default.

Getting connected

One include, one call.

The MQL5 client is a single header with one send function. The only terminal-side requirement is allowing the endpoint in Tools → Options → Expert Advisors. The HTTP request times out at 8000 ms, so a slow network degrades into a missed heartbeat rather than a stalled expert.

The store keeps the latest value only. One row per accountKey|magic|symbol|family, last write wins. There is no time-series history and no retention window to configure. Quantisentry is an observation plane, not a data warehouse — if you need tick-level history, keep your own.

Payload signing is not shipped. The envelope has fields for a payload hash and signature, and nothing writes or verifies them today. Transport security is TLS plus a header key. We would rather tell you that than let you assume otherwise.