FixAlchemy.MarketData behaviour (FIXAlchemy v0.3.0)

View Source

Base for a per-session market data subscriber.

use FixAlchemy.MarketData gives a GenServer that owns the instrument table for one FIX session. It subscribes to the session's market-data message types (X, W, y, Y) on the FixAlchemy.Client dispatch bus and processes each off the socket loop, so a decode failure or a burst of updates never stalls or kills the FIX session.

Streaming quotes (X), the security list (y), and the historical-candle accumulation over W/Y are all generic. The one venue-specific piece — the fields of the historical MarketDataRequest — is the historical_request_fields/3 callback, which an adapter overrides with @impl FixAlchemy.MarketData.

Summary

Types

A historical candle keyed by unix time with OHLC prices.

Callbacks

Fields of the historical MarketDataRequest (V) for a symbol and window.

What a SecurityList (y) entry says about an instrument, beyond its symbol.

Functions

Parse a MarketDataSnapshotFullRefresh (W) field list into a candle.

Read a published margin requirement as a fraction of a position's value.

Carry what is known about a symbol onto a new quote.

Fetch historical candles over the session by collecting snapshot responses.

The standard FIX reading of a SecurityList entry, used unless an adapter overrides instrument_meta/1.

Types

candle()

@type candle() :: %{
  time: integer(),
  open: float(),
  high: float(),
  low: float(),
  close: float()
}

A historical candle keyed by unix time with OHLC prices.

Callbacks

historical_request_fields(request_id, symbol, opts)

@callback historical_request_fields(
  request_id :: binary(),
  symbol :: binary(),
  opts :: keyword()
) :: [{integer() | atom(), term()}]

Fields of the historical MarketDataRequest (V) for a symbol and window.

instrument_meta(entry)

@callback instrument_meta(entry :: map()) :: map()

What a SecurityList (y) entry says about an instrument, beyond its symbol.

The default reads the standard fields: FIX 4.4 carries MarginRatio (898) in the FinancingDetails component of the NoRelatedSym group, as a percentage expressed decimally. It has no standard field for a tick size, which is why venues that publish one do it in their own tag range and supply it here by overriding.

Keys understood by the platform: :margin_rate (fraction of a position's value) and :point_size.

Functions

candle_from_fields(fields)

@spec candle_from_fields([{binary(), binary()}]) :: candle() | nil

Parse a MarketDataSnapshotFullRefresh (W) field list into a candle.

get_instrument(connection_id, session_name, symbol)

@spec get_instrument(binary(), FixAlchemy.SessionConfig.name(), binary()) ::
  map() | nil

list_instruments(connection_id, session_name)

@spec list_instruments(binary(), FixAlchemy.SessionConfig.name()) :: [binary()]

margin_rate_meta(value)

@spec margin_rate_meta(term()) :: map()

Read a published margin requirement as a fraction of a position's value.

A value above 1 is not a fraction — venues that quote a requirement per contract in account currency use the same field — and converting one needs a contract size, so it is left out rather than read as a percentage.

merge_instrument_meta(instruments, data)

@spec merge_instrument_meta(map(), map()) :: map()

Carry what is known about a symbol onto a new quote.

The quote wins every field it carries, so prices advance; anything the venue said about the symbol and the quote does not repeat, such as :point_size, is kept.

request_historical_candles(connection_id, session_name, symbol, opts)

@spec request_historical_candles(
  binary(),
  FixAlchemy.SessionConfig.name(),
  binary(),
  keyword()
) ::
  {:ok, [candle()]} | {:error, term()}

Fetch historical candles over the session by collecting snapshot responses.

Sends a MarketDataRequest snapshot (via historical_request_fields/3), then accumulates one candle per MarketDataSnapshotFullRefresh (W) until the burst goes quiet. A MarketDataRequestReject (Y) fails it immediately.

Options

  • :timeout - overall deadline in ms (default 20000)
  • plus whatever the adapter's historical_request_fields/3 reads

standard_instrument_meta(entry)

@spec standard_instrument_meta(map()) :: map()

The standard FIX reading of a SecurityList entry, used unless an adapter overrides instrument_meta/1.