{
  "category": "Lookup and reference functions",
  "display_name": "RTD",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.RTD",
  "implementation_state": {
    "answer_bank": null,
    "detail": "The answer comes from a COM server the host starts. DNA Calc recognises the name and calculates no answer.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": false,
    "state": "host",
    "state_label": "Needs a host",
    "summary": "Needs a real-time data server",
    "workbook_corpus": null
  },
  "implementations": [],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.RTD.json",
  "name": "RTD",
  "notes": [],
  "schema": "efh.function-reference/v1",
  "section_order": [
    "what-it-does",
    "try-it",
    "quirks",
    "how-to-implement",
    "version-differences",
    "alternatives"
  ],
  "sections": {
    "alternatives": "\n### Relationships\n\n- **`WEBSERVICE` / `FILTERXML`** are the other externally-sourced functions, but they are\n  pull-based and synchronous — a request made during evaluation, not a subscription.\n- **`NOW` and `TODAY`** are the mundane non-deterministic functions: volatile, but with a\n  source of truth (the clock) that any implementation has.\n- **User-defined functions marked as volatile** and add-in async functions occupy the adjacent\n  ground; the C API's asynchronous-function support is the same problem solved a different way.\n- Readers sometimes expect `RTD` to be a data-import function. It is not: it delivers one\n  value per call, pushed, with no schema.\n\n\n",
    "how-to-implement": "\n### Notes for implementers\n\n\n- Separate the request from the resolution. Parsing `(prog_id, server, topics…)` into a\n  well-formed request is deterministic and testable; obtaining a value is not. The reference\n  engine draws exactly this line, with a provider trait on one side and request parsing on the\n  other.\n- Model the provider's non-value outcomes explicitly — not-yet, capability denied, connection\n  failed, provider error — rather than collapsing them into one failure. They surface as\n  different worksheet codes and they have different remedies.\n- Topic identity matters: the same `(prog_id, server, topics)` tuple from two cells is one\n  subscription, and the engine must not create two.\n- Do not attempt to make `RTD` deterministic for testing by caching. A cached `RTD` value is a\n  correct workbook state and an incorrect test oracle.\n- `HostSerialized` thread safety is a hard constraint, not an optimization hint.\n\n\n",
    "quirks": "\n### Why a reference engine cannot answer this\n\nThat is the honest position and it is worth stating plainly rather than apologetically: a pure\nfunction evaluator cannot evaluate `RTD`, because the answer does not exist inside the\nevaluator. Producing one would require a live COM server, a machine on which it is registered,\na subscription, and a moment in time. None of those are properties of the formula.\n\nThis is the same boundary that `GETPIVOTDATA` sits on, from the other side: `GETPIVOTDATA`\nneeds a workbook structure the engine does not own, and `RTD` needs a process the engine cannot\nstart.\n\n\n\n### Result and edge cases\n\n\nThe return kind is whatever the server supplies — typically a number or text, and, in the\ntransient states, one of the extended error codes.\n\n- **Before the first value arrives**, the documented worksheet experience is a transient\n  placeholder. [The value universe](../model/01-value-universe.md) models `#GETTING_DATA` and\n  `#BUSY!` as exactly this: extended-family error codes standing in while external data is\n  retrieved. Which one appears, and for how long, is host and server behaviour.\n- **When the server is unavailable or blocked by policy**, `#N/A`, `#CONNECT!` or `#BLOCKED!`\n  are the codes the model reserves for those conditions. The Handbook has not verified which\n  `RTD` actually produces under which condition.\n- **Values persist across recalculation** until the server pushes a new one; a cell holding an\n  `RTD` value is not recomputed from its arguments in the ordinary sense.\n- **Saved workbooks** retain the last received value as a cached result, which reopens without\n  the server present. That cached value is indistinguishable from a live one by inspection.\n- **Threading.** `RTD` is classified `HostSerialized`: it cannot be evaluated on an arbitrary\n  calculation thread, because the COM interaction has affinity.\n\n\n\n### Errors\n\n\nMicrosoft's documentation for `RTD` describes the function's purpose and arguments; the\nHandbook has not confirmed an enumerated error table on that page and does not assert one.\n\nThe error surface a reader meets in practice comes from three places, and only the first is\n`RTD`'s own:\n\n1. arguments that cannot be coerced to text — `#VALUE!` under the ordinary coercion rules;\n2. the transient and connection codes listed above, produced by the host on the server's\n   behalf;\n3. security policy — real-time-data servers are executable code, and a workbook that arrives\n   with `RTD` formulas is a workbook that wants to start a process. Whether it may is a trust\n   decision made outside the formula.\n\n\n",
    "sources": "- Microsoft, *RTD function* —\n  <https://support.microsoft.com/en-us/office/rtd-function-e0cc001a-56f0-470a-9b19-9455dc0eb593>\n  (purpose and the `prog_id` / `server` / `topic` argument structure). Not retrieved for this\n  page; the behaviour above is stated as documented behaviour and should be re-checked against\n  the page.\n- Handbook `content/model/01-value-universe.md` (the extended error family, including\n  `#GETTING_DATA`, `#BUSY!`, `#CONNECT!` and `#BLOCKED!`, and the open question of how the\n  transient placeholders are classified).\n- Handbook `content/model/03-call-pipeline.md` (host interaction and the boundary between\n  function semantics and engine obligations).\n- Handbook `data/battery/FUNC.RTD.json` — the uniform battery record, every row\n  `cannot-call:nondeterministic-by-declaration:external-event-dependent`.\n- Handbook `data/functions/FUNC.RTD.json` — signature, arity 3–255, and the\n  `ExternalEventDependent` / `ExternalProvider` / `HostSerialized` / `VolatileContextual`\n  classification axes.\n\n\n",
    "version-differences": "No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.",
    "what-it-does": "\n`RTD` does not compute a value. It **names a subscription** and returns whatever the named\nserver most recently pushed for that topic.\n\nThe mechanics, as the function's interface implies: `RTD(prog_id, server, topic1, …)`\nidentifies a COM automation server by its programmatic identifier, optionally on a named\nmachine, and hands it an ordered list of topic strings. The server registers the topic, and\nthereafter *the server* decides when a new value exists and notifies Excel; Excel then\nrefreshes the subscribing cells. The direction of control is inverted relative to every other\nworksheet function: an ordinary function is pulled by recalculation, and `RTD` is pushed by an\nexternal process.\n\nThe canonical use is a market-data feed — one `RTD` call per instrument per field, thousands of\nthem, updating several times a second without the user touching anything.\n\nThree consequences follow directly, and they are what make `RTD` interesting to a handbook of\nfunction semantics rather than a handbook of Excel features:\n\n1. **`RTD` is not deterministic.** Two evaluations with identical arguments may legitimately\n   return different values, because the value is a function of time and of an external\n   process's state, not of the arguments.\n2. **`RTD` is volatile**, and volatile in the strongest sense: it participates in recalculation\n   because something outside the workbook said so.\n3. **`RTD` has no mathematical content whatsoever.** There is no kernel to be accurate about,\n   no rounding to characterize, no residual plate to draw. Its entire semantics is a protocol.\n\n\n\n### Arguments\n\n**`prog_id`** — text. The COM programmatic identifier of the real-time-data server (the string\nunder which the server registered itself on the machine).\n\n**`server`** — text. The machine on which the server runs. Empty text means the local machine;\nthis is the argument readers most often mis-handle, because \"omit it\" and \"pass an empty\nstring\" are not the same thing, and it is a required position rather than an optional one.\n\n**`topic1`, `topic2`, …** — text. The topic strings passed to the server, in order. Their\nmeaning is entirely the server's business: Excel neither parses nor validates them. Two servers\ncan use the same topic string for unrelated data, and there is no schema anywhere in the\nsystem.\n\nAll the arguments are text, and all of them are coerced to text before being handed on. That\nmakes `RTD` calls fully dynamic — the topic can be built from cells — and it also means a typo\nis not a syntax error; it is a topic the server has never heard of.\n\n\n"
  },
  "signature": {
    "display": "RTD(ProgID, server, topic1, [topic2], ...)",
    "parameters": [
      {
        "description": null,
        "name": "ProgID",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "server",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "topic1",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "topic2",
        "optional": true,
        "repeats": true
      }
    ],
    "trailing_repeats": true
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "host",
        "reason": "The answer comes from a COM server the host starts. DNA Calc recognises the name and calculates no answer."
      },
      "arity": {
        "max": 255,
        "min": 3
      },
      "category": "Lookup and reference functions",
      "classification": {
        "arg_preparation_profile": "ValuesOnlyPreAdapter",
        "coercion_lift_profile": "Custom",
        "determinism_class": "ExternalEventDependent",
        "error_collapse_profile": "None",
        "fec_dependency_profile": "ExternalProvider",
        "host_interaction_class": "ExternalProvider",
        "kernel_signature_class": "Custom",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "ExternalProvider",
        "thread_safety_class": "HostSerialized",
        "volatility_class": "VolatileContextual"
      },
      "descriptions": {
        "long": null,
        "short": "Live data from a program that supports real-time data (COM automation)",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Retrieves real-time data from a program that supports COM automation",
        "microsoft_url": "https://support.microsoft.com/en-us/office/rtd-function-e0cc001a-56f0-470a-9b19-9455dc0eb593"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "RTD"
        },
        {
          "locale": "bg-BG",
          "name": "RTD"
        },
        {
          "locale": "cs-CZ",
          "name": "RTD"
        },
        {
          "locale": "da-DK",
          "name": "RTD"
        },
        {
          "locale": "de-DE",
          "name": "RTD"
        },
        {
          "locale": "el-GR",
          "name": "RTD"
        },
        {
          "locale": "en-AU",
          "name": "RTD"
        },
        {
          "locale": "en-GB",
          "name": "RTD"
        },
        {
          "locale": "en-US",
          "name": "RTD"
        },
        {
          "locale": "es-ES",
          "name": "RDTR"
        },
        {
          "locale": "et-EE",
          "name": "RTD"
        },
        {
          "locale": "fi-FI",
          "name": "RTD"
        },
        {
          "locale": "fr-FR",
          "name": "RTD*"
        },
        {
          "locale": "he-IL",
          "name": "RTD"
        },
        {
          "locale": "hr-HR",
          "name": "RTD"
        },
        {
          "locale": "hu-HU",
          "name": "VIA"
        },
        {
          "locale": "id-ID",
          "name": "RTD"
        },
        {
          "locale": "it-IT",
          "name": "DATITEMPOREALE"
        },
        {
          "locale": "ja-JP",
          "name": "RTD"
        },
        {
          "locale": "ko-KR",
          "name": "RTD"
        },
        {
          "locale": "lt-LT",
          "name": "RTD"
        },
        {
          "locale": "lv-LV",
          "name": "RTD"
        },
        {
          "locale": "nb-NO",
          "name": "RTD"
        },
        {
          "locale": "nl-NL",
          "name": "RTG"
        },
        {
          "locale": "pl-PL",
          "name": "DANE.CZASU.RZECZ"
        },
        {
          "locale": "pt-BR",
          "name": "RTD"
        },
        {
          "locale": "pt-PT",
          "name": "RTD"
        },
        {
          "locale": "ro-RO",
          "name": "RTD"
        },
        {
          "locale": "ru-RU",
          "name": "ДРВ"
        },
        {
          "locale": "sk-SK",
          "name": "RTD"
        },
        {
          "locale": "sl-SI",
          "name": "RTD"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "RTD"
        },
        {
          "locale": "sv-SE",
          "name": "RTD"
        },
        {
          "locale": "th-TH",
          "name": "RTD"
        },
        {
          "locale": "tr-TR",
          "name": "GZV işlevi"
        },
        {
          "locale": "uk-UA",
          "name": "RTD"
        },
        {
          "locale": "vi-VN",
          "name": "RTD"
        },
        {
          "locale": "zh-CN",
          "name": "RTD"
        },
        {
          "locale": "zh-HK",
          "name": "RTD"
        },
        {
          "locale": "zh-TW",
          "name": "RTD"
        }
      ],
      "signature": {
        "display": "RTD(ProgID, server, topic1, [topic2], ...)",
        "parameters": [
          {
            "description": null,
            "name": "ProgID",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "server",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "topic1",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "topic2",
            "optional": true,
            "repeats": true
          }
        ],
        "trailing_repeats": true
      },
      "surface_name": "RTD",
      "version_marker": null,
      "xlcall": {
        "code": "379",
        "symbol": "xlfRtd"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/rtd-function-e0cc001a-56f0-470a-9b19-9455dc0eb593"
  },
  "try_it": {
    "formula": "=RTD(\"Example.Server\",,\"topic\")",
    "note": "This example needs an Excel service or external provider that OneCalc cannot supply in this preview.",
    "preview_status": "refused"
  },
  "url": "https://handbook.dnacalc.com/functions/RTD.html",
  "variants": [],
  "versions": []
}