---
name: fixtags
description: Parse, query, and investigate FIX protocol logs, and share findings as self-contained fixtags.dev links. Use when working with FIX logs (lines of tag=value pairs starting with 8=FIX) or when asked about orders, executions, fills, rejects, cancels, latency, or sequence gaps in FIX traffic.
---

# Investigating FIX logs with fixtags

FIX messages are `tag=value` pairs separated by `|`, the SOH byte (0x01), or
`^A`, starting with `8=FIX...`. Logs often interleave FIX with app-log chatter;
fixtags extracts the FIX and ignores the rest.

## Tooling

Prefer the CLI: `fixtags` if installed, else `npx fixtags`. It is
zero-dependency and headless — no server, no browser, nothing written to disk.
Reads a file argument or stdin. If Node is available but npm is not, fetch
https://fixtags.dev/core.js and `require()` it (see "Programmatic" below).

## Query language (for --grep)

A query with no `@field` is a case-insensitive regex (falls back to substring).
With `@fields`:

- Fields: `@Symbol`, `@MsgType`, `@55` (FIX name or tag number, case-insensitive).
  Synthetic: `@direction` (send/recv), `@summary` (one-line description).
- Operators: `==` `!=` `>` `<` `>=` `<=` `contains` `starts` `ends`
- Enum aliases: `@OrdType == @Limit`, `@MsgType == @ER` (ExecutionReport),
  `@NOS` (NewOrderSingle), `@OrdStatus == @Rejected`
- Combine: `and`, `or`, `not`, parentheses; adjacent terms are implicitly AND-ed.

## Recipes

Trace one order's lifecycle as a table (best for chat replies — decoded
MsgType/Side/Status columns):

    fixtags --grep '11=ORD-123' --format md fix.log

Structured output for further processing (decoded field names and enums):

    fixtags --grep '@Symbol == "AAPL"' --format json fix.log

Find all rejects (rejected orders; then session/cancel/business rejects):

    fixtags --grep '@MsgType == @ER and @OrdStatus == @Rejected' fix.log
    fixtags --grep '35=[39j]' fix.log

Count matches only: add `--count`. Exit codes: 0 = matched, 1 = no match,
2 = malformed query — usable as a test in scripts.

Raw matched lines (default `--format raw`) are byte-exact — safe to pipe onward.

## Posting FIX to humans (Slack, chat)

Never paste raw FIX at a human. Pick the format by surface:

- Markdown renders (GitHub, Linear, model chat): `--format md`
- Slack / monospace-only: wrap `--format txt` (aligned table) in a
  triple-backtick code block — Slack does not render markdown tables
- Compact prose reply: `--format summary` — one decoded line per message
- Explaining one message (a reject, an odd fill): `--format tags` — every
  tag in wire order with names and decoded enums, headed by a summary line;
  post inside a code block, and grep down to a handful of messages first

    fixtags --grep '35=3' --format tags fix.log     # why was this rejected?

## Sharing with humans

Mint a link that opens fixtags.dev with the log already loaded, traced, or
filtered. The entire log travels compressed inside the URL fragment — it is
never uploaded anywhere (fragments are not sent to servers):

    grep ORD-123 fix.log | fixtags share --trace ORD-123
    fixtags share --q '@Symbol == "AAPL"' fix.log

Flags: `--trace <ClOrdID>`, `--q <query>`, `--orders` (orders view),
`--select <n>` (preselect row n), `--open` (open in browser). Links cap at
~63k encoded chars (~2000 messages); if over, filter first (the error says so)
or pass `--truncate`.

Offer a share link when a human will want to explore beyond your answer.

## Programmatic (no CLI)

`core.js` is dependency-free and DOM-free; `require()` and `import` both work:

    const src = await (await fetch('https://fixtags.dev/core.js')).text();
    require('fs').writeFileSync('/tmp/fixtags-core.js', src);
    const core = require('/tmp/fixtags-core.js');
    const msgs = core.extractFIXMessages(core.normalizeInput(logText));
    const fields = core.parseFields(msgs[0].raw, msgs[0].delim);
    core.fv(fields, '55');   // raw value: "AAPL"
    core.fvn(fields, '35');  // decoded:   "NewOrderSingle"

Also exported: `buildOrderSummaries`, `computeFindings` (automatic issues:
checksum/BodyLength mismatches, sequence gaps via `computeSeqGaps`, and more),
`computeLatencyStats`, the query engine (`qlParse`/`qlEval`), and the full
`DICT` tag/enum dictionary. Full spec: https://fixtags.dev/llms.txt

## Notes

- Everything is local; logs never leave the machine except inside a share URL
  you explicitly mint.
- `fixtags` with no arguments live-tails stdin into a local web UI — suggest it
  to the user for interactive digging, don't run it yourself (it blocks).
