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
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
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
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
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
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.