FixAlchemy.Client (FIXAlchemy v0.2.2)
View SourceGenServer-based FIX protocol session client — the initiator side.
Dials a venue, sends the Logon, and reconnects with backoff when the
connection drops. Everything the session protocol does once bytes are flowing
— framing, sequence numbers, heartbeats, resends, delivery to subscribers —
belongs to FixAlchemy.Engine, which this client owns and drives.
FixAlchemy.Server.Session drives the same engine from the acceptor side.
The engine handles the universal session protocol itself — heartbeats,
TestRequest, reject, resend/sequence-reset — and reports the Logon, the
Logout, and any fatal condition back here. Every other inbound message is routed to
subscribers through a keyed pub/sub bus (FixAlchemy.Dispatch): a process
subscribes to a message type — for all messages of that type, for those where
a tag equals a value, or those where a tag satisfies a predicate — and
receives {:fix, type, raw, meta} for each match. Field decoding happens in
the subscriber, at the point of use, off the socket loop; meta.fields
carries the one framing-level field split the bus already performed for
routing.
Start sessions through FixAlchemy.SessionSupervisor, which supervises this
client alongside the subscriber processes an adapter supplies.
Examples
{:ok, _sup} = FixAlchemy.SessionSupervisor.start_link(
connection_id: "demo",
host: "fix.example.com",
port: 9043,
username: "demo_user",
sender_comp_id: "CLIENT1",
target_comp_id: "SERVER"
)
[{client, _}] = Registry.lookup(FixAlchemy.Registry, {"demo", :trading})
FixAlchemy.Client.subscribe(client, self(), "W", "EUR/USD")
Summary
Functions
Stop re-sending the logon message registered under key.
Returns a specification to start this module under a supervisor.
Whether the session has reached milestone.
Mark that the session has reached milestone, flushing anything waiting on it.
Mark the session ready for business messages; equivalent to reach(conn, :ready).
Register a message, keyed by key, that the engine sends each time the session becomes ready.
Send a FIX message built from {msg_type, fields}.
Send message once the session reaches milestone (immediately if already reached).
Start a FIX client session.
Stop a FIX session, including its subscriber processes.
Subscribe subscriber to a message type on this session.
Remove every subscription held by subscriber on this session.
Types
@type t() :: %FixAlchemy.Client{ connect_timeout: term(), connection_id: term(), default_appl_ver_id: term(), defer_ready: term(), engine: term(), host: term(), password: term(), port: term(), reconnect_attempts: term(), reset_seq_number: term(), session_name: term(), tls: term(), tls_opts: term(), user_on_login: term(), username: term() }
Functions
@spec cancel_logon_send(GenServer.server(), term()) :: :ok
Stop re-sending the logon message registered under key.
Returns a specification to start this module under a supervisor.
See Supervisor.
@spec get_capabilities(GenServer.server()) :: FixAlchemy.Capabilities.t()
@spec milestone_reached?(GenServer.server(), atom()) :: boolean()
Whether the session has reached milestone.
@spec reach(GenServer.server(), atom()) :: :ok
Mark that the session has reached milestone, flushing anything waiting on it.
Milestones name points in a broker's login flow — :ready on FIX logon by
default, plus adapter-defined ones such as :account. Reaching :ready
flushes register_logon_send/3 messages; reaching any milestone flushes the
send_when/3 messages queued for it.
@spec ready(GenServer.server()) :: :ok
Mark the session ready for business messages; equivalent to reach(conn, :ready).
@spec register_logon_send(GenServer.server(), term(), {binary(), list()}) :: :ok
Register a message, keyed by key, that the engine sends each time the session becomes ready.
Never sent before the session is ready (see ready/1), and re-sent after a
reconnect. Re-registering the same key replaces the message; remove it with
cancel_logon_send/2.
@spec send_custom_message( GenServer.server(), {binary(), list()} ) :: :ok
Send a FIX message built from {msg_type, fields}.
Examples
FixAlchemy.Client.send_custom_message(conn, {"D", [{55, "EUR/USD"}, {54, "1"}]})
@spec send_when(GenServer.server(), atom(), {binary(), list()}) :: :ok
Send message once the session reaches milestone (immediately if already reached).
@spec session_key(GenServer.server()) :: {binary(), FixAlchemy.SessionConfig.name()}
@spec start_link(keyword()) :: GenServer.on_start()
Start a FIX client session.
Options
:connection_id- Unique connection identifier (required):host- Server hostname (required):port- Server port (required):username- FIX Username (553), optional; sent only when set:sender_comp_id- Sender component ID (required):target_comp_id- Target component ID (required):password- FIX password (optional):sender_sub_id- SenderSubID (50), sent when set:target_sub_id- TargetSubID (57), sent when set:fix_version- FIX version string (default: "FIX.4.4"):heartbeat_interval- Heartbeat interval in seconds (default: 30):reset_seq_number- Reset sequence on login (default: "Y"):user_on_login- Send username/password in logon message (default: false):validate_checksum- Drop inbound messages with bad checksums (default: false):validate_inbound- Check every inbound message against the dictionary and Reject a bad one (default: false):sequence_recovery- Track inbound MsgSeqNum, request resends on gaps, answer inbound ResendRequests, and honour SequenceReset (default: false):message_store-FixAlchemy.MessageStoreimplementation used to replay sent messages (default:FixAlchemy.MessageStore.Memory):message_store_opts- Options passed to the store'snew/1:routing_keys- Map of message type to routing tag, merged over the dispatch defaults (default:%{}):tls- Connect over TLS (default: false):tls_opts- Extra:ssl.tls_client_option()entries merged over the defaults (verify_peer against the OS trust store, SNI from:host):process_name- Name used as Logger source metadata (default: "")
@spec stop(GenServer.server() | binary()) :: :ok
Stop a FIX session, including its subscriber processes.
Sends a Logout (35=5) before closing when the session is logged in.
@spec subscribe(GenServer.server(), pid(), binary(), binary() | :all, keyword()) :: :ok
Subscribe subscriber to a message type on this session.
subscribe(conn, pid, type)— every message of that typesubscribe(conn, pid, type, value)— where the routing tag equalsvaluesubscribe(conn, pid, type, :all, tag: t, where: fun)— wherefun.(value)
The subscriber receives {:fix, type, raw, meta} for each match, where meta
is %{connection_id, session_name, client, fields}. Subscriptions are pruned
automatically when the subscriber exits.
@spec unsubscribe(GenServer.server(), pid()) :: :ok
Remove every subscription held by subscriber on this session.