Table of Contents

Class Resolution

Namespace
DatabentoDotNet.Historical
Assembly
DatabentoDotNet.Historical.dll

The answer to a symbology.resolve request: what each symbol resolved to, over which dates, and which symbols did not fully resolve.

public sealed record Resolution : IEquatable<Resolution>
Inheritance
Resolution
Implements
Inherited Members

Remarks

Port of upstream's Resolution (symbology.rs:127-142).

Mappings holds every symbol that was asked for, including the ones that resolved to nothing. That is the API's behaviour rather than this port's, and it was verified against hist.databento.com rather than inferred: resolving ESH4,ESM4,NOTAREALSYMBOL returns "result":{"ESH4":[…],"ESM4":[…],"NOTAREALSYMBOL":[]} alongside "not_found":["NOTAREALSYMBOL"]. So ContainsKey(TKey) answers "did I ask for this", never "did this resolve": an empty interval list is what says nothing resolved, and NotFound and Partial are what name the shortfall.

Nothing resolving is not an error. That same response arrived as HTTP 200, with "status": 2, "message": "Not found" in the body — fields upstream's own deserializer ignores and this port ignores with it. No DatabentoApiException is thrown for it, so NotFound is the only signal a caller gets that a symbol was rejected.

Properties

Mappings

Each requested symbol, mapped to the intervals it resolved over — empty for a symbol that resolved to nothing. Interval dates are half-open, as MappingInterval documents.

public required IReadOnlyDictionary<string, IReadOnlyList<MappingInterval>> Mappings { get; init; }

Property Value

IReadOnlyDictionary<string, IReadOnlyList<MappingInterval>>

NotFound

The symbols that did not resolve at all. These appear in Mappings too, with an empty interval list.

public required IReadOnlyList<string> NotFound { get; init; }

Property Value

IReadOnlyList<string>

Partial

The symbols that resolved for part of the requested range but not all of it. These appear in Mappings as well, carrying the intervals they did resolve over.

public required IReadOnlyList<string> Partial { get; init; }

Property Value

IReadOnlyList<string>

Remarks

Unlike the rest of this type's remarks, that second sentence is inferred rather than probed. It follows from result holding a key for every requested symbol, which was verified — including for a symbol that resolved to nothing at all, the harder case. A partial resolution itself could not be produced to check directly: raw symbols resolve across the whole requested window even outside a contract's listed life, and a range starting before a dataset's first day is refused with HTTP 422 rather than partially resolved. The mock covers this bucket with a body marked synthetic for that reason.

StypeIn

The symbology the request's symbols were expressed in.

public required SType StypeIn { get; init; }

Property Value

SType

Remarks

Echoed from the request that produced this resolution, not read from the response. Upstream does the same (symbology.rs:47-48), and it is the right call — but not for the reason it is easy to assume. The response does carry stype_in and stype_out; a live body reads {"result":{…},"symbols":[…],"stype_in":"raw_symbol","stype_out":"instrument_id",…}.

It is echoed anyway because these two values are what makes ToSymbolMap() readable in the right direction, and the request is where the caller's intent actually lives. Reading the server's echo instead would buy nothing and add a way for this object to disagree with the request that produced it.

StypeOut

The symbology the symbols resolved to. Echoed from the request, for the reason StypeIn gives.

public required SType StypeOut { get; init; }

Property Value

SType

Methods

ToSymbolMap()

Builds a timestamped symbol map from this resolution — instrument id and date to text symbol.

public TsSymbolMap ToSymbolMap()

Returns

TsSymbolMap

A map from instrument id and date to the symbol in the other symbology.

Remarks

Port of upstream's Resolution::symbol_map (symbology.rs:150-186). This is the end of the ALL_SYMBOLS workflow FromMetadata(Metadata) starts: a stream that named every instrument by id becomes readable, because the map this returns is the same TsSymbolMap the decoder side already takes.

Which side of a mapping holds the instrument id depends on StypeIn. When the request resolved from instrument ids, the dictionary keys are the ids and the intervals carry the text symbols; otherwise the keys are the text symbols and the intervals carry the ids. A map is always keyed by id, so one of the two is parsed as a number — and which one flips with the request.

Exceptions

FormatException

A value that has to be an instrument id is not a number — the key when StypeIn is InstrumentId, and Symbol otherwise. The message names the offending value.

DbnDecodeException

An interval's StartDate is after its EndDate, which Insert(uint, LocalDate, LocalDate, string) refuses. Two intervals that overlap are not an error: the later insert wins for the shared days, matching how the same map is built from a stream's own metadata.