C# SDK
FathomCharts handles authentication, the initial snapshot, resuming after a disconnect, duplicates, history pagination, exports and rate-limit retries for you. This page describes every option and method; the behaviour the four SDKs share is in SDKs.
Install
dotnet add package FathomCharts- .NET 8 or later, and .NET Standard 2.0: the package also runs in .NET Framework 4.8 hosts, such as the add-ons of trading platforms.
- Its dependencies are
System.Text.Jsonand a managed zstd decompressor (ZstdSharp.Port); on .NET Standard 2.0,Microsoft.Bcl.AsyncInterfacestoo. Nothing native to install.
Indicator types
dnx FathomCharts.Types https://api.fathomcharts.com/v1/indicators FathomChartsTypes.csdnx comes with the .NET 10 SDK. Otherwise, install the tool once (dotnet tool install -g FathomCharts.Types) and run FathomCharts.Types https://api.fathomcharts.com/v1/indicators FathomChartsTypes.cs. It takes the catalog’s URL or a file saved from GET /v1/indicators.
The file holds, in the namespace FathomCharts.Indicators, one record per indicator for its parameters (BigTradesParams) and one for its data (BigTradesData), with the catalog’s descriptions as XML doc comments; strings with a fixed set of values become enums, and IndicatorIds lists the indicator ids (IndicatorIds.BigTrades). A tuple, such as a footprint level [price, bid, ask, unknown?], is a double[] whose positions its doc comment gives. Generate the file again when the catalog changes.
Real time: FathomChartsStream
using FathomCharts;
using FathomCharts.Indicators;
await using var stream = new FathomChartsStream(new StreamOptions
{
Url = "wss://stream.fathomcharts.com/v1",
ApiKey = Environment.GetEnvironmentVariable("FATHOM_CHARTS_API_KEY"),
OnStateChange = state => Console.WriteLine($"connection {state}"),
});
var bigTrades = stream.Subscribe<BigTradesData>(new SubscribeOptions
{
Instrument = "NQ.front",
Indicator = IndicatorIds.BigTrades,
Params = new BigTradesParams { Minimum = 30 },
Mode = Mode.Confirmed,
});
await foreach (var e in bigTrades)
{
if (e is Upsert<BigTradesData> upsert) Console.WriteLine($"{upsert.Cursor} {upsert.Data.Side} {upsert.Data.Volume}");
}Options
StreamOptions, durations as TimeSpan:
| Option | Purpose |
|---|---|
Url | Required. The stream address: wss://stream.fathomcharts.com/v1. |
ApiKey | API key, sent in the Authorization: Bearer header. |
StreamToken | Instead of ApiKey, in an application distributed to end users, which must not hold the key: a function (CancellationToken → Task<string>) returning a fresh single-use token that your backend gets from POST /v1/stream-tokens (FathomChartsRest.StreamTokenAsync()). It is called on every connection, reconnections included. Give exactly one of ApiKey and StreamToken, otherwise the constructor throws CONFIGURATION. |
WebSocketFactory | Optional: opens the sockets (by default, a ClientWebSocket with the Authorization header), to set a proxy for example. A socket it returns as new StreamSocket(socket, canPause: false) takes the MaxBuffered path below. |
Reconnect | Optional: new ReconnectOptions { InitialDelay, MaxDelay, QuotaRetry, QuotaDelay }: first reconnection delay (250 ms), backoff ceiling (30 s), how long a 4029 close code is retried (120 s), minimum delay between two attempts after a 4029 (5 s). |
HeartbeatTimeout | Silence after which the connection is considered lost, then reopened. 15 s by default: the server sends an hb every 5 seconds. |
HighWaterMark | Number of events waiting to be read, all subscriptions together, above which the SDK stops reading the socket and keeps only the latest version of each object in progress. While it waits, it sends ping messages so that the server keeps the connection. 10,000 by default. |
MaxBuffered | For a socket that cannot be paused: number of waiting events above which the SDK closes the connection (close code 4000, reason client buffer full), then reopens it from the last cursor received once half of HighWaterMark has been read. Nothing waiting is lost. 4 × HighWaterMark by default. |
Random | Optional, for tests: the source of the reconnection jitter, in [0, 1). |
OnStateChange | Called on every change of ConnectionState. |
OnNotice | Called with each Notice from the server (Kind, Id, EffectiveAt, EndsAt, Message): a restart, a maintenance window announced or cancelled. See Updates and maintenance. |
OnStateChange and OnNotice run on the stream’s threads: keep them short. await using (or DisposeAsync(), Close()) closes the stream. stream.ConnectionState is Idle, Connecting, Open, Reconnecting or Closed; stream.Maintenance lists the maintenance windows announced on the connection and not over, by start.
Subscribe()
stream.Subscribe<T>(options) opens a subscription and returns a Subscription<T>, to read with await foreach. SubscribeOptions holds the fields of the subscribe message: Instrument, Indicator, Params (a generated <Name>Params, or any object serialized to JSON), Mode (Mode.Live by default) and From (From.Live by default, From.Cursor(cursor, engine) or From.Time(time)). The SDK picks the sub name itself. T is the indicator’s data type (BigTradesData…); without it, Subscribe(options) gives the data as JsonElement.
The events are records deriving from StreamEvent: Subscribed, Snapshot<T>, Upsert<T>, Remove, Status, Reset and Notice, to test with is or switch. Their fields are those of Events, in Pascal case (TickSizeNanos, LagMs). An error on the subscription ends the loop: await foreach throws a FathomChartsException carrying the received Code.
Subscription
| Member | Purpose |
|---|---|
Cursor | The cursor of the last event handed to you: your resume point. null until a cursor has arrived. It also moves forward with hb messages when no event is waiting to be read. |
Topic | The topic of the latest Subscribed. |
Engine | The engine of the latest Subscribed: the computation your state comes from. Save it with Cursor to resume later. |
Id | The sub name the SDK chose for this subscription (s1, s2…). |
Request | The options of Subscribe(), completed with the default values. |
Close(), DisposeAsync() | Stops the subscription: the SDK sends unsubscribe, and a pending loop ends. |
Leaving the loop (break, return or an exception in its body) closes the subscription. Reconnection, resuming and close codes: see Connection lifecycle; to resume after your process restarts, see Resume after a restart.
History: FathomChartsRest
using var rest = new FathomChartsRest(new RestOptions
{
BaseUrl = "https://api.fathomcharts.com",
ApiKey = Environment.GetEnvironmentVariable("FATHOM_CHARTS_API_KEY"),
});| Option | Purpose |
|---|---|
BaseUrl | Required. The API address: https://api.fathomcharts.com. |
ApiKey | Required. API key, sent in the Authorization: Bearer header. |
HttpClient | Optional: your own HttpClient (proxy, handler…). |
RateLimitRetries | Number of retries of a request the server did not process, or of a read that failed (see Rate limit and retries). 3 by default. |
Methods
Queries are records with the fields of the API, as on the History page: PageQuery (Instrument, Indicator, Params, From, To, Mode, Limit, Cursor, UntilCursor, Snapshot) and RangeQuery for exports. Every method takes a CancellationToken: cancelling a call, or the wait for a retry, throws ABORTED.
| Method | Returns |
|---|---|
PageAsync<T>(query) | One page: Instrument, TickSizeNanos, Snapshot, Items, Next, ComputeUnits. |
PagesAsync<T>(query) | The pages one at a time, following Next, as you read them (await foreach). |
HistoryAsync<T>(query) | The results one at a time, across pages: Mutation<T> (Type is Upsert or Remove, each with its Cursor). With Snapshot = true, a HistorySnapshot<T>, the state at From, comes first. |
EstimateAsync(query) | The cost estimate, charging nothing. |
ExportAsync(query) | One export response: the zstd-compressed file as is, its content type, file name and Token (resumes the export). |
ExportNdjsonAsync(query, options) | The decompressed export, in chunks (ReadOnlyMemory<byte>) of whole lines, with automatic resume. ExportOptions: MaxResumes (5), ResumeDelay (1 s). See Exports. |
StreamTokenAsync() | A stream token: Token, ExpiresAt. |
UsageAsync() | Your usage this month and your limits. |
InstrumentsAsync() | Every instrument served. |
StatusAsync() | The state of the computation, of each instrument, and the maintenance windows announced. |
OffersAsync() | The plans and the limits of each combination. |
IndicatorsAsync() | The indicator catalog. |
Errors
Every error the SDK throws, or ends a loop with, is a FathomChartsException. Its codes are listed in Errors (ErrorCodes; the WebSocket close codes, CloseCode). CONFIGURATION also covers an invalid Url or BaseUrl, and data that does not fit the type T.
| Property | Content |
|---|---|
Code | The stable error code. |
Message | A human-readable explanation. |
Status | The HTTP status, over REST. |
CloseCode | The WebSocket close code, when the connection was closed. |
RetryAfter | The value of the Retry-After header, when the response has one. |
Problem | The full problem+json document of the response, with Errors when the API lists invalid fields; null otherwise. |
InnerException | The original error, when there is one (the cancellation, the error of HttpClient…). |
Cursors
Cursors.Compare("20720.111416.0", "20720.111417.0"); // < 0