SDKs

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

terminal
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.Json and a managed zstd decompressor (ZstdSharp.Port); on .NET Standard 2.0, Microsoft.Bcl.AsyncInterfaces too. Nothing native to install.

Indicator types

terminal
dnx FathomCharts.Types https://api.fathomcharts.com/v1/indicators FathomChartsTypes.cs

dnx 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

Program.cs
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:

OptionPurpose
UrlRequired. The stream address: wss://stream.fathomcharts.com/v1.
ApiKeyAPI key, sent in the Authorization: Bearer header.
StreamTokenInstead 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.
WebSocketFactoryOptional: 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.
ReconnectOptional: 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).
HeartbeatTimeoutSilence after which the connection is considered lost, then reopened. 15 s by default: the server sends an hb every 5 seconds.
HighWaterMarkNumber 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.
MaxBufferedFor 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.
RandomOptional, for tests: the source of the reconnection jitter, in [0, 1).
OnStateChangeCalled on every change of ConnectionState.
OnNoticeCalled 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

MemberPurpose
CursorThe 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.
TopicThe topic of the latest Subscribed.
EngineThe engine of the latest Subscribed: the computation your state comes from. Save it with Cursor to resume later.
IdThe sub name the SDK chose for this subscription (s1, s2…).
RequestThe 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

CSHARP
using var rest = new FathomChartsRest(new RestOptions
{
    BaseUrl = "https://api.fathomcharts.com",
    ApiKey = Environment.GetEnvironmentVariable("FATHOM_CHARTS_API_KEY"),
});
OptionPurpose
BaseUrlRequired. The API address: https://api.fathomcharts.com.
ApiKeyRequired. API key, sent in the Authorization: Bearer header.
HttpClientOptional: your own HttpClient (proxy, handler…).
RateLimitRetriesNumber 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.

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

PropertyContent
CodeThe stable error code.
MessageA human-readable explanation.
StatusThe HTTP status, over REST.
CloseCodeThe WebSocket close code, when the connection was closed.
RetryAfterThe value of the Retry-After header, when the response has one.
ProblemThe full problem+json document of the response, with Errors when the API lists invalid fields; null otherwise.
InnerExceptionThe original error, when there is one (the cancellation, the error of HttpClient…).

Cursors

CSHARP
Cursors.Compare("20720.111416.0", "20720.111417.0"); // < 0