Table of Contents

Class GetRangeParams

Namespace
DatabentoDotNet.Historical
Assembly
DatabentoDotNet.Historical.dll

The parameter set timeseries.get_range takes: what to download, over what range, and named in which symbology.

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

Examples

var request = new GetRangeParams
{
    Dataset = "GLBX.MDP3",
    Symbols = Symbols.From("ESH4"),
    Schema = Schema.Trades,

    // DateRange is half-open, and ToDateTimeRange widens one UTC day to the nanosecond instants
    // this endpoint takes.
    DateTimeRange = DateRange.OnDay(new LocalDate(2024, 1, 2)).ToDateTimeRange(),

    // Part of the priced query, so it lowers the bill as well as the output — which is why it
    // belongs here rather than in a break out of the read loop.
    Limit = 1000,
};

// Price the request you are about to send, not one built a second time by hand.
decimal cost = await client.Metadata.GetCostAsync(request.ToQuery());

await using var reader = await client.Timeseries.GetRangeAsync(request);

Remarks

Port of upstream's GetRangeParams (timeseries.rs:166-199). It is MetadataQueryParams plus a StypeOut — upstream keeps the two types distinct for that one field, and so does this port. #37 found the discrepancy the hard way, while porting symbology.resolve's From<GetRangeParams> conversion: the billing type's own doc comment used to promise it was the set this endpoint takes, and it never was.

ToQuery() is an addition over upstream, not a port of one. There is no From<GetRangeParams> for GetQueryParams anywhere in databento-rs; an upstream caller who wants to price a download builds the billing object by hand. That is the part not worth porting — two hand-built objects that must agree is where a drifted field becomes a wrong quote, and pricing the request you actually send is the whole property MetadataQueryParams exists for. The conversion keeps it, at the cost of one method. See PORTING.md §4.

encoding and compression are not properties, because they are not choices. Upstream hard-codes encoding=dbn and compression=zstd on every request (timeseries.rs:131-134) and so does ToFormParameters(). This client returns a decoder, so DBN is the only encoding it could ask for; zstd is what makes a multi-gigabyte range a reasonable thing to request at all. A caller who wants CSV wants a different library.

Upstream's deprecated per-request upgrade_policy is not ported. It was deprecated in 0.28.0 in favour of the client-level setting, which this library carries as UpgradePolicy. Porting a field upstream tells its own callers not to use would be fidelity to the wrong thing.

Properties

Dataset

The dataset code, for example GLBX.MDP3.

public required string Dataset { get; init; }

Property Value

string

DateTimeRange

The request range: inclusive start, exclusive end.

public required DateTimeRange DateTimeRange { get; init; }

Property Value

DateTimeRange

Remarks

Probed against the live API rather than inherited. Upstream documents the exclusive end at timeseries.rs:175 and it is correct — but #45 was a documented prior that turned out false, so #38 asked the server before repeating this one. An ohlcv-1d bar is stamped at exactly UTC midnight; a one-nanosecond window starting on that instant returns the bar, and a one-nanosecond window ending on it returns nothing. The endpoint also refuses start == end with 422 data_time_range_start_on_or_after_end, exactly as the three billing endpoints do — which is the answer an endpoint reading end as inclusive could not give, since that is how such an endpoint would spell a single instant.

Upstream adds that the filter is on ts_recv where the schema has one and on ts_event otherwise. That half is not probed here: ohlcv schemas carry no ts_recv, so the measurement above pins ts_event only.

Limit

The maximum number of records. Defaults to no limit, in which case the field is omitted from the request rather than sent empty.

public ulong? Limit { get; init; }

Property Value

ulong?

Remarks

Zero is refused here because the API's answer to it is self-contradictory. Upstream's type is Option<NonZeroU64> and C# has no non-zero integer, so the constraint has to live in an initializer either way. What #38 probed is why it is worth enforcing, and it is not the reason that was assumed: sending limit=0 does not request nothing. The response body is byte-identical to the one the same request returns with no limit at all — same records, same metadata — but it additionally carries X-Warning: No data found for the request you submitted.

So the server reads limit=0 as "no limit" on the data path and as "zero records" on the warning path, and the response's header contradicts its own body. HistoricalClient logs X-Warning faithfully, which means a caller who passed zero would see "No data found" logged beside a stream that has data. Refusing the value at construction is the only place that contradiction can be stopped.

Exceptions

ArgumentOutOfRangeException

The value is zero.

Schema

The record schema to download.

public required Schema Schema { get; init; }

Property Value

Schema

StypeIn

The symbology Symbols is expressed in. Defaults to RawSymbol, as upstream's builder does.

public SType StypeIn { get; init; }

Property Value

SType

StypeOut

The symbology the downloaded records name instruments in. Defaults to InstrumentId, as upstream's builder does.

public SType StypeOut { get; init; }

Property Value

SType

Remarks

The field MetadataQueryParams has no equivalent of, and the reason these are two types. It cannot affect a price, a record count or a billable size — it names output, not volume — which is why ToQuery() drops it rather than carrying it into a request that would ignore it.

Symbols

The symbols to download.

public required Symbols Symbols { get; init; }

Property Value

Symbols

Methods

ToFormParameters()

Renders this parameter set as the form body timeseries.get_range posts.

public IReadOnlyList<KeyValuePair<string, string>> ToFormParameters()

Returns

IReadOnlyList<KeyValuePair<string, string>>

The form fields, in upstream's push order.

Remarks

The order is upstream's push order (timeseries.rs:128-138), which is not the order the properties are declared in: encoding and compression sit between schema and the stypes, and stype_in precedes symbols. It makes no difference to the API and it makes the rendered body byte-comparable with upstream's, which is the cheapest way to tell this rendering apart from a plausible one — the same argument ToFormParameters() makes for its own order.

Exceptions

InvalidOperationException

Symbols or DateTimeRange is left at its type's default value. required forces a caller to assign each property but does not stop them assigning default, and the accessors this reads refuse to render one.

ToQuery()

Narrows this to the parameters the three metadata.* billing endpoints take, so a caller can price exactly the request they are about to send.

public MetadataQueryParams ToQuery()

Returns

MetadataQueryParams

The same request, priced rather than downloaded.

Remarks

Drops StypeOut and nothing else. That is not a lossy conversion in any sense that matters to a price: the billing endpoints neither take the field nor could use it, and upstream's own billing type has no room for it (metadata.rs:328-346).

The conversion runs in this direction only. Widening a billing query back into a download would have to invent a StypeOut, and FromQuery(MetadataQueryParams, SType) documents what inventing that value silently does.