epam/fix-antenna-net-core/antenna-net-core
Claude Code and agent skill by epam/fix-antenna-net-core
- community
Checking that the SKILL.md file is still in the repository.
This skill should be used when the user asks to "create a FIX session", "build a FIX acceptor", "build a FIX initiator", "send a NewOrderSingle", "handle ExecutionReport", "set up drop copy", "configure fixengine.properties", "implement FIX session recovery", "add a FIX repeating group", or mentions Epam.FixAntenna.NetCore, IFixSession, IFixSessionListener, IFixMessageListener, FixServer, FixMessage, SessionParametersBuilder, ForceSeqNumReset, or FIXT 1.1 in a .NET / C# context. Skip for QuickFIX/n or other FIX libraries — APIs differ.
Install
npx vskill@latest install epam/fix-antenna-net-core/antenna-net-coreSKILL.md
FIX Antenna .NET Core
Guidance for coding agents working in projects that depend on `Epam.FixAntenna.NetCore`. This skill is verified against version 1.2.3.
What FIX Antenna .NET Core is
A high-performance FIX protocol engine for .NET Standard 2.0+, maintained by EPAM / B2Bits, open-sourced under Apache 2.0. It implements FIX 4.0 – 5.0 and FIXT 1.1 session and application layers.
- Repository:
https://github.com/epam/fix-antenna-net-core - NuGet:
Epam.FixAntenna.NetCore - Official docs: <https://github.com/epam/fix-antenna-net-core/tree/main/Docs> — indexed and cross-mapped in
references/official-docs.md. Consult the bundled `references/` first; fetch upstream pages only when the topic isn't covered there (see "When in doubt").
What it is NOT
- Not QuickFIX/n. APIs differ. Do not translate QuickFIX/n samples and rename types — the session model, message construction, and config keys are different.
- Not a broker connectivity SDK. It speaks FIX. It does not normalize venue quirks or ship pre-built drop-in connectors per venue.
- Not an OMS or EMS. It gives session, message, persistence, recovery. Order state machine and business logic are out of scope.
Mental model
Four concepts. Master these or every generation will be wrong.
| Concept | Type(s) | Role | |
|---|---|---|---|
| Configuration | Config, SessionParameters, fixengine.properties | Where session params, storage, TLS live. Prefer file-based for production. | |
| Server / acceptor host | FixServer, IFixServerListener | Listens for inbound connections. Per-session NewFixSession(IFixSession) callback decides accept/reject. | |
| Session | IFixSession | One FIX session. Owns sequence numbers, heartbeats, logon/logout, resend. | |
| Session listener | IFixSessionListener : IFixMessageListener | Implements BOTH OnSessionStateChange(SessionState) (declared on IFixSessionListener) AND OnNewMessage(FixMessage) (inherited from IFixMessageListener). Register via session.SetFixSessionListener(...). Receives application messages only — admin messages (35=A,0,1,2,3,4,5) never reach it. | |
| Admin-message observers (optional) | IFixMessageListener | Session-level (admin) messages are consumed by the engine and NOT passed to the main listener. To observe inbound admin traffic (log Logons, watch 35=3 rejects, recovery flows), register via session.AddInSessionLevelMessageListener(...). | |
| Message | FixMessage : ITagList | Add tags with AddTag(int, value), read with GetTagValueAsString(int) etc. | |
| Tags (constants) | Epam.FixAntenna.Constants.Fix44.Tags | Static class of tag-number const int fields per FIX version. |
⚠️ Inheritance trap.IFixSessionListenerextendsIFixMessageListener. The compiler will demand that any class implementingIFixSessionListenerprovide BOTH methods (OnSessionStateChangeandOnNewMessage). Implement both on the same class. This is true in 1.2.3 and in 2.x master — same shape, different declaration site.
Hard rules — DO and DON'T
These are non-negotiable for production-quality code. Agents repeatedly violate these; this section exists to stop that.
DO
- Use the dictionary. Validate every inbound message against the FIX dictionary. Reject malformed messages at session layer; do not attempt business processing on a structurally invalid message.
- Treat FIX as binary-typed, not text. Read with
FixMessage.GetTagValueAsLong(Fix44.Tags.OrderQty), notint.Parse(message.ToString().Split('|')...). - Separate session handling from business logic.
OnNewMessageshould dispatch to a business handler that does NOT know about FIX wire format. The listener is a boundary. - Use a persistent storage factory in production. Set
storageFactory = Epam.FixAntenna.NetCore.FixEngine.Storage.FilesystemStorageFactory(default, durable) orMmfStorageFactory(memory-mapped, higher throughput). NeverInMemoryStorageFactoryfor a live session — it's for tests. Persistent storage is what makes gap fill / resend / restart recovery work. - Acknowledge state transitions explicitly.
OnSessionStateChangewill be called many times per session lifecycle (WaitingForLogon→LogonReceived→Connected→Disconnected→Reconnecting, etc.). Branch viaSessionState.IsDisconnected(state), not on string compares. - Dispose sessions. Always
session.Dispose()after disconnect. - Know the difference between `AddTag` and `Set`.
AddTag(tag, value)appends a new occurrence — calling it twice for the same tag on the same message yields a malformed (duplicate-tag) outbound.Set(tag, value)(inherited fromExtendedIndexedStorage, available on everyFixMessage) updates the tag in place and adds it if absent — everySetoverload delegates toUpdateValue(..., IndexedStorage.MissingTagHandling.AddIfNotExists), soSetis already the "replace if present, add if missing" call. Reach forUpdateValue(tag, value, IndexedStorage.MissingTagHandling.DontAddIfNotExists)only when you want the opposite — update only if the tag already exists, otherwise leave the message untouched (the call returns-1). (The enum is nested inIndexedStorage— fully-qualify it, orusing static Epam.FixAntenna.NetCore.Message.IndexedStorage;.) UseAddTagfor fresh outbound construction; useSetwhen mutating an existing message (e.g., echoing an inbound back with one field changed). - Engine fills the header and trailer. BeginString (8), BodyLength (9), MsgSeqNum (34), MsgType (35), SenderCompID (49), SendingTime (52), TargetCompID (56), CheckSum (10) are engine-managed.
DON'T
- Don't hardcode sequence numbers. Never write
session.OutSeqNum = 1on every start, never useSetSequenceNumbers(...)from app code unless explicitly implementing manual recovery tooling. The engine and persistent storage manage this; touching it breaks recovery and triggers session-level rejects. - Don't ignore Resend Requests. If a counterparty asks for messages N–M, the engine handles replay automatically if persistent storage is configured. Don't write custom resend logic.
- Don't parse FIX wire format with `Split('|')` or `Split('')`. Use
FixMessage's tag-typed accessors. - Don't treat ExecutionReport as fire-and-forget.
ExecType(150) andOrdStatus(39) define a state machine. - Don't swallow session-level rejects (msg type 3). Means the previous outbound was malformed. Log loudly.
- Don't bypass admin messages. Logon (A), Logout (5), Heartbeat (0), TestRequest (1), ResendRequest (2), SequenceReset (4), Reject (3) are handled by the engine. Don't construct them from app code.
- Don't catch and continue on listener exceptions silently. Log loudly, then either rethrow or disconnect.
- Don't invent enum values.
ForceSeqNumResethas exactly three values:Always,OneTime,Never. There is noOnLogon. - Don't reference `SessionState.LoggedOn`. It does not exist in 1.2.3. The fully-logged-on state is
SessionState.Connected(verify withSessionState.IsConnected(state)).
API surface
The full verified API surface lives in references/api-reference.md: namespaces, session construction (acceptor/initiator/listener), FixMessage read/write, SessionState and ForceSeqNumReset enums, useful SessionParameters properties, the "Other IFixSession methods worth knowing" table, and repeating-group iteration.
Load that reference before generating non-trivial FIX Antenna code. The signatures there were verified by reflection against 1.2.3.
Critical pitfalls captured in references/api-reference.md
- Single-arg `SendMessage(content)` is NOT interchangeable with two-arg `SendMessage(msgType, content)` on a raw
new FixMessage(). With no MsgType (35) it throwsArgumentException: Message type(35 tag) cannot be nullat serialization; with 35 set but no header it serializes without 8/9/34/49/52/56 (header updates useDontAddIfNotExists) and crashes at the storage layer with"Tag 34 is missing or has invalid value". Use the two-arg overload for fresh construction, orPrepareMessage(...). - `IFixSession.Connect()` is polymorphic by role: opens TCP + sends Logon on an initiator; accepts a pending inbound on an acceptor (inside
IFixServerListener.NewFixSession). - `IFixSessionListener` inherits `IFixMessageListener` — implement BOTH
OnSessionStateChangeandOnNewMessageon the same class. - `SessionState.LoggedOn` does not exist. Use
SessionState.Connected/SessionState.IsConnected(state). - `ForceSeqNumReset` values: only `Always`, `OneTime`, `Never`. No
OnLogon. - CompID property casing: `SenderCompId` / `TargetCompId` (lowercase
d) — the properties-file key, in contrast, issenderCompID/targetCompID(uppercase). - `AddTag` appends; `Set` replaces-or-adds. Two
AddTag(sameTag, ...)calls = malformed outbound.Set(tag, value)updates in place and adds the tag if absent (every overload delegates toUpdateValue(..., MissingTagHandling.AddIfNotExists)), soSetis the "replace if present, add if missing" call — don't reach forUpdateValuejust to get that behavior. UseUpdateValue(tag, value, IndexedStorage.MissingTagHandling.DontAddIfNotExists)only for update-only-if-present (returns-1, no-op when absent). The enum is nested inIndexedStorage(namespaceEpam.FixAntenna.NetCore.Message). - Repeating groups on a fresh `FixMessage` require
RawFixUtil.IndexRepeatingGroup(msg, FixVersion.Fix44, "<msgType>")beforeAddRepeatingGroup(leadingTag), otherwise it throws "no info about FIX version in message".
Namespaces (quick)
Configuration: fixengine.properties
The keys documented in this section and inreferences/12-perf-profiles.mdcover the common cases — use them as-is, no lookup needed. For any other key, do not invent it: the complete 1.2.3 key index (every recognized key, default, scope) is bundled inreferences/config-keys.md. The upstream `Docs/Configuration.md` is only needed for long-form prose on a key already found in the index.
The shipped Epam.FixAntenna.NetCore NuGet's SessionParametersBuilder reads a specific property-file layout (verified against epam/fix-antenna-net-core/Samples/ConnectToGateway/fixengine.properties):
- List sessions with the key
sessionIDs(comma-separated). - Per-session properties are prefixed
sessions.<id>.<key>. - Shared defaults can live under
sessions.default.<key>. - The session-type key is `sessionType` with values
initiator|acceptor— NOTconnectionType.
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/antenna-net-core/SKILL.md
Popularity
- Repository stars
- 48
- Repository forks
- 19
- 7-day trend score
- 19
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 30 Jul 2026, 3 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/epam/fix-antenna-net-core/antenna-net-core)