FixAlchemy.Backend behaviour (FIXAlchemy v0.2.0)
View SourceBase for a platform trading backend over the FIX engine.
use FixAlchemy.Backend gives a module the full backend API the
platform calls — connect/2, send_order/2, get_positions/1, and the rest —
plus the __backend__/0 marker that makes it auto-discoverable. The baseline
:fix backend is this module's defaults: generic connection fields, the plain
FixAlchemy.{Session,MarketData,Portfolio}.Plain handlers, FixAlchemy.Trading
as the order surface, and readiness on logon.
A broker adapter overrides the callbacks with @impl FixAlchemy.Backend
to change its config schema, handler set, readiness, trading surface, or the
extras it starts per connection — the connection/dispatch plumbing is shared:
defmodule MyBroker.TradingBackend do
use FixAlchemy.Backend
@impl FixAlchemy.Backend
def backend_config, do: %{FixAlchemy.Backend.default_config() | id: :mybroker}
@impl FixAlchemy.Backend
def trading_module, do: MyBroker
end
Summary
Callbacks
Config schema exposed to the platform for connection setup.
Whether sessions defer readiness until the adapter calls Client.ready/1.
Fetch historical candles for a symbol (default: unsupported).
Decimal places a price may carry for an instrument.
Per-session subscriber modules supervised with each client.
Start any per-connection extras once a trading session is up.
Stop any per-connection extras on disconnect.
The order-entry/read module used for this backend.
Functions
The sessions a connection config declares, in declaration order.
The baseline :fix backend config schema.
The generic connection fields shared by every FIX backend.
The sections a connection form lays its shared fields out in, in order.
The repeatable session group of a connection form.
The shared settings of fields a session may override, in declaration order.
Build what config needs before a session using it starts.
Run fun with the client of the session serving role.
Run fun with the name of the session serving role.
Callbacks
@callback backend_config() :: map()
Config schema exposed to the platform for connection setup.
@callback defer_ready?() :: boolean()
Whether sessions defer readiness until the adapter calls Client.ready/1.
@callback get_historical_candles( connection_id :: binary(), symbol :: binary(), opts :: keyword() ) :: {:ok, [map()]} | {:error, term()}
Fetch historical candles for a symbol (default: unsupported).
@callback get_instrument_precision(connection_id :: binary(), symbol :: binary()) :: {:ok, non_neg_integer()} | {:error, term()}
Decimal places a price may carry for an instrument.
The default derives it from the security list's point size (FXCM's
fxcm_sym_point_size). A venue that expresses precision differently overrides
this with @impl FixAlchemy.Backend.
@callback handlers() :: [module()]
Per-session subscriber modules supervised with each client.
Start any per-connection extras once a trading session is up.
Stop any per-connection extras on disconnect.
@callback trading_module() :: module()
The order-entry/read module used for this backend.
Functions
@spec configured_sessions(keyword() | map()) :: [FixAlchemy.SessionConfig.t()]
The sessions a connection config declares, in declaration order.
Delegates to FixAlchemy.SessionConfig.from_connection_config/1: a config
listing sessions under :sessions gets those; one carrying the flat
host/port/sender_comp_id and host_md/port_md/sender_comp_id_md
groups instead gets the sessions :trading and :md those groups describe.
Sessions that are not fully configured are dropped, so an empty list means
the config names no usable session.
@spec default_config() :: map()
The baseline :fix backend config schema.
@spec default_fields() :: [map()]
The generic connection fields shared by every FIX backend.
@spec default_groups() :: [map()]
The sections a connection form lays its shared fields out in, in order.
Every field of default_fields/0 carries the :group it belongs to.
@spec default_session_group() :: map()
The repeatable session group of a connection form.
Each row is one FIX session: the fields it always carries, plus whichever
shared settings it overrides. The overridable settings are not listed here —
a form derives them from the backend's own :fields, taking every one that
does not declare overridable: false, so a backend adding a shared field
makes it overridable by the same act.
The shared settings of fields a session may override, in declaration order.
Every field is overridable unless it declares overridable: false, which a
backend uses for a setting that belongs to the connection as a whole rather
than to any one session.
Build what config needs before a session using it starts.
Generates and caches the dictionaries config names. Repeat calls reuse what
is already built.
Returns {:error, reason} when a named dictionary cannot be built.
Run fun with the client of the session serving role.
The role is resolved through FixAlchemy.SessionDirectory, so a connection
whose sessions are named anything at all is reached by what its sessions are
for. with_client/2 uses the :trading role.
Returns {:error, :not_found} when the connection runs no session,
{:error, {:no_session_for_role, role}} when none serves the role, and
{:error, {:session_not_ready, name}} when the session that does has no live
client.
@spec with_client(binary(), FixAlchemy.SessionConfig.role(), (pid() -> result)) :: result | {:error, term()} when result: term()
@spec with_session( binary(), FixAlchemy.SessionConfig.role(), (FixAlchemy.SessionConfig.name() -> result) ) :: result | {:error, term()} when result: term()
Run fun with the name of the session serving role.
Resolves as with_client/3 does, for callers addressing a session's
subscriber processes rather than its client.