Class SecurityMasterClient
- Namespace
- DatabentoDotNet.Reference
- Assembly
- DatabentoDotNet.Reference.dll
The security_master.* endpoints: what a listing is, where it trades, and every identifier
it is known by.
public sealed class SecurityMasterClient
- Inheritance
-
SecurityMasterClient
- Inherited Members
Examples
// Every version of a listing over a window of one of its two timestamps.
await foreach (SecurityMaster version in client.SecurityMaster.GetRangeAsync(
new SecurityMasterGetRangeParams
{
Symbols = Symbols.From("AAPL"),
DateTimeRange = ReferenceDateTimeRange.Between(
Instant.FromUtc(2024, 1, 1, 0, 0), Instant.FromUtc(2024, 2, 1, 0, 0)),
// TsEffective — when the change took effect — rather than TsRecord, when Databento
// recorded it. A late correction lands under a different window depending on which.
Index = SecurityMasterIndex.TsEffective,
// Defaults to true, and on an ISIN-limited plan that can spend quota rather than only
// money. Set it deliberately.
AllocateIsins = false,
}))
{
Console.WriteLine($"{version.TsEffective} {version.Symbol} {version.ListingStatus}");
}
// The latest version only, which takes no window at all.
await foreach (SecurityMaster latest in client.SecurityMaster.GetLastAsync(
new SecurityMasterGetLastParams { Symbols = Symbols.From(["AAPL", "MSFT"]) }))
{
Console.WriteLine($"{latest.Symbol} {latest.Isin} {latest.Figi}");
}
Remarks
Reached through SecurityMaster rather than constructed. Port of
upstream's SecurityMasterClient (security.rs:20-82), which holds a mutable borrow
of the outer client; this holds a reference, there being no borrow checker to satisfy.
Two methods, one row type, and the difference between them is which rows. GetRangeAsync(SecurityMasterGetRangeParams, CancellationToken) asks for every version of a record over a window of one of its two timestamps; GetLastAsync(SecurityMasterGetLastParams, CancellationToken) asks for the latest version and takes no window at all. Both return SecurityMaster.
Both methods bill. Reference data is a separate Databento product, so a 403
here is a legitimate outcome on an account entitled for historical data rather than a
mysterious failure. Both also default to allocating ISINs — see
AllocateIsins, which is the one property in this
group whose default can spend an entitlement rather than only money.
Fields
RequestCompression
The compression both endpoints ask for. Not caller-settable.
public const string RequestCompression = "zstd"
Field Value
Remarks
Upstream hard-codes this (security.rs:40, :70) because the response handler
requires the frame; the two parameter types render it and document why it is a constant
rather than a property. Public and named so a test can assert the value on the wire against
the value the library believes it sends, rather than against a string typed twice — the same
reason RequestCompression is.
Methods
GetLastAsync(SecurityMasterGetLastParams, CancellationToken)
Streams the latest security master record for each security matching
parameters, a row at a time as they decompress.
public IAsyncEnumerable<SecurityMaster> GetLastAsync(SecurityMasterGetLastParams parameters, CancellationToken cancellationToken = default)
Parameters
parametersSecurityMasterGetLastParamsWhich symbols, narrowed how.
cancellationTokenCancellationTokenCancels the request and the enumeration.
Returns
- IAsyncEnumerable<SecurityMaster>
The latest row per security, in the order the server sent them.
Remarks
Port of upstream's get_last (security.rs:62-79).
No range and no index. The endpoint's answer is "the current record", so there is nothing for a window to select — SecurityMasterGetLastParams has no property for either, and the form this posts carries neither key.
Upstream documents this one as sorted by ts_effective and it is not sorted here,
which is #52's decision restated rather than a second one. That sort has no request
counterpart at all — no index is sent, so it is purely a rearrangement of a buffer
upstream had already paid for (security.rs:77). A stream has no buffer to rearrange.
A caller who wants it writes rows.OrderBy(row => row.TsEffective) over the
materialised sequence.
This costs money and defaults to allocating ISINs, exactly as GetRangeAsync(SecurityMasterGetRangeParams, CancellationToken) does, and sends nothing until the enumeration starts for the same reason.
Exceptions
- ArgumentNullException
parametersis null.- InvalidOperationException
parametersleaves Symbols at its type's default value.- DatabentoApiException
The API answered with a non-success status.
GetRangeAsync(SecurityMasterGetRangeParams, CancellationToken)
Streams every security master record matching parameters over the
requested range, a row at a time as they decompress.
public IAsyncEnumerable<SecurityMaster> GetRangeAsync(SecurityMasterGetRangeParams parameters, CancellationToken cancellationToken = default)
Parameters
parametersSecurityMasterGetRangeParamsWhich symbols, over what range of which timestamp.
cancellationTokenCancellationTokenCancels the request and the enumeration.
Returns
- IAsyncEnumerable<SecurityMaster>
One row per security master record, in the order the server sent them.
Remarks
Port of upstream's get_range (security.rs:31-53) — with one deliberate
behavioural difference, below.
This costs money, and it is billed by what it returns. Reference data is a separate
Databento product from historical market data: an API key entitled for one is not
necessarily entitled for the other, and a 403 from this endpoint on an otherwise
working key means exactly that rather than a broken credential. Unlike a batch job, a stream
can be stopped part-way — break out of the await foreach and the response is
disposed on the way out, which is half of why this streams.
Rows arrive in the server's order, and this method does not sort them. Upstream
buffers the whole response into a Vec and then sorts it by whichever timestamp
Index names (security.rs:50-53) — it can,
because it has already paid for the buffer. A stream has not: sorting is what buffering
is, so an IAsyncEnumerable<T> that sorted would be a list wearing a
stream's type. The index is still sent, because it is also what the server filters
on — dropping the sort does not drop the parameter. A caller who needs upstream's order can
have it in one line over the materialised sequence, and pays for the buffer where they can
see it. See ROADMAP.md §6, and
ReadZstdJsonLinesStreamAsync<T>(HttpResponseMessage, JsonTypeInfo<T>, CancellationToken) where
the argument is made in full.
Nothing is sent until the enumeration starts. Calling this method builds a query; the
request goes out on the first MoveNextAsync. A caller who never enumerates never
bills. The argument checks below run at the call rather than at that first step, so a
mistake in them faults where it was made.
Exceptions
- ArgumentNullException
parametersis null.- InvalidOperationException
parametersleaves Symbols or DateTimeRange at its type's default value.- DatabentoApiException
The API answered with a non-success status.