{
  "schemaVersion": "2.0.0",
  "package": {
    "name": "fintech-algorithms",
    "version": "0.12.0",
    "homepage": "https://docs.thefintechbuilder.com",
    "license": "MIT",
    "type": "module",
    "engines": {
      "node": ">=22"
    },
    "languages": [
      "typescript"
    ],
    "entryPoints": {
      "root": {
        "specifier": "fintech-algorithms",
        "contains": "metadata",
        "note": "The root export carries the topic registry and the lookup helpers (topic, byDomain, byFamily, byArchetype, load, runner). No algorithm is re-exported here."
      },
      "topic": {
        "pattern": "fintech-algorithms/{topic.path}",
        "conditions": [
          "import",
          "require"
        ],
        "note": "Algorithms are subpath-only. Each subpath exports the function named in its `import.entry` and its own types; a sibling topic's function is never re-exported, so import it from its own subpath.",
        "commonjs": "The require condition resolves to the same ES module as import — there is no separate CommonJS build — so require() needs a runtime that supports require(esm)."
      }
    },
    "machineSurface": {
      "site": "https://docs.thefintechbuilder.com",
      "llms": "https://docs.thefintechbuilder.com/llms.txt",
      "versionEndpoint": "https://docs.thefintechbuilder.com/version.json",
      "payload": "https://docs.thefintechbuilder.com/reference/payload.json",
      "domainLlms": "https://docs.thefintechbuilder.com/{domain.slug}/llms.txt",
      "topicPage": "https://docs.thefintechbuilder.com/{topic.path}/",
      "topicMarkdown": "https://docs.thefintechbuilder.com/{topic.path}/index.md",
      "archetypeGuide": "https://docs.thefintechbuilder.com/guides/archetypes/"
    }
  },
  "counts": {
    "topics": 324,
    "domains": 13,
    "families": 54,
    "verified": 158,
    "withExample": 324,
    "withDiagram": 324,
    "withApiContract": 324
  },
  "archetypes": [
    {
      "name": "series-transform",
      "topicCount": 37,
      "firstArgument": "(number | null)[]",
      "returns": "an array of the same length, aligned index-for-index with the input",
      "type": "type SeriesTransform = (values: (number | null)[], ...params: number[]) => (number | null)[];",
      "example": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/sma",
        "entry": "calculateSma",
        "call": "calculateSma([10, 13, 12, 15, 14, 18], 3)",
        "args": [
          [
            10,
            13,
            12,
            15,
            14,
            18
          ],
          3
        ]
      },
      "validator": {
        "subpath": "fintech-algorithms/market-data-engineering/cleaning-and-validation/median-absolute-deviation-outlier-filter",
        "note": "A numeric series has no structure to check, so check its values. Takes the same number[] you are about to pass to the indicator."
      },
      "caveat": "Leading nulls are warm-up, not missing data. The output is the same length as the input so that bars[i] and result[i] describe the same instant; filtering the nulls shifts the series left and nothing errors."
    },
    {
      "name": "tape-aggregate",
      "topicCount": 7,
      "firstArgument": "Trade[]",
      "returns": "Bar[]",
      "type": "type TapeAggregate = (trades: Trade[], config: object) => Bar[];",
      "example": {
        "subpath": "fintech-algorithms/market-data-engineering/bar-construction/time-bars",
        "entry": "constructBars",
        "call": "constructBars(trades, { intervalSeconds: 60, sessionStarts: { RTH: … } })",
        "args": [
          [
            {
              "tradeId": "1",
              "timestamp": "2026-07-20T09:30:01.000Z",
              "session": "RTH",
              "symbol": "DEMO",
              "price": 100,
              "volume": 500,
              "currency": "USD"
            }
          ],
          {
            "intervalSeconds": 60,
            "sessionStarts": {
              "RTH": "2026-07-20T09:30:00.000Z"
            }
          }
        ]
      },
      "validator": {
        "subpath": "fintech-algorithms/market-data-engineering/cleaning-and-validation/duplicate-trade-resolver",
        "note": "Run before aggregating. A duplicated print inflates volume permanently and is invisible once it is inside a bar."
      },
      "caveat": "The only shape that cares about ordering and sessions. Trades must arrive in chronological order, and sessionStarts anchors every bucket boundary — get it wrong and every bar edge is off by the same amount, consistently enough to look correct."
    },
    {
      "name": "row-classify",
      "topicCount": 17,
      "firstArgument": "an array of rows",
      "returns": "one verdict per row, in the same order — verdicts.length === rows.length",
      "type": "type RowClassify = (rows: Row[], config?: object) => Verdict[];",
      "example": {
        "subpath": "fintech-algorithms/market-data-engineering/cleaning-and-validation/ohlc-consistency-validator",
        "entry": "validateBars",
        "call": "validateBars(bars, { tickSize: 0.01, toleranceTicks: 1, priceScale: 1 })",
        "args": [
          [
            {
              "timestamp": "2026-07-20T09:30:00Z",
              "symbol": "DEMO",
              "open": 100,
              "high": 101,
              "low": 99.5,
              "close": 100.5,
              "volume": 1000
            }
          ],
          {
            "tickSize": 0.01,
            "toleranceTicks": 1,
            "priceScale": 1
          }
        ]
      },
      "validator": {
        "subpath": null,
        "note": "This archetype is the boundary. It is what you run before the other four."
      },
      "caveat": "Nothing signals failure except the verdict. These never throw on bad input — one malformed record in ten thousand should lose neither the record nor the other 9,999 — so ignoring the return value looks like success."
    },
    {
      "name": "snapshot-evaluate",
      "topicCount": 6,
      "firstArgument": "one point-in-time snapshot",
      "returns": "a single verdict about that instant",
      "type": "type SnapshotEvaluate = (snapshot: object, policyOrTime: object | string) => Verdict;",
      "example": {
        "subpath": "fintech-algorithms/market-data-engineering/data-quality/price-source-consensus-check",
        "entry": "consensus",
        "call": "consensus({ as_of, quotes }, policy)",
        "args": [
          {
            "as_of": "2026-07-13T13:30:01.000Z",
            "quotes": [
              {
                "source_id": "A",
                "owner_id": "OWNER-A",
                "price": 100,
                "instrument_id": "SYNTH-USD",
                "currency": "USD",
                "price_type": "last_trade",
                "adjustment": "unadjusted",
                "session": "regular",
                "event_time": "2026-07-13T13:30:01.000Z"
              },
              {
                "source_id": "B",
                "owner_id": "OWNER-B",
                "price": 100.01,
                "instrument_id": "SYNTH-USD",
                "currency": "USD",
                "price_type": "last_trade",
                "adjustment": "unadjusted",
                "session": "regular",
                "event_time": "2026-07-13T13:30:01.000Z"
              },
              {
                "source_id": "C",
                "owner_id": "OWNER-C",
                "price": 100.02,
                "instrument_id": "SYNTH-USD",
                "currency": "USD",
                "price_type": "last_trade",
                "adjustment": "unadjusted",
                "session": "regular",
                "event_time": "2026-07-13T13:30:01.000Z"
              }
            ]
          },
          {
            "minimum_independent_sources": 3,
            "z_threshold": 3.5,
            "absolute_tolerance": 0.03,
            "maximum_tolerance": 0.15,
            "max_age_ms": 500,
            "expected_contract": {
              "instrument_id": "SYNTH-USD",
              "currency": "USD",
              "price_type": "last_trade",
              "adjustment": "unadjusted",
              "session": "regular"
            }
          }
        ]
      },
      "validator": {
        "subpath": null,
        "note": "These are themselves validators. Feed them the snapshot you are about to trust."
      },
      "caveat": "The second argument is usually a decision time, and it is what makes the result reproducible. Passing 'now' instead of the instant being evaluated turns a point-in-time check into look-ahead."
    },
    {
      "name": "record-transform",
      "topicCount": 257,
      "firstArgument": "a domain-specific record or array",
      "returns": "a domain-specific result",
      "type": null,
      "example": null,
      "validator": {
        "subpath": null,
        "note": "Whichever matches the record being passed: a bar → ohlc-consistency-validator, a quote → stale-quote-detector, a corporate action → its own family's guard."
      },
      "caveat": "Not a shape. This is the residual bucket — a topic lands here when it is none of the other four — so it spans twelve of the thirteen domains and shares no field names between families. Read the topic's own `api` block and `example` in this payload instead."
    }
  ],
  "domains": [
    {
      "id": "D01",
      "name": "Market Data Engineering",
      "slug": "market-data-engineering",
      "topicCount": 31,
      "families": [
        {
          "id": "D01-F01",
          "name": "Bar Construction",
          "topicCount": 7
        },
        {
          "id": "D01-F02",
          "name": "Cleaning and Validation",
          "topicCount": 6
        },
        {
          "id": "D01-F03",
          "name": "Time Synchronization",
          "topicCount": 5
        },
        {
          "id": "D01-F04",
          "name": "Data Quality",
          "topicCount": 6
        },
        {
          "id": "D01-F05",
          "name": "Order-Book Feed Engineering",
          "topicCount": 7
        }
      ]
    },
    {
      "id": "D02",
      "name": "Corporate Actions and Security Master Data",
      "slug": "corporate-actions-and-security-master-data",
      "topicCount": 20,
      "families": [
        {
          "id": "D02-F01",
          "name": "Adjustment Factors",
          "topicCount": 5
        },
        {
          "id": "D02-F02",
          "name": "Complex Distributions",
          "topicCount": 5
        },
        {
          "id": "D02-F03",
          "name": "Identity Continuity",
          "topicCount": 5
        },
        {
          "id": "D02-F04",
          "name": "Point-in-Time Universe",
          "topicCount": 5
        }
      ]
    },
    {
      "id": "D03",
      "name": "Index and Benchmark Engineering",
      "slug": "index-and-benchmark-engineering",
      "topicCount": 40,
      "families": [
        {
          "id": "D03-F01",
          "name": "Index Initialization and Continuity",
          "topicCount": 5
        },
        {
          "id": "D03-F02",
          "name": "Weighting and Capping",
          "topicCount": 8
        },
        {
          "id": "D03-F03",
          "name": "Alternative Weighting",
          "topicCount": 6
        },
        {
          "id": "D03-F04",
          "name": "Return Variants",
          "topicCount": 7
        },
        {
          "id": "D03-F05",
          "name": "Strategy Indices",
          "topicCount": 6
        },
        {
          "id": "D03-F06",
          "name": "Governance and Maintenance",
          "topicCount": 8
        }
      ]
    },
    {
      "id": "D04",
      "name": "Market Breadth and Internals",
      "slug": "market-breadth-and-internals",
      "topicCount": 28,
      "families": [
        {
          "id": "D04-F01",
          "name": "Advance/Decline Breadth",
          "topicCount": 5
        },
        {
          "id": "D04-F02",
          "name": "McClellan Family",
          "topicCount": 6
        },
        {
          "id": "D04-F03",
          "name": "High/Low and Trend Breadth",
          "topicCount": 6
        },
        {
          "id": "D04-F04",
          "name": "Thrust and Pressure",
          "topicCount": 6
        },
        {
          "id": "D04-F05",
          "name": "Concentration and Diffusion",
          "topicCount": 5
        }
      ]
    },
    {
      "id": "D06",
      "name": "Price Action and Candlesticks",
      "slug": "price-action-and-candlesticks",
      "topicCount": 38,
      "families": [
        {
          "id": "D06-F01",
          "name": "Candle Foundations",
          "topicCount": 5
        },
        {
          "id": "D06-F02",
          "name": "Single-Candle Patterns",
          "topicCount": 9
        },
        {
          "id": "D06-F03",
          "name": "Two-Candle Patterns",
          "topicCount": 8
        },
        {
          "id": "D06-F04",
          "name": "Multi-Candle Patterns",
          "topicCount": 7
        },
        {
          "id": "D06-F05",
          "name": "Candlestick Scanning and Context",
          "topicCount": 9
        }
      ]
    },
    {
      "id": "D07",
      "name": "Technical Indicators",
      "slug": "technical-indicators",
      "topicCount": 37,
      "families": [
        {
          "id": "D07-F01",
          "name": "Trend Smoothing",
          "topicCount": 9
        },
        {
          "id": "D07-F02",
          "name": "Trend Systems",
          "topicCount": 8
        },
        {
          "id": "D07-F03",
          "name": "Momentum",
          "topicCount": 8
        },
        {
          "id": "D07-F04",
          "name": "Volatility and Channels",
          "topicCount": 6
        },
        {
          "id": "D07-F05",
          "name": "Volume Indicators",
          "topicCount": 6
        }
      ]
    },
    {
      "id": "D08",
      "name": "Geometric Chart Patterns",
      "slug": "geometric-chart-patterns",
      "topicCount": 27,
      "families": [
        {
          "id": "D08-F01",
          "name": "Pivots and Levels",
          "topicCount": 4
        },
        {
          "id": "D08-F02",
          "name": "Reversal Structures",
          "topicCount": 6
        },
        {
          "id": "D08-F05",
          "name": "Indicator Divergence Detection",
          "topicCount": 8
        },
        {
          "id": "D08-F06",
          "name": "Level Confluence and Zone Scoring",
          "topicCount": 9
        }
      ]
    },
    {
      "id": "D09",
      "name": "Statistical Time Series",
      "slug": "statistical-time-series",
      "topicCount": 29,
      "families": [
        {
          "id": "D09-F01",
          "name": "Diagnostics",
          "topicCount": 6
        },
        {
          "id": "D09-F02",
          "name": "Forecast Models",
          "topicCount": 6
        },
        {
          "id": "D09-F03",
          "name": "Multivariate Systems",
          "topicCount": 5
        },
        {
          "id": "D09-F04",
          "name": "State and Regime Models",
          "topicCount": 6
        },
        {
          "id": "D09-F05",
          "name": "Decomposition and Cycles",
          "topicCount": 6
        }
      ]
    },
    {
      "id": "D11",
      "name": "Market Microstructure",
      "slug": "market-microstructure",
      "topicCount": 29,
      "families": [
        {
          "id": "D11-F01",
          "name": "Trade Classification",
          "topicCount": 4
        },
        {
          "id": "D11-F02",
          "name": "Liquidity and Spreads",
          "topicCount": 6
        },
        {
          "id": "D11-F03",
          "name": "Order-Flow and Impact",
          "topicCount": 6
        },
        {
          "id": "D11-F04",
          "name": "Order-Book Dynamics",
          "topicCount": 5
        },
        {
          "id": "D11-F05",
          "name": "Market-Depth Analytics",
          "topicCount": 8
        }
      ]
    },
    {
      "id": "D12",
      "name": "Matching Engines and Venue Logic",
      "slug": "matching-engines-and-venue-logic",
      "topicCount": 21,
      "families": [
        {
          "id": "D12-F01",
          "name": "Continuous Matching",
          "topicCount": 4
        },
        {
          "id": "D12-F02",
          "name": "Auctions",
          "topicCount": 5
        },
        {
          "id": "D12-F03",
          "name": "Order Controls",
          "topicCount": 6
        },
        {
          "id": "D12-F04",
          "name": "Order Lifecycle and Queue State",
          "topicCount": 6
        }
      ]
    },
    {
      "id": "D13",
      "name": "Execution and Transaction Cost Analysis",
      "slug": "execution-and-transaction-cost-analysis",
      "topicCount": 9,
      "families": [
        {
          "id": "D13-F01",
          "name": "Schedule-Based Execution",
          "topicCount": 4
        },
        {
          "id": "D13-F02",
          "name": "Cost/Risk Optimization",
          "topicCount": 5
        }
      ]
    },
    {
      "id": "D25",
      "name": "Digital Assets and On-Chain Finance",
      "slug": "digital-assets-and-on-chain-finance",
      "topicCount": 10,
      "families": [
        {
          "id": "D25-F01",
          "name": "AMM Pricing",
          "topicCount": 5
        },
        {
          "id": "D25-F02",
          "name": "Liquidity and Liquidation",
          "topicCount": 5
        }
      ]
    },
    {
      "id": "D46",
      "name": "Earnings and Per-Share Analytics",
      "slug": "earnings-and-per-share-analytics",
      "topicCount": 5,
      "families": [
        {
          "id": "D46-F01",
          "name": "Earnings and Share Foundations",
          "topicCount": 2
        },
        {
          "id": "D46-F02",
          "name": "Basic and Diluted EPS",
          "topicCount": 3
        }
      ]
    }
  ],
  "topics": [
    {
      "id": "D01-F01-A01",
      "name": "Time Bars",
      "headline": null,
      "slug": "time-bars",
      "path": "market-data-engineering/bar-construction/time-bars",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F01",
        "family": "Bar Construction",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/bar-construction/time-bars",
        "entry": "constructBars",
        "params": [
          "trades",
          "config"
        ],
        "exports": [
          "constructBars"
        ],
        "archetype": "tape-aggregate",
        "signature": "constructBars(trades, config)"
      },
      "api": {
        "summary": "Groups a trade tape into fixed-duration bars. This is the sampling scheme every chart you have seen uses, and it is a *choice*: it samples the market at a constant rate regardless of how much is happening in it.",
        "params": [
          {
            "name": "trades",
            "type": "Trade[]",
            "required": true,
            "description": "The raw tape in chronological order. Each trade carries `tradeId`, `timestamp`, `session`, `symbol`, `price`, `volume` and `currency`.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ intervalSeconds: number; sessionStarts: Record<string, string>; closePartial?: boolean; emptyBarPolicy?: \"omit\" }",
            "required": true,
            "description": "`intervalSeconds` sets the bar length. `sessionStarts` maps each session id to its opening timestamp, so bucket boundaries are anchored to the session rather than to the first trade. `closePartial` decides whether a final incomplete bar is emitted. `emptyBarPolicy: \"omit\"` drops intervals with no trades instead of emitting a flat bar.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Bar[]",
          "length": "fewer",
          "description": "One bar per interval that produced trades, carrying open, high, low, close, volume and the interval boundaries."
        },
        "warmup": null,
        "errors": [
          {
            "when": "intervalSeconds is not a positive number",
            "behaviour": "throws"
          },
          {
            "when": "sessionStarts is missing or empty",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(bars)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D01-F01-A01.json",
        "call": "constructBars([{\"tradeId\":\"W1\",\"timestamp\":\"2026-01-05T14:30:00.000Z\",\"session\":\"S1\",\"symbol\":\"SYNTH\",\"price\":100,\"volume\":10,\"currency\":\"USD\"},{\"tradeId\":\"W2\",\"timestamp\":\"2026-01-05T14:30:59.999Z\",\"session\":\"S1\",\"symbol\":\"SYNTH\",\"price\":101,\"volume\":5,\"currency\":\"USD\"},{\"tradeId\":\"W3\",\"timestamp\":\"2026-01-05T14:31:00.000Z\",\"session\":\"S1\",\"symbol\":\"SYNTH\",\"price\":99,\"volume\":8,\"currency\":\"USD\"}], {\"intervalSeconds\":60,\"sessionStarts\":{\"S1\":\"2026-01-05T14:30:00.000Z\"},\"emptyBarPolicy\":\"omit\",\"closePartial\":true})",
        "args": [
          {
            "value": [
              {
                "tradeId": "W1",
                "timestamp": "2026-01-05T14:30:00.000Z",
                "session": "S1",
                "symbol": "SYNTH",
                "price": 100,
                "volume": 10,
                "currency": "USD"
              },
              {
                "tradeId": "W2",
                "timestamp": "2026-01-05T14:30:59.999Z",
                "session": "S1",
                "symbol": "SYNTH",
                "price": 101,
                "volume": 5,
                "currency": "USD"
              },
              {
                "tradeId": "W3",
                "timestamp": "2026-01-05T14:31:00.000Z",
                "session": "S1",
                "symbol": "SYNTH",
                "price": 99,
                "volume": 8,
                "currency": "USD"
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 4
            }
          },
          {
            "value": {
              "intervalSeconds": 60,
              "sessionStarts": {
                "S1": "2026-01-05T14:30:00.000Z"
              },
              "emptyBarPolicy": "omit",
              "closePartial": true
            },
            "elided": null
          }
        ],
        "output": [
          {
            "barIndex": 0,
            "session": "S1",
            "intervalIndex": 0,
            "startTime": "2026-01-05T14:30:00.000Z",
            "endTime": "2026-01-05T14:31:00.000Z",
            "firstTradeTime": "2026-01-05T14:30:00.000Z",
            "lastTradeTime": "2026-01-05T14:30:59.999Z",
            "open": 100,
            "high": 101,
            "low": 100,
            "close": 101,
            "volume": 15,
            "dollarValue": 1505,
            "tickCount": 2
          },
          {
            "barIndex": 1,
            "session": "S1",
            "intervalIndex": 1,
            "startTime": "2026-01-05T14:31:00.000Z",
            "endTime": "2026-01-05T14:32:00.000Z",
            "firstTradeTime": "2026-01-05T14:31:00.000Z",
            "lastTradeTime": "2026-01-05T14:31:00.000Z",
            "open": 99,
            "high": 99,
            "low": 99,
            "close": 99,
            "volume": 8,
            "dollarValue": 792,
            "tickCount": 1
          },
          {
            "barIndex": 2,
            "session": "S1",
            "intervalIndex": 3,
            "startTime": "2026-01-05T14:33:00.000Z",
            "endTime": "2026-01-05T14:34:00.000Z",
            "firstTradeTime": "2026-01-05T14:33:15.000Z",
            "lastTradeTime": "2026-01-05T14:33:15.000Z",
            "open": 102,
            "high": 102,
            "low": 102,
            "close": 102,
            "volume": 2,
            "dollarValue": 204,
            "tickCount": 1
          }
        ],
        "outputElided": null,
        "outputShape": "array of 3 objects"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a01/static/article-hero.svg"
          },
          {
            "file": "boundary-and-state.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a01/static/boundary-and-state.svg"
          },
          {
            "file": "construction-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a01/static/construction-anatomy.svg"
          }
        ],
        "mermaid": [
          {
            "file": "construction-flow.md",
            "caption": "Causal construction flow — Time Bars",
            "source": "flowchart TD\n    A[\"Receive finalized eligible trade\"] --> B{\"New session key?\"}\n    B -->|Yes| C[\"Apply finite-tail policy and reset\"]\n    B -->|No| D[\"Keep current interval\"]\n    C --> E[\"Compute session-relative interval index\"]\n    D --> E\n    E --> F{\"Same interval?\"}\n    F -->|No| G[\"Emit prior nonempty bar\"]\n    F -->|Yes| H[\"Accumulate trade into OHLCV and lineage\"]\n    G --> H\n    H --> A"
          }
        ]
      },
      "references": [
        {
          "key": "R01",
          "title": "NYSE Daily TAQ Client Specification",
          "author": "New York Stock Exchange, an Intercontinental Exchange company",
          "url": "https://www.nyse.com/publicdocs/nyse/data/Daily_TAQ_Client_Spec_v4.3.pdf"
        },
        {
          "key": "R02",
          "title": "Trading Information",
          "author": "New York Stock Exchange",
          "url": "https://www.nyse.com/trade/trading-information"
        },
        {
          "key": "R03",
          "title": "Auctions",
          "author": "New York Stock Exchange",
          "url": "https://www.nyse.com/trade/auctions"
        },
        {
          "key": "R04",
          "title": "Rule 613: Consolidated Audit Trail",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/about/divisions-offices/division-trading-markets/rule-613-consolidated-audit-trail"
        },
        {
          "key": "Evidence and data decision",
          "title": "Evidence and data decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/bar-construction/time-bars/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Time-Bars-Bar-Construction-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/bar-construction/time-bars/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F01-A02",
      "name": "Tick Bars",
      "headline": null,
      "slug": "tick-bars",
      "path": "market-data-engineering/bar-construction/tick-bars",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F01",
        "family": "Bar Construction",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/bar-construction/tick-bars",
        "entry": "constructBars",
        "params": [
          "trades",
          "config"
        ],
        "exports": [
          "constructBars"
        ],
        "archetype": "tape-aggregate",
        "signature": "constructBars(trades, config)"
      },
      "api": {
        "summary": "Closes a bar every N trades rather than every N seconds. Bars then arrive at the rate the market is transacting, so quiet periods produce fewer of them.",
        "params": [
          {
            "name": "trades",
            "type": "Trade[]",
            "required": true,
            "description": "The raw tape in chronological order. Each trade carries `tradeId`, `timestamp`, `session`, `symbol`, `price`, `volume` and `currency`.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ targetTicks: number; closePartial?: boolean }",
            "required": true,
            "description": "`targetTicks` is the trade count that closes a bar. `closePartial` decides whether a final short bar is emitted.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Bar[]",
          "length": "fewer",
          "description": "One bar per completed group of `targetTicks` trades."
        },
        "warmup": null,
        "errors": [
          {
            "when": "targetTicks is not a positive integer",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(bars)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D01-F01-A02.json",
        "call": "constructBars([{\"tradeId\":\"E01\",\"timestamp\":\"2026-01-05T14:30:00.000Z\",\"session\":\"2026-01-05\",\"symbol\":\"SYNTH\",\"price\":100,\"volume\":10,\"currency\":\"USD\"},{\"tradeId\":\"E02\",\"timestamp\":\"2026-01-05T14:30:01.000Z\",\"session\":\"2026-01-05\",\"symbol\":\"SYNTH\",\"price\":101,\"volume\":20,\"currency\":\"USD\"},{\"tradeId\":\"E03\",\"timestamp\":\"2026-01-05T14:30:02.000Z\",\"session\":\"2026-01-05\",\"symbol\":\"SYNTH\",\"price\":99,\"volume\":15,\"currency\":\"USD\"}], {\"targetTicks\":3,\"closePartial\":true})",
        "args": [
          {
            "value": [
              {
                "tradeId": "E01",
                "timestamp": "2026-01-05T14:30:00.000Z",
                "session": "2026-01-05",
                "symbol": "SYNTH",
                "price": 100,
                "volume": 10,
                "currency": "USD"
              },
              {
                "tradeId": "E02",
                "timestamp": "2026-01-05T14:30:01.000Z",
                "session": "2026-01-05",
                "symbol": "SYNTH",
                "price": 101,
                "volume": 20,
                "currency": "USD"
              },
              {
                "tradeId": "E03",
                "timestamp": "2026-01-05T14:30:02.000Z",
                "session": "2026-01-05",
                "symbol": "SYNTH",
                "price": 99,
                "volume": 15,
                "currency": "USD"
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 7
            }
          },
          {
            "value": {
              "targetTicks": 3,
              "closePartial": true
            },
            "elided": null
          }
        ],
        "output": [
          {
            "barIndex": 0,
            "session": "2026-01-05",
            "startTime": "2026-01-05T14:30:00.000Z",
            "endTime": "2026-01-05T14:30:02.000Z",
            "lastTradeTime": "2026-01-05T14:30:02.000Z",
            "open": 100,
            "high": 101,
            "low": 99,
            "close": 99,
            "volume": 45,
            "dollarValue": 4505,
            "tickCount": 3,
            "firstTradeId": "E01",
            "lastTradeId": "E03"
          },
          {
            "barIndex": 1,
            "session": "2026-01-05",
            "startTime": "2026-01-05T14:30:03.000Z",
            "endTime": "2026-01-05T14:30:05.000Z",
            "lastTradeTime": "2026-01-05T14:30:05.000Z",
            "open": 100,
            "high": 102,
            "low": 100,
            "close": 101,
            "volume": 65,
            "dollarValue": 6550,
            "tickCount": 3,
            "firstTradeId": "E04",
            "lastTradeId": "E06"
          },
          {
            "barIndex": 2,
            "session": "2026-01-05",
            "startTime": "2026-01-05T14:30:06.000Z",
            "endTime": "2026-01-05T14:30:06.000Z",
            "lastTradeTime": "2026-01-05T14:30:06.000Z",
            "open": 103,
            "high": 103,
            "low": 103,
            "close": 103,
            "volume": 5,
            "dollarValue": 515,
            "tickCount": 1,
            "firstTradeId": "E07",
            "lastTradeId": "E07"
          }
        ],
        "outputElided": null,
        "outputShape": "array of 3 objects"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a02/static/article-hero.svg"
          },
          {
            "file": "boundary-and-state.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a02/static/boundary-and-state.svg"
          },
          {
            "file": "construction-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a02/static/construction-anatomy.svg"
          }
        ],
        "mermaid": [
          {
            "file": "construction-flow.md",
            "caption": "Causal construction flow — Tick Bars",
            "source": "flowchart TD\n    A[\"Receive next trade in authoritative order\"] --> B{\"New session?\"}\n    B -->|Yes| C[\"Emit or discard partial tail\"]\n    C --> D[\"Reset current bar\"]\n    B -->|No| E[\"Keep current bar\"]\n    D --> F[\"Append the whole trade\"]\n    E --> F\n    F --> G[\"Increment count by one\"]\n    G --> H{\"Count equals targetTicks?\"}\n    H -->|No| A\n    H -->|Yes| I[\"Emit threshold bar with lineage\"]\n    I --> J[\"Reset current bar\"]\n    J --> A"
          }
        ]
      },
      "references": [
        {
          "key": "R01",
          "title": "Advances in Financial Machine Learning, Chapter 1 manuscript",
          "author": "Marcos López de Prado",
          "url": "https://ssrn.com/abstract=3104847"
        },
        {
          "key": "R02",
          "title": "NYSE Daily TAQ Client Specifications",
          "author": "New York Stock Exchange, an Intercontinental Exchange company",
          "url": "https://www.nyse.com/publicdocs/nyse/data/Daily_TAQ_Client_Spec_v4.3.pdf"
        },
        {
          "key": "R03",
          "title": "Trade Reporting Frequently Asked Questions",
          "author": "Financial Industry Regulatory Authority",
          "url": "https://www.finra.org/filing-reporting/market-transparency-reporting/trade-reporting-faq"
        },
        {
          "key": "R04",
          "title": "MIDAS: Market Information Data Analytics System",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/securities-topics/market-structure-analytics/midas-market-information-data-analytics-system"
        },
        {
          "key": "Evidence and data decision",
          "title": "Evidence and data decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/bar-construction/tick-bars/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Tick-Bars-Bar-Construction-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/bar-construction/tick-bars/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F01-A03",
      "name": "Volume Bars",
      "headline": null,
      "slug": "volume-bars",
      "path": "market-data-engineering/bar-construction/volume-bars",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F01",
        "family": "Bar Construction",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/bar-construction/volume-bars",
        "entry": "constructBars",
        "params": [
          "trades",
          "config"
        ],
        "exports": [
          "constructBars"
        ],
        "archetype": "tape-aggregate",
        "signature": "constructBars(trades, config)"
      },
      "api": {
        "summary": "Closes a bar once a target share volume has traded. Sampling by volume rather than by clock gives series with far more stable statistical properties than time bars.",
        "params": [
          {
            "name": "trades",
            "type": "Trade[]",
            "required": true,
            "description": "The raw tape in chronological order. Each trade carries `tradeId`, `timestamp`, `session`, `symbol`, `price`, `volume` and `currency`.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ targetVolume: number; closePartial?: boolean }",
            "required": true,
            "description": "`targetVolume` is the cumulative share volume that closes a bar. A single trade larger than the target closes a bar on its own. `closePartial` decides whether a final short bar is emitted.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Bar[]",
          "length": "fewer",
          "description": "One bar per completed volume bucket."
        },
        "warmup": null,
        "errors": [
          {
            "when": "targetVolume is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(bars)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D01-F01-A03.json",
        "call": "constructBars([{\"tradeId\":\"W001\",\"timestamp\":\"2026-01-05T14:30:00.000Z\",\"session\":\"2026-01-05\",\"symbol\":\"SYNTH\",\"price\":100,\"volume\":400,\"currency\":\"USD\"},{\"tradeId\":\"W002\",\"timestamp\":\"2026-01-05T14:30:01.000Z\",\"session\":\"2026-01-05\",\"symbol\":\"SYNTH\",\"price\":101,\"volume\":350,\"currency\":\"USD\"},{\"tradeId\":\"W003\",\"timestamp\":\"2026-01-05T14:30:02.000Z\",\"session\":\"2026-01-05\",\"symbol\":\"SYNTH\",\"price\":99,\"volume\":500,\"currency\":\"USD\"}], {\"targetVolume\":1000,\"closePartial\":true})",
        "args": [
          {
            "value": [
              {
                "tradeId": "W001",
                "timestamp": "2026-01-05T14:30:00.000Z",
                "session": "2026-01-05",
                "symbol": "SYNTH",
                "price": 100,
                "volume": 400,
                "currency": "USD"
              },
              {
                "tradeId": "W002",
                "timestamp": "2026-01-05T14:30:01.000Z",
                "session": "2026-01-05",
                "symbol": "SYNTH",
                "price": 101,
                "volume": 350,
                "currency": "USD"
              },
              {
                "tradeId": "W003",
                "timestamp": "2026-01-05T14:30:02.000Z",
                "session": "2026-01-05",
                "symbol": "SYNTH",
                "price": 99,
                "volume": 500,
                "currency": "USD"
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 6
            }
          },
          {
            "value": {
              "targetVolume": 1000,
              "closePartial": true
            },
            "elided": null
          }
        ],
        "output": [
          {
            "barIndex": 0,
            "session": "2026-01-05",
            "startTime": "2026-01-05T14:30:00.000Z",
            "endTime": "2026-01-05T14:30:02.000Z",
            "lastTradeTime": "2026-01-05T14:30:02.000Z",
            "open": 100,
            "high": 101,
            "low": 99,
            "close": 99,
            "volume": 1250,
            "dollarValue": 124850,
            "tickCount": 3,
            "firstTradeId": "W001",
            "lastTradeId": "W003"
          },
          {
            "barIndex": 1,
            "session": "2026-01-05",
            "startTime": "2026-01-05T14:30:03.000Z",
            "endTime": "2026-01-05T14:30:04.000Z",
            "lastTradeTime": "2026-01-05T14:30:04.000Z",
            "open": 99.5,
            "high": 100.5,
            "low": 99.5,
            "close": 100.5,
            "volume": 1000,
            "dollarValue": 99900,
            "tickCount": 2,
            "firstTradeId": "W004",
            "lastTradeId": "W005"
          },
          {
            "barIndex": 2,
            "session": "2026-01-05",
            "startTime": "2026-01-05T14:30:05.000Z",
            "endTime": "2026-01-05T14:30:05.000Z",
            "lastTradeTime": "2026-01-05T14:30:05.000Z",
            "open": 101,
            "high": 101,
            "low": 101,
            "close": 101,
            "volume": 250,
            "dollarValue": 25250,
            "tickCount": 1,
            "firstTradeId": "W006",
            "lastTradeId": "W006"
          }
        ],
        "outputElided": null,
        "outputShape": "array of 3 objects"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a03/static/article-hero.svg"
          },
          {
            "file": "boundary-and-state.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a03/static/boundary-and-state.svg"
          },
          {
            "file": "construction-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a03/static/construction-anatomy.svg"
          }
        ],
        "mermaid": [
          {
            "file": "construction-flow.md",
            "caption": "Causal construction flow - Volume Bars",
            "source": "flowchart TD\n    A[\"Receive next cleaned eligible trade\"] --> B{\"New session?\"}\n    B -->|Yes| C[\"Apply partial-tail policy; reset to zero\"]\n    B -->|No| D[\"Keep open bar\"]\n    C --> E[\"Add the whole trade\"]\n    D --> E\n    E --> F{\"Cumulative shares >= target?\"}\n    F -->|No| A\n    F -->|Yes| G[\"Emit OHLCV, close reason, and lineage\"]\n    G --> H[\"Reset to zero; do not carry overshoot\"]\n    H --> A"
          }
        ]
      },
      "references": [
        {
          "key": "R01 - Advances in Financial Machine Learning, Chapter 1",
          "title": "R01 - Advances in Financial Machine Learning, Chapter 1",
          "author": "Marcos Lopez de Prado",
          "url": "https://ssrn.com/abstract=3104847"
        },
        {
          "key": "R02 - NYSE Daily TAQ Client Specification",
          "title": "R02 - NYSE Daily TAQ Client Specification",
          "author": "New York Stock Exchange, an Intercontinental Exchange company",
          "url": "https://www.nyse.com/publicdocs/nyse/data/Daily_TAQ_Client_Spec_v4.3.pdf"
        },
        {
          "key": "R03 - Trade Reporting Frequently Asked Questions",
          "title": "R03 - Trade Reporting Frequently Asked Questions",
          "author": "Financial Industry Regulatory Authority",
          "url": "https://www.finra.org/filing-reporting/market-transparency-reporting/trade-reporting-faq"
        },
        {
          "key": "R04 - MIDAS: Market Information Data Analytics System",
          "title": "R04 - MIDAS: Market Information Data Analytics System",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/securities-topics/market-structure-analytics/midas-market-information-data-analytics-system"
        },
        {
          "key": "Evidence and data note",
          "title": "Evidence and data note",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/bar-construction/volume-bars/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Volume-Bars-Bar-Construction-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/bar-construction/volume-bars/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F01-A04",
      "name": "Dollar Bars",
      "headline": null,
      "slug": "dollar-bars",
      "path": "market-data-engineering/bar-construction/dollar-bars",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F01",
        "family": "Bar Construction",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/bar-construction/dollar-bars",
        "entry": "constructBars",
        "params": [
          "trades",
          "config"
        ],
        "exports": [
          "constructBars"
        ],
        "archetype": "tape-aggregate",
        "signature": "constructBars(trades, config)"
      },
      "api": {
        "summary": "Closes a bar once a target traded *value* is reached. Unlike volume bars this stays comparable as the price level changes — 1,000 shares of a $10 stock and of a $500 stock are not the same event.",
        "params": [
          {
            "name": "trades",
            "type": "Trade[]",
            "required": true,
            "description": "The raw tape in chronological order. Each trade carries `tradeId`, `timestamp`, `session`, `symbol`, `price`, `volume` and `currency`.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ targetDollar: number; currency: string; priceDecimals?: number; quantityDecimals?: number; closePartial?: boolean }",
            "required": true,
            "description": "`targetDollar` is the notional that closes a bar and `currency` the unit it is denominated in. The two decimal settings fix the rounding used when accumulating price × quantity, so the same tape gives the same bars on any machine.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Bar[]",
          "length": "fewer",
          "description": "One bar per completed notional bucket."
        },
        "warmup": null,
        "errors": [
          {
            "when": "targetDollar is not positive",
            "behaviour": "throws"
          },
          {
            "when": "a trade's currency does not match the configured currency",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(bars)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D01-F01-A04.json",
        "call": "constructBars([{\"tradeId\":\"W1\",\"timestamp\":\"2026-01-05T14:30:00.000Z\",\"session\":\"2026-01-05\",\"symbol\":\"SYNTH\",\"price\":100,\"volume\":40,\"currency\":\"USD\"},{\"tradeId\":\"W2\",\"timestamp\":\"2026-01-05T14:30:01.000Z\",\"session\":\"2026-01-05\",\"symbol\":\"SYNTH\",\"price\":90,\"volume\":70,\"currency\":\"USD\"}], {\"targetDollar\":10000,\"currency\":\"USD\",\"priceDecimals\":2,\"quantityDecimals\":0,\"closePartial\":true})",
        "args": [
          {
            "value": [
              {
                "tradeId": "W1",
                "timestamp": "2026-01-05T14:30:00.000Z",
                "session": "2026-01-05",
                "symbol": "SYNTH",
                "price": 100,
                "volume": 40,
                "currency": "USD"
              },
              {
                "tradeId": "W2",
                "timestamp": "2026-01-05T14:30:01.000Z",
                "session": "2026-01-05",
                "symbol": "SYNTH",
                "price": 90,
                "volume": 70,
                "currency": "USD"
              }
            ],
            "elided": null
          },
          {
            "value": {
              "targetDollar": 10000,
              "currency": "USD",
              "priceDecimals": 2,
              "quantityDecimals": 0,
              "closePartial": true
            },
            "elided": null
          }
        ],
        "output": [
          {
            "barIndex": 0,
            "session": "2026-01-05",
            "symbol": "SYNTH",
            "currency": "USD",
            "startTime": "2026-01-05T14:30:00.000Z",
            "endTime": "2026-01-05T14:30:01.000Z",
            "lastTradeTime": "2026-01-05T14:30:01.000Z",
            "open": 100,
            "high": 100,
            "low": 90,
            "close": 90,
            "volume": 110,
            "dollarValue": 10300,
            "targetDollar": 10000
          }
        ],
        "outputElided": null,
        "outputShape": "array of 1 object"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a04/static/article-hero.svg"
          },
          {
            "file": "boundary-and-state.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a04/static/boundary-and-state.svg"
          },
          {
            "file": "construction-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a04/static/construction-anatomy.svg"
          }
        ],
        "mermaid": [
          {
            "file": "construction-flow.md",
            "caption": "Causal construction flow — Dollar Bars",
            "source": "flowchart TD\n    A[\"Receive corrected, eligible trade\"] --> B[\"Validate symbol, currency, units, time, and tie sequence\"]\n    B --> C{\"New session?\"}\n    C -->|Yes| D{\"Keep partial tails?\"}\n    D -->|Yes| E[\"Emit prior session partial\"]\n    D -->|No| F[\"Discard prior session partial\"]\n    E --> G[\"Reset exact cumulative state\"]\n    F --> G\n    C -->|No| H[\"Keep open-bar state\"]\n    G --> I[\"Add whole trade: scaled price × scaled quantity\"]\n    H --> I\n    I --> J{\"Cumulative notional ≥ target?\"}\n    J -->|No| A\n    J -->|Yes| K[\"Emit complete bar, lineage, and excess\"]\n    K --> L[\"Reset open-bar state\"]\n    L --> A"
          }
        ]
      },
      "references": [
        {
          "key": "R01",
          "title": "Advances in Financial Machine Learning, Chapter 1 manuscript",
          "author": "Marcos López de Prado",
          "url": "https://ssrn.com/abstract=3104847"
        },
        {
          "key": "R02",
          "title": "NYSE Daily TAQ Client Specification v4.3",
          "author": "New York Stock Exchange, an Intercontinental Exchange company",
          "url": "https://www.nyse.com/publicdocs/nyse/data/Daily_TAQ_Client_Spec_v4.3.pdf"
        },
        {
          "key": "R03",
          "title": "Trade Reporting Frequently Asked Questions",
          "author": "Financial Industry Regulatory Authority (FINRA)",
          "url": "https://www.finra.org/filing-reporting/market-transparency-reporting/trade-reporting-faq"
        },
        {
          "key": "Evidence classification",
          "title": "Evidence classification",
          "author": null,
          "url": null
        },
        {
          "key": "Data and historical-case note",
          "title": "Data and historical-case note",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/bar-construction/dollar-bars/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Dollar-Bars-Bar-Construction-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/bar-construction/dollar-bars/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F01-A05",
      "name": "Tick-Imbalance Bars",
      "headline": null,
      "slug": "tick-imbalance-bars",
      "path": "market-data-engineering/bar-construction/tick-imbalance-bars",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F01",
        "family": "Bar Construction",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/bar-construction/tick-imbalance-bars",
        "entry": "constructBars",
        "params": [
          "trades",
          "config"
        ],
        "exports": [
          "constructBars"
        ],
        "archetype": "tape-aggregate",
        "signature": "constructBars(trades, config)"
      },
      "api": {
        "summary": "Closes a bar when signed tick flow becomes unusually one-sided relative to what recent history led you to expect. Bars are emitted on *information* rather than on elapsed time or traded quantity.",
        "params": [
          {
            "name": "trades",
            "type": "Trade[]",
            "required": true,
            "description": "The raw tape in chronological order. Each trade carries `tradeId`, `timestamp`, `session`, `symbol`, `price`, `volume` and `currency`.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ initialTickSign: number; initialExpectedTicks: number; initialExpectedTickImbalance: number; alphaTicks: number; alphaTickImbalance: number; thresholdFloor: number; thresholdMultiplier: number; closePartial?: boolean }",
            "required": true,
            "description": "The `initial*` values seed the expectations before any bar has closed; the `alpha*` values are the EWMA decay rates that update them afterwards. `thresholdFloor` and `thresholdMultiplier` bound the resulting threshold so it cannot collapse toward zero in quiet periods.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Bar[]",
          "length": "fewer",
          "description": "One bar per imbalance event, with the threshold that triggered it recorded on the bar."
        },
        "warmup": null,
        "errors": [
          {
            "when": "any alpha falls outside 0…1, or a seed expectation is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(bars)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D01-F01-A05.json",
        "call": "constructBars([{\"tradeId\":\"W1\",\"timestamp\":\"2026-01-05T14:30:00.000Z\",\"session\":\"2026-01-05\",\"symbol\":\"SYNTH\",\"price\":100,\"volume\":10,\"currency\":\"USD\"},{\"tradeId\":\"W2\",\"timestamp\":\"2026-01-05T14:30:01.000Z\",\"session\":\"2026-01-05\",\"symbol\":\"SYNTH\",\"price\":100,\"volume\":10,\"currency\":\"USD\"},{\"tradeId\":\"W3\",\"timestamp\":\"2026-01-05T14:30:02.000Z\",\"session\":\"2026-01-05\",\"symbol\":\"SYNTH\",\"price\":100.1,\"volume\":10,\"currency\":\"USD\"}], {\"closePartial\":true,\"initialTickSign\":1,\"initialExpectedTicks\":8,\"initialExpectedTickImbalance\":0.5,\"alphaTicks\":0.25,\"alphaTickImbalance\":0.5,\"thresholdFloor\":3,\"thresholdMultiplier\":1})",
        "args": [
          {
            "value": [
              {
                "tradeId": "W1",
                "timestamp": "2026-01-05T14:30:00.000Z",
                "session": "2026-01-05",
                "symbol": "SYNTH",
                "price": 100,
                "volume": 10,
                "currency": "USD"
              },
              {
                "tradeId": "W2",
                "timestamp": "2026-01-05T14:30:01.000Z",
                "session": "2026-01-05",
                "symbol": "SYNTH",
                "price": 100,
                "volume": 10,
                "currency": "USD"
              },
              {
                "tradeId": "W3",
                "timestamp": "2026-01-05T14:30:02.000Z",
                "session": "2026-01-05",
                "symbol": "SYNTH",
                "price": 100.1,
                "volume": 10,
                "currency": "USD"
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 6
            }
          },
          {
            "value": {
              "closePartial": true,
              "initialTickSign": 1,
              "initialExpectedTicks": 8,
              "initialExpectedTickImbalance": 0.5,
              "alphaTicks": 0.25,
              "alphaTickImbalance": 0.5,
              "thresholdFloor": 3,
              "thresholdMultiplier": 1
            },
            "elided": null
          }
        ],
        "output": [
          {
            "barIndex": 0,
            "session": "2026-01-05",
            "startTime": "2026-01-05T14:30:00.000Z",
            "endTime": "2026-01-05T14:30:05.000Z",
            "lastTradeTime": "2026-01-05T14:30:05.000Z",
            "open": 100,
            "high": 100.15,
            "low": 100,
            "close": 100.15,
            "volume": 60,
            "dollarValue": 6004,
            "tickCount": 6,
            "firstTradeId": "W1",
            "lastTradeId": "W6"
          }
        ],
        "outputElided": null,
        "outputShape": "array of 1 object"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a05/static/article-hero.svg"
          },
          {
            "file": "boundary-and-state.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a05/static/boundary-and-state.svg"
          },
          {
            "file": "construction-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a05/static/construction-anatomy.svg"
          }
        ],
        "mermaid": [
          {
            "file": "construction-flow.md",
            "caption": "Causal construction flow",
            "source": "flowchart TD\n    A[\"Corrected, eligible, stably ordered trade\"] --> B{\"New session?\"}\n    B -->|Yes| C[\"Emit or drop tail; reset price, sign, and expectations\"]\n    B -->|No| D[\"Keep session state\"]\n    C --> E[\"Freeze threshold for new bar\"]\n    D --> F[\"Assign tick sign; flat carries prior sign\"]\n    E --> F\n    F --> G[\"Update OHLCV and cumulative tick imbalance\"]\n    G --> H{\"Absolute imbalance at least frozen threshold?\"}\n    H -->|No| A\n    H -->|Yes| I[\"Emit complete bar and lineage\"]\n    I --> J[\"Update expected length and expected mean sign\"]\n    J --> E"
          }
        ]
      },
      "references": [
        {
          "key": "R01",
          "title": "*Advances in Financial Machine Learning*, Section 2.3.2.1",
          "author": "Marcos López de Prado",
          "url": "https://uat.store.wiley.com/en-us/advances-in-financial-machine-learning-p-9781119482109"
        },
        {
          "key": "R02",
          "title": "NYSE Daily TAQ Client Specification",
          "author": "New York Stock Exchange, an Intercontinental Exchange company",
          "url": "https://www.nyse.com/publicdocs/nyse/data/Daily_TAQ_Client_Spec_v4.3.pdf"
        },
        {
          "key": "R03",
          "title": "Trade Reporting Frequently Asked Questions",
          "author": "Financial Industry Regulatory Authority",
          "url": "https://www.finra.org/filing-reporting/market-transparency-reporting/trade-reporting-faq"
        },
        {
          "key": "Evidence classification",
          "title": "Evidence classification",
          "author": null,
          "url": null
        },
        {
          "key": "Data and licensing note",
          "title": "Data and licensing note",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/bar-construction/tick-imbalance-bars/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Tick-Imbalance-Bars-Bar-Construction-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/bar-construction/tick-imbalance-bars/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F01-A06",
      "name": "Volume-Imbalance Bars",
      "headline": null,
      "slug": "volume-imbalance-bars",
      "path": "market-data-engineering/bar-construction/volume-imbalance-bars",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F01",
        "family": "Bar Construction",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/bar-construction/volume-imbalance-bars",
        "entry": "constructBars",
        "params": [
          "trades",
          "config"
        ],
        "exports": [
          "constructBars"
        ],
        "archetype": "tape-aggregate",
        "signature": "constructBars(trades, config)"
      },
      "api": {
        "summary": "The imbalance rule applied to signed *volume* rather than signed tick count, so one large order weighs more than many small ones pointing the same way.",
        "params": [
          {
            "name": "trades",
            "type": "Trade[]",
            "required": true,
            "description": "The raw tape in chronological order. Each trade carries `tradeId`, `timestamp`, `session`, `symbol`, `price`, `volume` and `currency`.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ initialTickSign: number; initialExpectedTicks: number; initialExpectedSignedVolume: number; alphaTicks: number; alphaSignedVolume: number; thresholdFloorShares: number; thresholdScale: number; closePartial?: boolean }",
            "required": true,
            "description": "As for tick-imbalance bars, but the tracked quantity is signed volume. `thresholdFloorShares` is the floor in shares, and `thresholdScale` multiplies the expectation to form the trigger.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Bar[]",
          "length": "fewer",
          "description": "One bar per signed-volume imbalance event."
        },
        "warmup": null,
        "errors": [
          {
            "when": "any alpha falls outside 0…1, or a seed expectation is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(bars)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D01-F01-A06.json",
        "call": "constructBars([{\"tradeId\":\"W01\",\"timestamp\":\"2026-01-05T14:30:00.000Z\",\"session\":\"2026-01-05\",\"symbol\":\"SYNTH\",\"price\":100,\"volume\":60,\"currency\":\"USD\"},{\"tradeId\":\"W02\",\"timestamp\":\"2026-01-05T14:30:00.000Z\",\"session\":\"2026-01-05\",\"symbol\":\"SYNTH\",\"price\":100,\"volume\":40,\"currency\":\"USD\"},{\"tradeId\":\"W03\",\"timestamp\":\"2026-01-05T14:30:01.000Z\",\"session\":\"2026-01-05\",\"symbol\":\"SYNTH\",\"price\":99.99,\"volume\":70,\"currency\":\"USD\"}], {\"closePartial\":true,\"initialTickSign\":1,\"initialExpectedTicks\":4,\"initialExpectedSignedVolume\":50,\"alphaTicks\":0.25,\"alphaSignedVolume\":0.25,\"thresholdFloorShares\":120,\"thresholdScale\":1})",
        "args": [
          {
            "value": [
              {
                "tradeId": "W01",
                "timestamp": "2026-01-05T14:30:00.000Z",
                "session": "2026-01-05",
                "symbol": "SYNTH",
                "price": 100,
                "volume": 60,
                "currency": "USD"
              },
              {
                "tradeId": "W02",
                "timestamp": "2026-01-05T14:30:00.000Z",
                "session": "2026-01-05",
                "symbol": "SYNTH",
                "price": 100,
                "volume": 40,
                "currency": "USD"
              },
              {
                "tradeId": "W03",
                "timestamp": "2026-01-05T14:30:01.000Z",
                "session": "2026-01-05",
                "symbol": "SYNTH",
                "price": 99.99,
                "volume": 70,
                "currency": "USD"
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 8
            }
          },
          {
            "value": {
              "closePartial": true,
              "initialTickSign": 1,
              "initialExpectedTicks": 4,
              "initialExpectedSignedVolume": 50,
              "alphaTicks": 0.25,
              "alphaSignedVolume": 0.25,
              "thresholdFloorShares": 120,
              "thresholdScale": 1
            },
            "elided": null
          }
        ],
        "output": [
          {
            "barIndex": 0,
            "session": "2026-01-05",
            "startTime": "2026-01-05T14:30:00.000Z",
            "endTime": "2026-01-05T14:30:04.000Z",
            "open": 100,
            "high": 100,
            "low": 99.97,
            "close": 99.97,
            "volume": 405,
            "dollarValue": 40493.65,
            "tickCount": 6,
            "firstTradeId": "W01",
            "lastTradeId": "W06",
            "closeReason": "threshold"
          },
          {
            "barIndex": 1,
            "session": "2026-01-05",
            "startTime": "2026-01-05T14:30:05.000Z",
            "endTime": "2026-01-05T14:30:06.000Z",
            "open": 99.98,
            "high": 99.99,
            "low": 99.98,
            "close": 99.99,
            "volume": 135,
            "dollarValue": 13497.85,
            "tickCount": 2,
            "firstTradeId": "W07",
            "lastTradeId": "W08",
            "closeReason": "threshold"
          }
        ],
        "outputElided": null,
        "outputShape": "array of 2 objects"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a06/static/article-hero.svg"
          },
          {
            "file": "boundary-and-state.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a06/static/boundary-and-state.svg"
          },
          {
            "file": "construction-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a06/static/construction-anatomy.svg"
          }
        ],
        "mermaid": [
          {
            "file": "construction-flow.md",
            "caption": "Causal volume-imbalance construction flow",
            "source": "flowchart TD\n    A[\"Receive corrected, eligible, ordered trade\"] --> B{\"New session?\"}\n    B -->|Yes| C[\"Apply partial-tail policy\"]\n    C --> D[\"Reset sign and expectation seeds\"]\n    B -->|No| E[\"Keep frozen threshold\"]\n    D --> F[\"Infer tick sign and add signed shares\"]\n    E --> F\n    F --> G{\"Absolute signed shares >= frozen threshold?\"}\n    G -->|No| A\n    G -->|Yes| H[\"Emit complete bar, lineage, and overshoot\"]\n    H --> I[\"Update expected ticks and signed shares per trade\"]\n    I --> J[\"Reset accumulation and freeze next threshold\"]\n    J --> A"
          }
        ]
      },
      "references": [
        {
          "key": "R01",
          "title": "Advances in Financial Machine Learning, Chapter 1 manuscript",
          "author": "Marcos Lopez de Prado",
          "url": "https://ssrn.com/abstract=3104847"
        },
        {
          "key": "R02",
          "title": "Inferring Trade Direction from Intraday Data",
          "author": "Charles M. C. Lee and Mark J. Ready",
          "url": "https://doi.org/10.1111/j.1540-6261.1991.tb02683.x"
        },
        {
          "key": "R03",
          "title": "NYSE Daily TAQ Client Specification",
          "author": "New York Stock Exchange / Intercontinental Exchange",
          "url": "https://www.nyse.com/publicdocs/nyse/data/Daily_TAQ_Client_Spec_v4.3.pdf"
        },
        {
          "key": "R04",
          "title": "Trade Reporting Frequently Asked Questions",
          "author": "Financial Industry Regulatory Authority (FINRA)",
          "url": "https://www.finra.org/filing-reporting/market-transparency-reporting/trade-reporting-faq"
        },
        {
          "key": "Evidence and historical-example decision",
          "title": "Evidence and historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/bar-construction/volume-imbalance-bars/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Volume-Imbalance-Bars-Bar-Construction-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/bar-construction/volume-imbalance-bars/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F01-A07",
      "name": "Tick-Run Bars",
      "headline": null,
      "slug": "tick-run-bars",
      "path": "market-data-engineering/bar-construction/tick-run-bars",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F01",
        "family": "Bar Construction",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/bar-construction/tick-run-bars",
        "entry": "constructBars",
        "params": [
          "trades",
          "config"
        ],
        "exports": [
          "constructBars"
        ],
        "archetype": "tape-aggregate",
        "signature": "constructBars(trades, config)"
      },
      "api": {
        "summary": "Closes a bar when a run of same-signed trades exceeds what the recent buy probability makes plausible. Where imbalance bars react to net one-sidedness, run bars react to *persistence*.",
        "params": [
          {
            "name": "trades",
            "type": "Trade[]",
            "required": true,
            "description": "The raw tape in chronological order. Each trade carries `tradeId`, `timestamp`, `session`, `symbol`, `price`, `volume` and `currency`.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ initialTickSign: number; initialExpectedTicks: number; initialBuyProbability: number; alphaTicks: number; alphaBuyProbability: number; thresholdFloorTicks: number; thresholdMultiplier: number; closePartial?: boolean }",
            "required": true,
            "description": "`initialBuyProbability` seeds the estimate of how often trades arrive buyer-initiated, updated by `alphaBuyProbability`. The threshold is bounded below by `thresholdFloorTicks`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Bar[]",
          "length": "fewer",
          "description": "One bar per run event."
        },
        "warmup": null,
        "errors": [
          {
            "when": "any alpha or probability falls outside 0…1",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(bars)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D01-F01-A07.json",
        "call": "constructBars([{\"tradeId\":\"W01\",\"timestamp\":\"2026-01-05T14:30:00.000Z\",\"session\":\"S1\",\"symbol\":\"SYNTH\",\"price\":100,\"volume\":10,\"currency\":\"USD\"},{\"tradeId\":\"W02\",\"timestamp\":\"2026-01-05T14:30:01.000Z\",\"session\":\"S1\",\"symbol\":\"SYNTH\",\"price\":100,\"volume\":20,\"currency\":\"USD\"},{\"tradeId\":\"W03\",\"timestamp\":\"2026-01-05T14:30:02.000Z\",\"session\":\"S1\",\"symbol\":\"SYNTH\",\"price\":99.9,\"volume\":15,\"currency\":\"USD\"}], {\"closePartial\":true,\"initialTickSign\":1,\"initialExpectedTicks\":4,\"initialBuyProbability\":0.625,\"alphaTicks\":0.5,\"alphaBuyProbability\":0.5,\"thresholdFloorTicks\":2,\"thresholdMultiplier\":1})",
        "args": [
          {
            "value": [
              {
                "tradeId": "W01",
                "timestamp": "2026-01-05T14:30:00.000Z",
                "session": "S1",
                "symbol": "SYNTH",
                "price": 100,
                "volume": 10,
                "currency": "USD"
              },
              {
                "tradeId": "W02",
                "timestamp": "2026-01-05T14:30:01.000Z",
                "session": "S1",
                "symbol": "SYNTH",
                "price": 100,
                "volume": 20,
                "currency": "USD"
              },
              {
                "tradeId": "W03",
                "timestamp": "2026-01-05T14:30:02.000Z",
                "session": "S1",
                "symbol": "SYNTH",
                "price": 99.9,
                "volume": 15,
                "currency": "USD"
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 8
            }
          },
          {
            "value": {
              "closePartial": true,
              "initialTickSign": 1,
              "initialExpectedTicks": 4,
              "initialBuyProbability": 0.625,
              "alphaTicks": 0.5,
              "alphaBuyProbability": 0.5,
              "thresholdFloorTicks": 2,
              "thresholdMultiplier": 1
            },
            "elided": null
          }
        ],
        "output": [
          {
            "firstTradeId": "W01",
            "lastTradeId": "W04",
            "tickCount": 4,
            "buyTicks": 3,
            "sellTicks": 1,
            "dominantSide": "buy",
            "thresholdTicks": 2.5,
            "overshootTicks": 0.5,
            "closeReason": "threshold"
          },
          {
            "firstTradeId": "W05",
            "lastTradeId": "W08",
            "tickCount": 4,
            "buyTicks": 1,
            "sellTicks": 3,
            "dominantSide": "sell",
            "thresholdTicks": 2.75,
            "overshootTicks": 0.25,
            "closeReason": "threshold"
          }
        ],
        "outputElided": null,
        "outputShape": "array of 2 objects"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a07/static/article-hero.svg"
          },
          {
            "file": "boundary-and-state.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a07/static/boundary-and-state.svg"
          },
          {
            "file": "construction-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d01-f01-a07/static/construction-anatomy.svg"
          }
        ],
        "mermaid": [
          {
            "file": "construction-flow.md",
            "caption": "Causal construction flow — Tick-Run Bars",
            "source": "flowchart TD\n    A[\"Receive cleaned chronological trade\"] --> B{\"New session?\"}\n    B -->|Yes| C[\"Emit or drop partial; reset price, sign, expectations, and bar state\"]\n    B -->|No| D[\"Keep session state\"]\n    C --> E[\"Assign tick sign; flat carries prior sign\"]\n    D --> E\n    E --> F[\"Update OHLCV, N+, and N−\"]\n    F --> G{\"max(N+, N−) >= frozen h?\"}\n    G -->|No| A\n    G -->|Yes| H[\"Emit complete bar with lineage and diagnostics\"]\n    H --> I[\"Update E[T] and p+ from the completed bar\"]\n    I --> J[\"Freeze the next threshold\"]\n    J --> A"
          }
        ]
      },
      "references": [
        {
          "key": "R01",
          "title": "*Advances in Financial Machine Learning*, Section 2.3.2.2",
          "author": "Marcos López de Prado",
          "url": "https://uat.store.wiley.com/en-us/advances-in-financial-machine-learning-p-9781119482109"
        },
        {
          "key": "R02",
          "title": "Inferring Trade Direction from Intraday Data",
          "author": "Charles M. C. Lee and Mark J. Ready",
          "url": "https://onlinelibrary.wiley.com/doi/abs/10.1111/j.1540-6261.1991.tb02683.x"
        },
        {
          "key": "R03",
          "title": "NYSE Daily TAQ Client Specification",
          "author": "New York Stock Exchange / Intercontinental Exchange",
          "url": "https://www.nyse.com/publicdocs/nyse/data/Daily_TAQ_Client_Spec_v4.3.pdf"
        },
        {
          "key": "R04",
          "title": "Trade Reporting Frequently Asked Questions",
          "author": "Financial Industry Regulatory Authority (FINRA)",
          "url": "https://www.finra.org/filing-reporting/market-transparency-reporting/trade-reporting-faq"
        },
        {
          "key": "Evidence classification",
          "title": "Evidence classification",
          "author": null,
          "url": null
        },
        {
          "key": "Data, licensing, and historical-example decision",
          "title": "Data, licensing, and historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/bar-construction/tick-run-bars/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Tick-Run-Bars-Bar-Construction-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/bar-construction/tick-run-bars/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F02-A01",
      "name": "OHLC Consistency Validator",
      "headline": null,
      "slug": "ohlc-consistency-validator",
      "path": "market-data-engineering/cleaning-and-validation/ohlc-consistency-validator",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F02",
        "family": "Cleaning and Validation",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/cleaning-and-validation/ohlc-consistency-validator",
        "entry": "validateBars",
        "params": [
          "bars",
          "config"
        ],
        "exports": [
          "validateBars"
        ],
        "archetype": "row-classify",
        "signature": "validateBars(bars, config)"
      },
      "api": {
        "summary": "Checks each bar against the invariants an OHLC bar must satisfy — high is the maximum, low is the minimum, open and close lie between them — with a tick-size tolerance so representable rounding is not reported as corruption.",
        "params": [
          {
            "name": "bars",
            "type": "OhlcRow[]",
            "required": true,
            "description": "Bars to check, each carrying `bar_id`, `source`, `symbol`, `timestamp` and the four prices.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ tickSize: number; toleranceTicks: number; priceScale: number }",
            "required": true,
            "description": "`tickSize` is the instrument's minimum increment and `toleranceTicks` how many of them a value may be out before it is a violation. `priceScale` fixes the decimal scale used for comparison so floating-point representation does not create phantom failures.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Verdict[]",
          "length": "same-as-input",
          "description": "One verdict per bar, naming which invariant failed and by how much. Returns one verdict per input row rather than throwing, so a single bad record cannot abort the batch — and cannot pass unnoticed either."
        },
        "warmup": null,
        "errors": [
          {
            "when": "tickSize is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "validateBars([{\"bar_id\":\"B01\",\"source\":\"SYNTHETIC\",\"symbol\":\"DEMO\",\"timestamp\":\"2026-07-20T09:30:00Z\",\"open\":100,\"high\":102,\"low\":99,\"close\":101,\"volume\":1000},{\"bar_id\":\"B02\",\"source\":\"SYNTHETIC\",\"symbol\":\"DEMO\",\"timestamp\":\"2026-07-20T09:31:00Z\",\"open\":100.01,\"high\":100,\"low\":99.5,\"close\":99.9,\"volume\":900},{\"bar_id\":\"B03\",\"source\":\"SYNTHETIC\",\"symbol\":\"DEMO\",\"timestamp\":\"2026-07-20T09:32:00Z\",\"open\":100.0101,\"high\":100,\"low\":99.5,\"close\":99.9,\"volume\":800}], {\"tickSize\":0.01,\"toleranceTicks\":1,\"priceScale\":1})",
        "args": [
          {
            "value": [
              {
                "bar_id": "B01",
                "source": "SYNTHETIC",
                "symbol": "DEMO",
                "timestamp": "2026-07-20T09:30:00Z",
                "open": 100,
                "high": 102,
                "low": 99,
                "close": 101,
                "volume": 1000
              },
              {
                "bar_id": "B02",
                "source": "SYNTHETIC",
                "symbol": "DEMO",
                "timestamp": "2026-07-20T09:31:00Z",
                "open": 100.01,
                "high": 100,
                "low": 99.5,
                "close": 99.9,
                "volume": 900
              },
              {
                "bar_id": "B03",
                "source": "SYNTHETIC",
                "symbol": "DEMO",
                "timestamp": "2026-07-20T09:32:00Z",
                "open": 100.0101,
                "high": 100,
                "low": 99.5,
                "close": 99.9,
                "volume": 800
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 7
            }
          },
          {
            "value": {
              "tickSize": 0.01,
              "toleranceTicks": 1,
              "priceScale": 1
            },
            "elided": null
          }
        ],
        "output": [
          {
            "index": 0,
            "timestamp": "2026-07-20T09:30:00Z",
            "valid": true,
            "issues": [],
            "tolerancePriceUnits": 0.01,
            "normalizedPrices": {
              "open": 100,
              "high": 102,
              "low": 99,
              "close": 101
            },
            "provenance": {
              "source": "SYNTHETIC",
              "symbol": "DEMO",
              "bar_id": "B01"
            },
            "rawBar": {
              "bar_id": "B01",
              "source": "SYNTHETIC",
              "symbol": "DEMO",
              "timestamp": "2026-07-20T09:30:00Z",
              "open": 100,
              "high": 102,
              "low": 99,
              "close": 101,
              "volume": 1000
            }
          },
          {
            "index": 1,
            "timestamp": "2026-07-20T09:31:00Z",
            "valid": true,
            "issues": [],
            "tolerancePriceUnits": 0.01,
            "normalizedPrices": {
              "open": 100.01,
              "high": 100,
              "low": 99.5,
              "close": 99.9
            },
            "provenance": {
              "source": "SYNTHETIC",
              "symbol": "DEMO",
              "bar_id": "B02"
            },
            "rawBar": {
              "bar_id": "B02",
              "source": "SYNTHETIC",
              "symbol": "DEMO",
              "timestamp": "2026-07-20T09:31:00Z",
              "open": 100.01,
              "high": 100,
              "low": 99.5,
              "close": 99.9,
              "volume": 900
            }
          },
          {
            "index": 2,
            "timestamp": "2026-07-20T09:32:00Z",
            "valid": false,
            "issues": [
              "HIGH_BELOW_BODY"
            ],
            "tolerancePriceUnits": 0.01,
            "normalizedPrices": {
              "open": 100.0101,
              "high": 100,
              "low": 99.5,
              "close": 99.9
            },
            "provenance": {
              "source": "SYNTHETIC",
              "symbol": "DEMO",
              "bar_id": "B03"
            },
            "rawBar": {
              "bar_id": "B03",
              "source": "SYNTHETIC",
              "symbol": "DEMO",
              "timestamp": "2026-07-20T09:32:00Z",
              "open": 100.0101,
              "high": 100,
              "low": 99.5,
              "close": 99.9,
              "volume": 800
            }
          }
        ],
        "outputElided": {
          "kind": "array",
          "shown": 3,
          "total": 7
        },
        "outputShape": "array of 7 objects"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f02-a01/static/article-hero.svg"
          },
          {
            "file": "ohlc-invariants.svg",
            "url": "https://thefintechbuilder.com/content/d01-f02-a01/static/ohlc-invariants.svg"
          }
        ],
        "mermaid": [
          {
            "file": "validation-flow.md",
            "caption": "Detection, investigation, and repair flow",
            "source": "flowchart LR\n    A[\"Raw bar plus provenance\"] --> B{\"Configuration valid?\"}\n    B -->|No| X[\"Reject the validation request\"]\n    B -->|Yes| C{\"Required fields valid?\"}\n    C -->|No| D[\"Record field issues\"]\n    C -->|Yes| E[\"Normalize price scale\"]\n    E --> F[\"Evaluate all three OHLC gaps\"]\n    D --> G[\"Emit detection result and raw row\"]\n    F --> G\n    G --> H{\"Independent evidence confirms cause?\"}\n    H -->|No| I[\"Quarantine and investigate\"]\n    H -->|Yes| J[\"Apply an approved versioned repair downstream\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NYSE-CLOSE-2.2",
          "title": "Closing Prices Client Specification",
          "author": "New York Stock Exchange / Intercontinental Exchange",
          "url": "https://www.nyse.com/publicdocs/nyse/data/TAQ_Closing_Prices_Client_Spec_v2.2.pdf"
        },
        {
          "key": "NYSE-DTAQ-4.3",
          "title": "Daily TAQ Client Specification",
          "author": "New York Stock Exchange / Intercontinental Exchange",
          "url": "https://www.nyse.com/publicdocs/nyse/data/Daily_TAQ_Client_Spec_v4.3.pdf"
        },
        {
          "key": "SEC-DQA",
          "title": "Final Data Quality Assurance Guidelines",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/data-research/final-data-quality-assurance-guidelines"
        },
        {
          "key": "Evidence classification",
          "title": "Evidence classification",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/cleaning-and-validation/ohlc-consistency-validator/",
        "repo": "https://github.com/IslamBaraka90/Fintech-OHLC-Consistency-Validator-Data-Quality-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/cleaning-and-validation/ohlc-consistency-validator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F02-A02",
      "name": "Hampel Bad-Tick Filter",
      "headline": null,
      "slug": "hampel-bad-tick-filter",
      "path": "market-data-engineering/cleaning-and-validation/hampel-bad-tick-filter",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F02",
        "family": "Cleaning and Validation",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/cleaning-and-validation/hampel-bad-tick-filter",
        "entry": "hampelFilter",
        "params": [
          "values",
          "options"
        ],
        "exports": [
          "hampelFilter"
        ],
        "archetype": "record-transform",
        "signature": "hampelFilter(values, options)"
      },
      "api": {
        "summary": "Flags points that sit too far from a rolling median, measured in robust deviations rather than standard deviations — so one fat-finger print cannot inflate the very statistic used to detect it.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series in chronological order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "options",
            "type": "{ windowRadius?: number; threshold?: number; scale?: number; minHistory?: number; mode?: \"causal\" | \"centred\" }",
            "required": false,
            "description": "`windowRadius` is the half-width of the rolling window (default 3). `threshold` is how many scaled MADs count as an outlier. `scale` converts MAD to a standard-deviation equivalent (1.4826 for normal data). `minHistory` is the minimum sample before any judgement is made. `mode` chooses causal — history only, safe for live use — or centred, which sees future points and must never be used on a live feed.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Verdict[]",
          "length": "same-as-input",
          "description": "One verdict per point with its median, deviation and the threshold applied. Returns one verdict per input row rather than throwing, so a single bad record cannot abort the batch — and cannot pass unnoticed either."
        },
        "warmup": null,
        "errors": [
          {
            "when": "windowRadius or threshold is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × windowRadius)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "hampelFilter([100,100.1,99.9,100,100.1,112], {\"windowRadius\":3,\"threshold\":3,\"scale\":1.4826,\"minHistory\":3,\"mode\":\"causal\"})",
        "args": [
          {
            "value": [
              100,
              100.1,
              99.9,
              100,
              100.1,
              112
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 17
            }
          },
          {
            "value": {
              "windowRadius": 3,
              "threshold": 3,
              "scale": 1.4826,
              "minHistory": 3,
              "mode": "causal"
            },
            "elided": null
          }
        ],
        "output": [
          {
            "index": 0,
            "value": 100,
            "mode": "causal",
            "windowStart": 0,
            "windowEnd": 0,
            "windowCount": 1,
            "median": 100,
            "mad": 0,
            "scaledMad": 0,
            "score": null,
            "threshold": 3,
            "flagged": false,
            "status": "insufficient_history",
            "lookaheadUsed": false
          },
          {
            "index": 1,
            "value": 100.1,
            "mode": "causal",
            "windowStart": 0,
            "windowEnd": 1,
            "windowCount": 2,
            "median": 100.05,
            "mad": 0.04999999999999716,
            "scaledMad": 0.07412999999999578,
            "score": null,
            "threshold": 3,
            "flagged": false,
            "status": "insufficient_history",
            "lookaheadUsed": false
          },
          {
            "index": 2,
            "value": 99.9,
            "mode": "causal",
            "windowStart": 0,
            "windowEnd": 2,
            "windowCount": 3,
            "median": 100,
            "mad": 0.09999999999999432,
            "scaledMad": 0.14825999999999157,
            "score": 0.6744907594765952,
            "threshold": 3,
            "flagged": false,
            "status": "eligible",
            "lookaheadUsed": false
          }
        ],
        "outputElided": {
          "kind": "array",
          "shown": 3,
          "total": 17
        },
        "outputShape": "array of 17 objects"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f02-a02/static/article-hero.svg"
          },
          {
            "file": "hampel-window.svg",
            "url": "https://thefintechbuilder.com/content/d01-f02-a02/static/hampel-window.svg"
          }
        ],
        "mermaid": [
          {
            "file": "filter-flow.md",
            "caption": "Hampel diagnostic, evidence, and policy flow",
            "source": "flowchart LR\n    A[\"Ordered eligible tick\"] --> B{\"Window mode\"}\n    B -->|\"Causal default\"| C[\"Trailing values through i\"]\n    B -->|\"Centered retrospective\"| D[\"Past and future values around i\"]\n    C --> E[\"Median, MAD, score\"]\n    D --> E\n    E --> F[\"Flag plus diagnostics\"]\n    F --> G{\"Independent evidence\"}\n    G -->|\"Unconfirmed\"| H[\"Preserve and investigate\"]\n    G -->|\"Authorized policy\"| I[\"Annotate or derive replacement\"]"
          }
        ]
      },
      "references": [
        {
          "key": "HAMPEL-1974",
          "title": "The Influence Curve and Its Role in Robust Estimation",
          "author": "Frank R. Hampel, ETH Zürich",
          "url": "https://doi.org/10.1080/01621459.1974.10482962"
        },
        {
          "key": "NIST-MAD",
          "title": "Median Absolute Deviation",
          "author": "National Institute of Standards and Technology",
          "url": "https://www.itl.nist.gov/div898/software/dataplot/refman2/auxillar/mad.htm"
        },
        {
          "key": "NIST-OUTLIERS",
          "title": "Detection of Outliers",
          "author": "National Institute of Standards and Technology",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35h.htm"
        },
        {
          "key": "PEARSON-2016",
          "title": "Generalized Hampel Filters",
          "author": "Ronald K. Pearson, Yrjö Neuvo, Jaakko Astola, Moncef Gabbouj",
          "url": "https://doi.org/10.1186/s13634-016-0383-6"
        },
        {
          "key": "NYSE-TAQ-4.3",
          "title": "Daily TAQ Client Specifications",
          "author": "New York Stock Exchange",
          "url": "https://www.nyse.com/publicdocs/nyse/data/Daily_TAQ_Client_Spec_v4.3.pdf"
        },
        {
          "key": "Evidence and data note",
          "title": "Evidence and data note",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/cleaning-and-validation/hampel-bad-tick-filter/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Hampel-Bad-Tick-Filter-Data-Quality-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/cleaning-and-validation/hampel-bad-tick-filter/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F02-A03",
      "name": "Median Absolute Deviation Outlier Filter",
      "headline": null,
      "slug": "median-absolute-deviation-outlier-filter",
      "path": "market-data-engineering/cleaning-and-validation/median-absolute-deviation-outlier-filter",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F02",
        "family": "Cleaning and Validation",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/cleaning-and-validation/median-absolute-deviation-outlier-filter",
        "entry": "madOutliers",
        "params": [
          "values",
          "threshold",
          "scale",
          "minimumSamples"
        ],
        "exports": [
          "madOutliers"
        ],
        "archetype": "record-transform",
        "signature": "madOutliers(values, threshold, scale, minimumSamples)"
      },
      "api": {
        "summary": "Whole-sample outlier detection against the median absolute deviation. Where the Hampel filter is local and rolling, this judges every point against one global robust spread.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "The complete sample to evaluate.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "threshold",
            "type": "number",
            "required": true,
            "description": "How many scaled MADs from the median a point may sit before it is flagged.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "scale",
            "type": "number",
            "required": true,
            "description": "MAD-to-sigma conversion factor; 1.4826 makes the result comparable to a standard deviation under normality.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "minimumSamples",
            "type": "number",
            "required": true,
            "description": "Below this count the function reports insufficient data rather than guessing from a handful of points.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, valid_count, median, raw_mad, scaled_mad, threshold, outliers }",
          "description": "The decision plus every statistic behind it, so a surprising result can be checked rather than re-derived."
        },
        "warmup": null,
        "errors": [
          {
            "when": "threshold or scale is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "madOutliers([10,10.1,9.9,10.2,10.1,9.8], 3.5, 1.4825796886582654, 3)",
        "args": [
          {
            "value": [
              10,
              10.1,
              9.9,
              10.2,
              10.1,
              9.8
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 13
            }
          },
          {
            "value": 3.5,
            "elided": null
          },
          {
            "value": 1.4825796886582654,
            "elided": null
          },
          {
            "value": 3,
            "elided": null
          }
        ],
        "output": {
          "status": "ok",
          "valid_count": 12,
          "minimum_samples": 3,
          "median": 10.05,
          "raw_mad": 0.09999999999999964,
          "scaled_mad": 0.148257968865826,
          "scale": 1.4825796886582654,
          "threshold": 3.5,
          "points": [
            {
              "index": 0,
              "value": 10,
              "score": 0.337250000000006,
              "outlier": false
            },
            {
              "index": 1,
              "value": 10.1,
              "score": 0.337249999999994,
              "outlier": false
            },
            {
              "index": 2,
              "value": 9.9,
              "score": 1.011750000000006,
              "outlier": false
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: status, valid_count, minimum_samples, median, raw_mad, scaled_mad, scale, threshold, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f02-a03/static/article-hero.svg"
          },
          {
            "file": "mad-geometry.svg",
            "url": "https://thefintechbuilder.com/content/d01-f02-a03/static/mad-geometry.svg"
          }
        ],
        "mermaid": [
          {
            "file": "mad-flow.md",
            "caption": "Global MAD classification flow",
            "source": "flowchart TD\n    A[\"Comparable source records\"] --> B[\"Partition by unit, field, time basis, and adjustment basis\"]\n    B --> C[\"Reject nonfinite values; preserve missing positions\"]\n    C --> D{\"Enough finite observations?\"}\n    D -->|No| E[\"Insufficient sample; no scores or flags\"]\n    D -->|Yes| F[\"Compute median, raw MAD, and scaled MAD\"]\n    F --> G{\"Raw MAD equals zero?\"}\n    G -->|No| H[\"Score absolute distance divided by scaled MAD\"]\n    G -->|Yes| I[\"Equal values score 0; unequal values score infinity\"]\n    H --> J[\"Flag only score strictly above threshold\"]\n    I --> J\n    J --> K[\"Emit diagnostics and preserve raw input\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST-SCALE - Measures of Scale",
          "title": "NIST-SCALE - Measures of Scale",
          "author": "NIST/SEMATECH",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda356.htm"
        },
        {
          "key": "NIST-DATAPLOT - Median Absolute Deviation",
          "title": "NIST-DATAPLOT - Median Absolute Deviation",
          "author": "National Institute of Standards and Technology",
          "url": "https://www.itl.nist.gov/div898/software/dataplot/refman2/auxillar/mad.htm"
        },
        {
          "key": "HAMPEL-1974 - The Influence Curve and Its Role in Robust Estimation",
          "title": "HAMPEL-1974 - The Influence Curve and Its Role in Robust Estimation",
          "author": "Frank R. Hampel",
          "url": "https://doi.org/10.1080/01621459.1974.10482962"
        },
        {
          "key": "Package-policy classification",
          "title": "Package-policy classification",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/cleaning-and-validation/median-absolute-deviation-outlier-filter/",
        "repo": "https://github.com/IslamBaraka90/Fintech-MAD-Median-Absolute-Deviation-Outlier-Filter-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/cleaning-and-validation/median-absolute-deviation-outlier-filter/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F02-A04",
      "name": "Stale-Quote Detector",
      "headline": null,
      "slug": "stale-quote-detector",
      "path": "market-data-engineering/cleaning-and-validation/stale-quote-detector",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F02",
        "family": "Cleaning and Validation",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/cleaning-and-validation/stale-quote-detector",
        "entry": "detectStaleQuotes",
        "params": [
          "events",
          "config"
        ],
        "exports": [
          "detectStaleQuotes"
        ],
        "archetype": "row-classify",
        "signature": "detectStaleQuotes(events, config)"
      },
      "api": {
        "summary": "Separates the several distinct ways a quote can be stale: old at the source, delayed in transport, unchanged for too long, or arriving after a missed heartbeat. They have different causes and different remedies, so they are reported separately.",
        "params": [
          {
            "name": "events",
            "type": "QuoteEvent[]",
            "required": true,
            "description": "Quote and heartbeat events with both `source_event_ts` and `observed_ts`, which is what makes source age and transport age separable.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ max_source_event_age_ms: number; max_transport_age_ms: number; unchanged_threshold_ms: number; heartbeat_timeout_ms: number }",
            "required": true,
            "description": "One budget per failure mode: how old the venue's own timestamp may be, how long transport may take, how long a quote may sit unchanged, and how long a heartbeat may be missing.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Verdict[]",
          "length": "same-as-input",
          "description": "One verdict per event naming which budget was breached. Returns one verdict per input row rather than throwing, so a single bad record cannot abort the batch — and cannot pass unnoticed either."
        },
        "warmup": null,
        "errors": [
          {
            "when": "any threshold is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "detectStaleQuotes([{\"event_id\":\"E01\",\"kind\":\"quote\",\"source_event_ts\":\"2026-07-22T09:30:00.000Z\",\"observed_ts\":\"2026-07-22T09:30:00.100Z\",\"bid\":100,\"ask\":100.02,\"clock_sync_ok\":true,\"session_id\":\"S1\",\"session_state\":\"ACTIVE\",\"activity_expected\":true},{\"event_id\":\"E02\",\"kind\":\"heartbeat\",\"observed_ts\":\"2026-07-22T09:30:00.900Z\",\"session_id\":\"S1\",\"session_state\":\"ACTIVE\",\"activity_expected\":true},{\"event_id\":\"E03\",\"kind\":\"check\",\"observed_ts\":\"2026-07-22T09:30:01.200Z\",\"session_id\":\"S1\",\"session_state\":\"ACTIVE\",\"activity_expected\":true}], {\"max_source_event_age_ms\":1200,\"max_transport_age_ms\":250,\"unchanged_threshold_ms\":3000,\"heartbeat_timeout_ms\":1200})",
        "args": [
          {
            "value": [
              {
                "event_id": "E01",
                "kind": "quote",
                "source_event_ts": "2026-07-22T09:30:00.000Z",
                "observed_ts": "2026-07-22T09:30:00.100Z",
                "bid": 100,
                "ask": 100.02,
                "clock_sync_ok": true,
                "session_id": "S1",
                "session_state": "ACTIVE",
                "activity_expected": true
              },
              {
                "event_id": "E02",
                "kind": "heartbeat",
                "observed_ts": "2026-07-22T09:30:00.900Z",
                "session_id": "S1",
                "session_state": "ACTIVE",
                "activity_expected": true
              },
              {
                "event_id": "E03",
                "kind": "check",
                "observed_ts": "2026-07-22T09:30:01.200Z",
                "session_id": "S1",
                "session_state": "ACTIVE",
                "activity_expected": true
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 12
            }
          },
          {
            "value": {
              "max_source_event_age_ms": 1200,
              "max_transport_age_ms": 250,
              "unchanged_threshold_ms": 3000,
              "heartbeat_timeout_ms": 1200
            },
            "elided": null
          }
        ],
        "output": [
          {
            "event_id": "E01",
            "kind": "quote",
            "source_event_ts": "2026-07-22T09:30:00.000Z",
            "observed_ts": "2026-07-22T09:30:00.100Z",
            "bid": 100,
            "ask": 100.02,
            "clock_sync_ok": true,
            "session_id": "S1",
            "session_state": "ACTIVE",
            "activity_expected": true,
            "source_event_age_ms": 100,
            "last_transport_age_ms": 100,
            "unchanged_duration_ms": 0,
            "heartbeat_age_ms": 0
          },
          {
            "event_id": "E02",
            "kind": "heartbeat",
            "observed_ts": "2026-07-22T09:30:00.900Z",
            "session_id": "S1",
            "session_state": "ACTIVE",
            "activity_expected": true,
            "source_event_age_ms": 900,
            "last_transport_age_ms": 100,
            "unchanged_duration_ms": 800,
            "heartbeat_age_ms": 0,
            "source_event_age_exceeded": false,
            "transport_late": false,
            "unchanged_threshold_reached": false,
            "heartbeat_lost": false
          },
          {
            "event_id": "E03",
            "kind": "check",
            "observed_ts": "2026-07-22T09:30:01.200Z",
            "session_id": "S1",
            "session_state": "ACTIVE",
            "activity_expected": true,
            "source_event_age_ms": 1200,
            "last_transport_age_ms": 100,
            "unchanged_duration_ms": 1100,
            "heartbeat_age_ms": 300,
            "source_event_age_exceeded": false,
            "transport_late": false,
            "unchanged_threshold_reached": false,
            "heartbeat_lost": false
          }
        ],
        "outputElided": {
          "kind": "array",
          "shown": 3,
          "total": 12
        },
        "outputShape": "array of 12 objects"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f02-a04/static/article-hero.svg"
          },
          {
            "file": "stale-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d01-f02-a04/static/stale-timeline.svg"
          }
        ],
        "mermaid": [
          {
            "file": "stale-state.md",
            "caption": "Validation-before-mutation flow",
            "source": "flowchart TD\n    A[\"Quote, heartbeat, or check\"] --> B{\"Schema and receiver order valid?\"}\n    B -->|No| R[\"Reject and preserve state\"]\n    B -->|Yes| C{\"Quote event?\"}\n    C -->|Yes| D{\"Clock sync verified, age nonnegative, source order valid?\"}\n    D -->|No| R\n    D -->|Yes| E[\"Apply session reset if ID changed\"]\n    C -->|No| E\n    E --> F[\"Quote or heartbeat updates last-message receipt\"]\n    F --> G[\"Only changed quote updates last-change receipt\"]\n    G --> H[\"Compute source, transport, unchanged, and heartbeat ages\"]\n    H --> I[\"Apply active-session business policy\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NASDAQ-ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "NASDAQ-SOUP",
          "title": "SoupBinTCP 4.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/tradingproducts/soupbintcp4_0.pdf"
        },
        {
          "key": "NASDAQ-2013",
          "title": "Post Mortem: NASDAQ Trading Halted in Tape C Securities",
          "author": "Nasdaq OMX",
          "url": "https://www.nasdaqtrader.com/TraderNews.aspx?id=ETA2013-77"
        },
        {
          "key": "UTP-2013-9",
          "title": "UTP SIP Issue on Thursday, August 22, 2013",
          "author": "UTP SIP / Nasdaq OMX",
          "url": "https://www.nasdaqtrader.com/TraderNews.aspx?id=uva2013-9"
        },
        {
          "key": "SEC-SCI",
          "title": "Regulation Systems Compliance and Integrity",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/files/rules/final/2014/34-73639.pdf"
        },
        {
          "key": "FINRA-6820",
          "title": "Clock Synchronization",
          "author": "Financial Industry Regulatory Authority",
          "url": "https://www.finra.org/rules-guidance/rulebooks/finra-rules/6820"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/cleaning-and-validation/stale-quote-detector/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Stale-Quote-Detector-Data-Quality-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/cleaning-and-validation/stale-quote-detector/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F02-A05",
      "name": "Duplicate-Trade Resolver",
      "headline": null,
      "slug": "duplicate-trade-resolver",
      "path": "market-data-engineering/cleaning-and-validation/duplicate-trade-resolver",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F02",
        "family": "Cleaning and Validation",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/cleaning-and-validation/duplicate-trade-resolver",
        "entry": "resolveTrades",
        "params": [
          "input"
        ],
        "exports": [
          "resolveTrades"
        ],
        "archetype": "row-classify",
        "signature": "resolveTrades(input)"
      },
      "api": {
        "summary": "Reconciles a stream of new, corrected and cancelled trade messages into one authoritative set. Replays of the same message must be idempotent, and a cancellation must survive a later redelivery of the trade it cancelled.",
        "params": [
          {
            "name": "input",
            "type": "TradeMessage[]",
            "required": true,
            "description": "Messages carrying `source_id`, `session_id`, `instrument_id`, `event_id`, `trade_id` and an `action` of new, correct or cancel.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ policy_version, active, states, tombstones, pending, versions, raw_history, audit }",
          "description": "The resolved set (`active`), cancelled trades kept as `tombstones` so a redelivery cannot resurrect them, messages awaiting a predecessor (`pending`), and a full `audit` of how each decision was reached."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a message is missing an identifier required to place it",
            "behaviour": "recorded in the audit rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "resolveTrades([{\"source_id\":\"SIP-X\",\"session_id\":\"2026-07-20\",\"instrument_id\":\"XYZ\",\"event_id\":\"E2\",\"trade_id\":\"T1\",\"action\":\"CORRECT\",\"ref_event_id\":\"E1\",\"receive_ts\":\"2026-07-20T13:30:00.003Z\",\"sequence\":2,\"price\":101,\"size\":12},{\"source_id\":\"SIP-X\",\"session_id\":\"2026-07-20\",\"instrument_id\":\"XYZ\",\"event_id\":\"E1\",\"trade_id\":\"T1\",\"action\":\"NEW\",\"receive_ts\":\"2026-07-20T13:30:00.004Z\",\"sequence\":1,\"price\":100,\"size\":10},{\"source_id\":\"SIP-X\",\"session_id\":\"2026-07-20\",\"instrument_id\":\"XYZ\",\"event_id\":\"E1\",\"trade_id\":\"T1\",\"action\":\"NEW\",\"receive_ts\":\"2026-07-20T13:30:00.004Z\",\"sequence\":1,\"price\":100,\"size\":10}])",
        "args": [
          {
            "value": [
              {
                "source_id": "SIP-X",
                "session_id": "2026-07-20",
                "instrument_id": "XYZ",
                "event_id": "E2",
                "trade_id": "T1",
                "action": "CORRECT",
                "ref_event_id": "E1",
                "receive_ts": "2026-07-20T13:30:00.003Z",
                "sequence": 2,
                "price": 101,
                "size": 12
              },
              {
                "source_id": "SIP-X",
                "session_id": "2026-07-20",
                "instrument_id": "XYZ",
                "event_id": "E1",
                "trade_id": "T1",
                "action": "NEW",
                "receive_ts": "2026-07-20T13:30:00.004Z",
                "sequence": 1,
                "price": 100,
                "size": 10
              },
              {
                "source_id": "SIP-X",
                "session_id": "2026-07-20",
                "instrument_id": "XYZ",
                "event_id": "E1",
                "trade_id": "T1",
                "action": "NEW",
                "receive_ts": "2026-07-20T13:30:00.004Z",
                "sequence": 1,
                "price": 100,
                "size": 10
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 24
            }
          }
        ],
        "output": {
          "policy_version": "synthetic-lifecycle-v2",
          "active": [
            {
              "trade_key": "SIP-X|2026-07-20|XYZ|T5",
              "source_id": "SIP-X",
              "session_id": "2026-07-20",
              "instrument_id": "XYZ",
              "trade_id": "T5",
              "status": "ACTIVE",
              "head_event_id": "E13",
              "head_event_key": "SIP-X|2026-07-20|E13",
              "price": 80.5,
              "size": 32,
              "chain": [
                "E12",
                "E13"
              ]
            }
          ],
          "states": {
            "SIP-X|2026-07-20|XYZ|T1": {
              "trade_key": "SIP-X|2026-07-20|XYZ|T1",
              "source_id": "SIP-X",
              "session_id": "2026-07-20",
              "instrument_id": "XYZ",
              "trade_id": "T1",
              "status": "CANCELED",
              "head_event_id": "E3",
              "head_event_key": "SIP-X|2026-07-20|E3",
              "price": 101,
              "size": 12,
              "chain": [
                "E1",
                "E2",
                "E3"
              ],
              "tombstone": {
                "action": "CANCEL",
                "event_id": "E3",
                "ref_event_id": "E2"
              }
            },
            "SIP-X|2026-07-20|XYZ|T3": {
              "trade_key": "SIP-X|2026-07-20|XYZ|T3",
              "source_id": "SIP-X",
              "session_id": "2026-07-20",
              "instrument_id": "XYZ",
              "trade_id": "T3",
              "status": "ERRORED",
              "head_event_id": "E8",
              "head_event_key": "SIP-X|2026-07-20|E8",
              "price": 75,
              "size": 20,
              "chain": [
                "E7",
                "E8"
              ],
              "tombstone": {
                "action": "ERROR",
                "event_id": "E8",
                "ref_event_id": "E7"
              }
            },
            "SIP-X|2026-07-20|XYZ|T4": {
              "trade_key": "SIP-X|2026-07-20|XYZ|T4",
              "source_id": "SIP-X",
              "session_id": "2026-07-20",
              "instrument_id": "XYZ",
              "trade_id": "T4",
              "status": "CANCELED",
              "head_event_id": "E18",
              "head_event_key": "SIP-X|2026-07-20|E18",
              "price": 60,
              "size": 8,
              "chain": [
                "E9",
                "E18"
              ],
              "tombstone": {
                "action": "CANCEL",
                "event_id": "E18",
                "ref_event_id": "E9"
              }
            },
            "SIP-X|2026-07-20|XYZ|T5": {
              "trade_key": "SIP-X|2026-07-20|XYZ|T5",
              "source_id": "SIP-X",
              "session_id": "2026-07-20",
              "instrument_id": "XYZ",
              "trade_id": "T5",
              "status": "ACTIVE",
              "head_event_id": "E13",
              "head_event_key": "SIP-X|2026-07-20|E13",
              "price": 80.5,
              "size": 32,
              "chain": [
                "E12",
                "E13"
              ]
            },
            "SIP-X|2026-07-21|XYZ|T1": {
              "trade_key": "SIP-X|2026-07-21|XYZ|T1",
              "source_id": "SIP-X",
              "session_id": "2026-07-21",
              "instrument_id": "XYZ",
              "trade_id": "T1",
              "status": "ERRORED",
              "head_event_id": "E2",
              "head_event_key": "SIP-X|2026-07-21|E2",
              "price": 103,
              "size": 11,
              "chain": [
                "E1",
                "E2"
              ],
              "tombstone": {
                "action": "ERROR",
                "event_id": "E2",
                "ref_event_id": "E1"
              }
            }
          },
          "tombstones": [
            {
              "trade_key": "SIP-X|2026-07-20|XYZ|T1",
              "source_id": "SIP-X",
              "session_id": "2026-07-20",
              "instrument_id": "XYZ",
              "trade_id": "T1",
              "status": "CANCELED",
              "head_event_id": "E3",
              "head_event_key": "SIP-X|2026-07-20|E3",
              "price": 101,
              "size": 12,
              "chain": [
                "E1",
                "E2",
                "E3"
              ],
              "tombstone": {
                "action": "CANCEL",
                "event_id": "E3",
                "ref_event_id": "E2"
              }
            },
            {
              "trade_key": "SIP-X|2026-07-20|XYZ|T3",
              "source_id": "SIP-X",
              "session_id": "2026-07-20",
              "instrument_id": "XYZ",
              "trade_id": "T3",
              "status": "ERRORED",
              "head_event_id": "E8",
              "head_event_key": "SIP-X|2026-07-20|E8",
              "price": 75,
              "size": 20,
              "chain": [
                "E7",
                "E8"
              ],
              "tombstone": {
                "action": "ERROR",
                "event_id": "E8",
                "ref_event_id": "E7"
              }
            },
            {
              "trade_key": "SIP-X|2026-07-20|XYZ|T4",
              "source_id": "SIP-X",
              "session_id": "2026-07-20",
              "instrument_id": "XYZ",
              "trade_id": "T4",
              "status": "CANCELED",
              "head_event_id": "E18",
              "head_event_key": "SIP-X|2026-07-20|E18",
              "price": 60,
              "size": 8,
              "chain": [
                "E9",
                "E18"
              ],
              "tombstone": {
                "action": "CANCEL",
                "event_id": "E18",
                "ref_event_id": "E9"
              }
            }
          ],
          "pending": [
            {
              "event_key": "SIP-X|2026-07-20|E10",
              "trade_key": "SIP-X|2026-07-20|XYZ|T4",
              "ref_event_id": "MISSING",
              "action": "CORRECT"
            }
          ],
          "versions": [
            {
              "event_key": "SIP-X|2026-07-20|E1",
              "trade_key": "SIP-X|2026-07-20|XYZ|T1",
              "event_id": "E1",
              "action": "NEW",
              "sequence": 1,
              "price": 100,
              "size": 10,
              "decision": "APPLY_NEW",
              "head_before": null,
              "head_after": "E1"
            },
            {
              "event_key": "SIP-X|2026-07-20|E2",
              "trade_key": "SIP-X|2026-07-20|XYZ|T1",
              "event_id": "E2",
              "action": "CORRECT",
              "ref_event_id": "E1",
              "sequence": 2,
              "price": 101,
              "size": 12,
              "decision": "APPLY_CORRECTION",
              "head_before": "E1",
              "head_after": "E2"
            },
            {
              "event_key": "SIP-X|2026-07-20|E3",
              "trade_key": "SIP-X|2026-07-20|XYZ|T1",
              "event_id": "E3",
              "action": "CANCEL",
              "ref_event_id": "E2",
              "sequence": 3,
              "decision": "APPLY_CANCEL",
              "head_before": "E2",
              "head_after": "E3"
            }
          ],
          "raw_history": [
            {
              "arrival_index": 0,
              "event": {
                "source_id": "SIP-X",
                "session_id": "2026-07-20",
                "instrument_id": "XYZ",
                "event_id": "E2",
                "trade_id": "T1",
                "action": "CORRECT",
                "ref_event_id": "E1",
                "receive_ts": "2026-07-20T13:30:00.003Z",
                "sequence": 2,
                "price": 101,
                "size": 12
              },
              "validation_errors": []
            },
            {
              "arrival_index": 1,
              "event": {
                "source_id": "SIP-X",
                "session_id": "2026-07-20",
                "instrument_id": "XYZ",
                "event_id": "E1",
                "trade_id": "T1",
                "action": "NEW",
                "receive_ts": "2026-07-20T13:30:00.004Z",
                "sequence": 1,
                "price": 100,
                "size": 10
              },
              "validation_errors": []
            },
            {
              "arrival_index": 2,
              "event": {
                "source_id": "SIP-X",
                "session_id": "2026-07-20",
                "instrument_id": "XYZ",
                "event_id": "E1",
                "trade_id": "T1",
                "action": "NEW",
                "receive_ts": "2026-07-20T13:30:00.004Z",
                "sequence": 1,
                "price": 100,
                "size": 10
              },
              "validation_errors": []
            }
          ],
          "audit": [
            {
              "arrival_index": 0,
              "event_id": "E2",
              "trade_id": "T1",
              "decision": "APPLY_CORRECTION",
              "reason": "correction references the current active version"
            },
            {
              "arrival_index": 1,
              "event_id": "E1",
              "trade_id": "T1",
              "decision": "APPLY_NEW",
              "reason": "first valid NEW for this scoped trade key"
            },
            {
              "arrival_index": 2,
              "event_id": "E1",
              "trade_id": "T1",
              "decision": "DROP_REPLAY",
              "reason": "byte-equivalent normalized event_id already retained"
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: policy_version, active, states, tombstones, pending, versions, raw_history, audit"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f02-a05/static/article-hero.svg"
          },
          {
            "file": "audit-lineage.svg",
            "url": "https://thefintechbuilder.com/content/d01-f02-a05/static/audit-lineage.svg"
          },
          {
            "file": "duplicate-precedence.svg",
            "url": "https://thefintechbuilder.com/content/d01-f02-a05/static/duplicate-precedence.svg"
          }
        ],
        "mermaid": [
          {
            "file": "resolution-state.md",
            "caption": "Resolution state and evidence paths",
            "source": "stateDiagram-v2\n  [*] --> Absent\n  Absent --> Active: valid NEW\n  Active --> Active: linked current-head CORRECT\n  Active --> Canceled: linked CANCEL\n  Active --> Errored: linked ERROR\n  Absent --> Pending: missing parent\n  Active --> Quarantine: stale or cross-key reference\n  Absent --> Quarantine: ID or sequence conflict\n  Active --> Active: exact replay or duplicate NEW\n  Canceled --> Quarantine: later lifecycle action\n  Errored --> Quarantine: later lifecycle action"
          }
        ]
      },
      "references": [
        {
          "key": "NYSE-DTAQ-4.3",
          "title": "Daily TAQ Client Specifications",
          "author": "New York Stock Exchange / Intercontinental Exchange",
          "url": "https://www.nyse.com/publicdocs/nyse/data/Daily_TAQ_Client_Spec_v4.3.pdf"
        },
        {
          "key": "NASDAQ-ITCH-5.0",
          "title": "Nasdaq TotalView-ITCH",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHspecification.pdf"
        },
        {
          "key": "FIX-POSTTRADE",
          "title": "Business Area: Post-Trade",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/online-specification/business-area-posttrade/"
        },
        {
          "key": "FIX-487",
          "title": "TradeReportTransType",
          "author": "FIX Trading Community",
          "url": "https://fiximate.fixtrading.org/legacy/en/FIX.5.0SP2/tag487.html"
        },
        {
          "key": "Dataset and historical-example note",
          "title": "Dataset and historical-example note",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/cleaning-and-validation/duplicate-trade-resolver/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Duplicate-Trade-Resolver-Data-Quality-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/cleaning-and-validation/duplicate-trade-resolver/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F02-A06",
      "name": "Crossed/Locked Market Detector",
      "headline": null,
      "slug": "crossed-locked-market-detector",
      "path": "market-data-engineering/cleaning-and-validation/crossed-locked-market-detector",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F02",
        "family": "Cleaning and Validation",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/cleaning-and-validation/crossed-locked-market-detector",
        "entry": "classifyMarkets",
        "params": [
          "quotes",
          "options"
        ],
        "exports": [
          "classifyMarkets"
        ],
        "archetype": "row-classify",
        "signature": "classifyMarkets(quotes, options)"
      },
      "api": {
        "summary": "Classifies a quote as normal, locked (bid equals ask) or crossed (bid above ask). Crossed markets are usually a stale or misordered feed rather than a real arbitrage, which is exactly why they must be caught before anything downstream trusts the spread.",
        "params": [
          {
            "name": "quotes",
            "type": "Quote[]",
            "required": true,
            "description": "Quotes carrying `instrument`, `market_scope`, `feed`, `event_time`, `receive_time`, `sequence`, bid and ask.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "options",
            "type": "{ tolerance_ticks?: number; relative_tolerance_ppm?: number }",
            "required": false,
            "description": "Absolute tolerance in ticks and relative tolerance in parts per million, so a one-tick rounding artefact is not reported as a crossed book.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Verdict[]",
          "length": "same-as-input",
          "description": "One classification per quote with the margin by which it locked or crossed. Returns one verdict per input row rather than throwing, so a single bad record cannot abort the batch — and cannot pass unnoticed either."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a tolerance is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "classifyMarkets([{\"instrument\":\"SYNTH\",\"market_scope\":\"SYNTHETIC_CONSOLIDATED_TOP\",\"feed\":\"SYNTH-SIP\",\"event_time\":\"2026-07-20T13:30:00.000Z\",\"receive_time\":\"2026-07-20T13:30:00.003Z\",\"sequence\":1001,\"bid_source\":\"VENUE-A\",\"ask_source\":\"VENUE-B\",\"bid\":100,\"ask\":100.02,\"tick_size\":0.01},{\"instrument\":\"SYNTH\",\"market_scope\":\"SYNTHETIC_CONSOLIDATED_TOP\",\"feed\":\"SYNTH-SIP\",\"event_time\":\"2026-07-20T13:30:00.100Z\",\"receive_time\":\"2026-07-20T13:30:00.104Z\",\"sequence\":1002,\"bid_source\":\"VENUE-A\",\"ask_source\":\"VENUE-B\",\"bid\":100.01,\"ask\":100.01,\"tick_size\":0.01},{\"instrument\":\"SYNTH\",\"market_scope\":\"SYNTHETIC_CONSOLIDATED_TOP\",\"feed\":\"SYNTH-SIP\",\"event_time\":\"2026-07-20T13:30:00.200Z\",\"receive_time\":\"2026-07-20T13:30:00.207Z\",\"sequence\":1003,\"bid_source\":\"VENUE-A\",\"ask_source\":\"VENUE-C\",\"bid\":100.03,\"ask\":100.02,\"tick_size\":0.01}], {\"tolerance_ticks\":0,\"relative_tolerance_ppm\":0})",
        "args": [
          {
            "value": [
              {
                "instrument": "SYNTH",
                "market_scope": "SYNTHETIC_CONSOLIDATED_TOP",
                "feed": "SYNTH-SIP",
                "event_time": "2026-07-20T13:30:00.000Z",
                "receive_time": "2026-07-20T13:30:00.003Z",
                "sequence": 1001,
                "bid_source": "VENUE-A",
                "ask_source": "VENUE-B",
                "bid": 100,
                "ask": 100.02,
                "tick_size": 0.01
              },
              {
                "instrument": "SYNTH",
                "market_scope": "SYNTHETIC_CONSOLIDATED_TOP",
                "feed": "SYNTH-SIP",
                "event_time": "2026-07-20T13:30:00.100Z",
                "receive_time": "2026-07-20T13:30:00.104Z",
                "sequence": 1002,
                "bid_source": "VENUE-A",
                "ask_source": "VENUE-B",
                "bid": 100.01,
                "ask": 100.01,
                "tick_size": 0.01
              },
              {
                "instrument": "SYNTH",
                "market_scope": "SYNTHETIC_CONSOLIDATED_TOP",
                "feed": "SYNTH-SIP",
                "event_time": "2026-07-20T13:30:00.200Z",
                "receive_time": "2026-07-20T13:30:00.207Z",
                "sequence": 1003,
                "bid_source": "VENUE-A",
                "ask_source": "VENUE-C",
                "bid": 100.03,
                "ask": 100.02,
                "tick_size": 0.01
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 8
            }
          },
          {
            "value": {
              "tolerance_ticks": 0,
              "relative_tolerance_ppm": 0
            },
            "elided": null
          }
        ],
        "output": [
          {
            "instrument": "SYNTH",
            "market_scope": "SYNTHETIC_CONSOLIDATED_TOP",
            "feed": "SYNTH-SIP",
            "event_time": "2026-07-20T13:30:00.000Z",
            "receive_time": "2026-07-20T13:30:00.003Z",
            "sequence": 1001,
            "bid_source": "VENUE-A",
            "ask_source": "VENUE-B",
            "bid": 100,
            "ask": 100.02,
            "tick_size": 0.01,
            "index": 0,
            "spread": 0.01999999999999602,
            "spread_ticks": 1.999999999999602
          },
          {
            "instrument": "SYNTH",
            "market_scope": "SYNTHETIC_CONSOLIDATED_TOP",
            "feed": "SYNTH-SIP",
            "event_time": "2026-07-20T13:30:00.100Z",
            "receive_time": "2026-07-20T13:30:00.104Z",
            "sequence": 1002,
            "bid_source": "VENUE-A",
            "ask_source": "VENUE-B",
            "bid": 100.01,
            "ask": 100.01,
            "tick_size": 0.01,
            "index": 1,
            "spread": 0,
            "spread_ticks": 0
          },
          {
            "instrument": "SYNTH",
            "market_scope": "SYNTHETIC_CONSOLIDATED_TOP",
            "feed": "SYNTH-SIP",
            "event_time": "2026-07-20T13:30:00.200Z",
            "receive_time": "2026-07-20T13:30:00.207Z",
            "sequence": 1003,
            "bid_source": "VENUE-A",
            "ask_source": "VENUE-C",
            "bid": 100.03,
            "ask": 100.02,
            "tick_size": 0.01,
            "index": 2,
            "spread": -0.010000000000005116,
            "spread_ticks": -1.0000000000005116
          }
        ],
        "outputElided": {
          "kind": "array",
          "shown": 3,
          "total": 8
        },
        "outputShape": "array of 8 objects"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f02-a06/static/article-hero.svg"
          },
          {
            "file": "spread-geometry.svg",
            "url": "https://thefintechbuilder.com/content/d01-f02-a06/static/spread-geometry.svg"
          }
        ],
        "mermaid": [
          {
            "file": "market-flow.md",
            "caption": "Geometry-to-review flow",
            "source": "flowchart LR\n    A[\"Snapshot plus scope, feed, and clocks\"] --> B{\"Context and values valid?\"}\n    B -->|No| C[\"Retain INVALID plus reason\"]\n    B -->|Yes| D[\"Compute spread, ticks, and explicit boundary\"]\n    D --> E{\"Compare spread with boundary\"}\n    E -->|Above| F[\"NORMAL observation\"]\n    E -->|Within| G[\"LOCKED observation\"]\n    E -->|Below| H[\"CROSSED observation\"]\n    F --> I[\"Attach lineage and warnings\"]\n    G --> I\n    H --> I\n    I --> J[\"Separate review or policy layer\"]"
          }
        ]
      },
      "references": [
        {
          "key": "SEC-605-FAQ - Frequently Asked Questions: Rule 605 of Regulation NMS",
          "title": "SEC-605-FAQ - Frequently Asked Questions: Rule 605 of Regulation NMS",
          "author": "U.S. Securities and Exchange Commission, Division of Trading and Markets staff",
          "url": "https://www.sec.gov/rules-regulations/staff-guidance/trading-markets-frequently-asked-questions/frequently-asked-questions-rule-605-regulation-nms"
        },
        {
          "key": "SEC-610-611-FAQ - Responses Concerning Rules 610 and 611",
          "title": "SEC-610-611-FAQ - Responses Concerning Rules 610 and 611",
          "author": "U.S. Securities and Exchange Commission, Division of Trading and Markets staff",
          "url": "https://www.sec.gov/divisions/marketreg/nmsfaq610-11.htm"
        },
        {
          "key": "SEC-2026-PROPOSAL - Trade-Through Rule and Locked and Crossed Markets Provisions",
          "title": "SEC-2026-PROPOSAL - Trade-Through Rule and Locked and Crossed Markets Provisions",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/rules-regulations/2026/06/s7-2026-20"
        },
        {
          "key": "SEC-TICK-SIZE-RELIEF - 2025 exemptive order and compliance timing",
          "title": "SEC-TICK-SIZE-RELIEF - 2025 exemptive order and compliance timing",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/newsroom/press-releases/2025-130-sec-issues-exemptive-order-regarding-compliance-certain-rules-under-regulation-nms"
        },
        {
          "key": "PY-FLOAT - Python floating-point information",
          "title": "PY-FLOAT - Python floating-point information",
          "author": "Python Software Foundation",
          "url": "https://docs.python.org/3/library/sys.html#sys.float_info"
        },
        {
          "key": "ECMASCRIPT-NUMBER - Number.EPSILON",
          "title": "ECMASCRIPT-NUMBER - Number.EPSILON",
          "author": "ECMA International",
          "url": "https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.epsilon"
        },
        {
          "key": "Evidence classification and historical-example decision",
          "title": "Evidence classification and historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/cleaning-and-validation/crossed-locked-market-detector/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Crossed-Locked-Market-Detector-Data-Quality-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/cleaning-and-validation/crossed-locked-market-detector/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F03-A01",
      "name": "Previous-Tick Interpolation",
      "headline": null,
      "slug": "previous-tick-interpolation",
      "path": "market-data-engineering/time-synchronization/previous-tick-interpolation",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F03",
        "family": "Time Synchronization",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/time-synchronization/previous-tick-interpolation",
        "entry": "previousTick",
        "params": [
          "observations",
          "requests",
          "maxStalenessMs"
        ],
        "exports": [
          "previousTick"
        ],
        "archetype": "record-transform",
        "signature": "previousTick(observations, requests, maxStalenessMs)"
      },
      "api": {
        "summary": "Samples a series onto a grid by carrying the last value known *at that moment* forward. The only interpolation that is safe on live data: it never uses a value that had not yet arrived.",
        "params": [
          {
            "name": "observations",
            "type": "Observation[]",
            "required": true,
            "description": "Observations carrying both `event_time` and `available_time`, which is what allows the as-of rule to be applied honestly.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "requests",
            "type": "{ grid_time: string; query_time: string }[]",
            "required": true,
            "description": "The grid points to sample, each with the knowledge time the answer must respect.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "maxStalenessMs",
            "type": "number",
            "required": true,
            "description": "How old a carried-forward value may be before the sample is reported unusable rather than silently stale.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Sample[]",
          "length": "same-as-input",
          "description": "One sample per request with the value used, its age, and whether the staleness budget was met."
        },
        "warmup": null,
        "errors": [
          {
            "when": "maxStalenessMs is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n + m)",
          "space": "O(m)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "previousTick([{\"instrument\":\"A\",\"event_time\":\"2026-01-02T14:30:00.100Z\",\"available_time\":\"2026-01-02T14:30:00.180Z\",\"revision\":0,\"value\":100},{\"instrument\":\"A\",\"event_time\":\"2026-01-02T14:30:00.100Z\",\"available_time\":\"2026-01-02T14:30:01.400Z\",\"revision\":1,\"value\":99.8},{\"instrument\":\"A\",\"event_time\":\"2026-01-02T14:30:02.200Z\",\"available_time\":\"2026-01-02T14:30:02.260Z\",\"revision\":0,\"value\":100.4}], [{\"grid_time\":\"2026-01-02T14:30:00.000Z\",\"query_time\":\"2026-01-02T14:30:00.000Z\"},{\"grid_time\":\"2026-01-02T14:30:01.000Z\",\"query_time\":\"2026-01-02T14:30:01.000Z\"},{\"grid_time\":\"2026-01-02T14:30:01.000Z\",\"query_time\":\"2026-01-02T14:30:02.000Z\"}], 1500)",
        "args": [
          {
            "value": [
              {
                "instrument": "A",
                "event_time": "2026-01-02T14:30:00.100Z",
                "available_time": "2026-01-02T14:30:00.180Z",
                "revision": 0,
                "value": 100
              },
              {
                "instrument": "A",
                "event_time": "2026-01-02T14:30:00.100Z",
                "available_time": "2026-01-02T14:30:01.400Z",
                "revision": 1,
                "value": 99.8
              },
              {
                "instrument": "A",
                "event_time": "2026-01-02T14:30:02.200Z",
                "available_time": "2026-01-02T14:30:02.260Z",
                "revision": 0,
                "value": 100.4
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": [
              {
                "grid_time": "2026-01-02T14:30:00.000Z",
                "query_time": "2026-01-02T14:30:00.000Z"
              },
              {
                "grid_time": "2026-01-02T14:30:01.000Z",
                "query_time": "2026-01-02T14:30:01.000Z"
              },
              {
                "grid_time": "2026-01-02T14:30:01.000Z",
                "query_time": "2026-01-02T14:30:02.000Z"
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": 1500,
            "elided": null
          }
        ],
        "output": [
          {
            "instrument": "A",
            "grid_time": "2026-01-02T14:30:00.000Z",
            "query_time": "2026-01-02T14:30:00.000Z",
            "value": null,
            "source_event_time": null,
            "source_available_time": null,
            "source_revision": null,
            "staleness_ms": null,
            "status": "no_history"
          },
          {
            "instrument": "A",
            "grid_time": "2026-01-02T14:30:01.000Z",
            "query_time": "2026-01-02T14:30:01.000Z",
            "value": 100,
            "source_event_time": "2026-01-02T14:30:00.100Z",
            "source_available_time": "2026-01-02T14:30:00.180Z",
            "source_revision": 0,
            "staleness_ms": 900,
            "status": "carried"
          },
          {
            "instrument": "A",
            "grid_time": "2026-01-02T14:30:01.000Z",
            "query_time": "2026-01-02T14:30:02.000Z",
            "value": 99.8,
            "source_event_time": "2026-01-02T14:30:00.100Z",
            "source_available_time": "2026-01-02T14:30:01.400Z",
            "source_revision": 1,
            "staleness_ms": 900,
            "status": "carried"
          }
        ],
        "outputElided": {
          "kind": "array",
          "shown": 3,
          "total": 10
        },
        "outputShape": "array of 10 objects"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f03-a01/static/article-hero.svg"
          },
          {
            "file": "causality-and-staleness.svg",
            "url": "https://thefintechbuilder.com/content/d01-f03-a01/static/causality-and-staleness.svg"
          }
        ],
        "mermaid": [
          {
            "file": "causal-flow.md",
            "caption": "Point-in-time previous-tick decision",
            "source": "flowchart LR\n    A[\"Stored source revisions\"] --> B{\"Event time <= grid time?\"}\n    B -->|No| C[\"No history\"]\n    B -->|Yes| D{\"Availability time <= query time?\"}\n    D -->|No| E[\"Not yet available\"]\n    D -->|Yes| F[\"Latest event, latest available revision\"]\n    F --> G{\"Source age <= expiry?\"}\n    G -->|Yes| H[\"Exact or carried value\"]\n    G -->|No| I[\"Stale missing value with lineage\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R01 - RFC 3339: Date and Time on the Internet: Timestamps",
          "title": "R01 - RFC 3339: Date and Time on the Internet: Timestamps",
          "author": "Internet Engineering Task Force; G. Klyne and C. Newman",
          "url": null
        },
        {
          "key": "R02 - On covariance estimation of non-synchronously observed diffusion processes",
          "title": "R02 - On covariance estimation of non-synchronously observed diffusion processes",
          "author": "Takaki Hayashi and Nakahiro Yoshida",
          "url": null
        },
        {
          "key": "R03 - NYSE Holidays and Trading Hours",
          "title": "R03 - NYSE Holidays and Trading Hours",
          "author": "New York Stock Exchange",
          "url": null
        },
        {
          "key": "Implementation choices in this package",
          "title": "Implementation choices in this package",
          "author": null,
          "url": null
        },
        {
          "key": "Dataset and historical-evidence classification",
          "title": "Dataset and historical-evidence classification",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/time-synchronization/previous-tick-interpolation/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Previous-Tick-Interpolation-Time-Synchronization-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/time-synchronization/previous-tick-interpolation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F03-A02",
      "name": "Linear Quote Interpolation",
      "headline": null,
      "slug": "linear-quote-interpolation",
      "path": "market-data-engineering/time-synchronization/linear-quote-interpolation",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F03",
        "family": "Time Synchronization",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/time-synchronization/linear-quote-interpolation",
        "entry": "linearQuoteInterpolation",
        "params": [
          "quotes",
          "targets",
          "maxGapMs"
        ],
        "exports": [
          "linearQuoteInterpolation"
        ],
        "archetype": "record-transform",
        "signature": "linearQuoteInterpolation(quotes, targets, maxGapMs)"
      },
      "api": {
        "summary": "Interpolates between the quotes either side of a target time. More accurate than carrying forward, and **not causal** — it uses a quote from after the target, so it belongs in research and never in a live path.",
        "params": [
          {
            "name": "quotes",
            "type": "Quote[]",
            "required": true,
            "description": "Quotes with `event_time`, `available_time`, bid and ask.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "targets",
            "type": "Target[]",
            "required": true,
            "description": "Times to interpolate at, each with the evaluation time that bounds what may be used.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "maxGapMs",
            "type": "number",
            "required": true,
            "description": "Widest gap between bracketing quotes that may still be interpolated across.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Sample[]",
          "length": "same-as-input",
          "description": "One sample per target with both bracketing quotes, the interpolated value, and whether the gap budget was met."
        },
        "warmup": null,
        "errors": [
          {
            "when": "maxGapMs is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n + m)",
          "space": "O(m)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "linearQuoteInterpolation([{\"instrument\":\"A\",\"venue\":\"X\",\"session_id\":\"S\",\"event_time\":\"2026-01-01T00:00:00.000Z\",\"available_time\":\"2026-01-01T00:00:00.100Z\",\"bid\":99,\"ask\":101},{\"instrument\":\"A\",\"venue\":\"X\",\"session_id\":\"S\",\"event_time\":\"2026-01-01T00:00:02.000Z\",\"available_time\":\"2026-01-01T00:00:02.120Z\",\"bid\":101,\"ask\":103}], [{\"instrument\":\"A\",\"venue\":\"X\",\"session_id\":\"S\",\"target_time\":\"2026-01-01T00:00:01.000Z\",\"evaluation_time\":\"2026-01-01T00:00:01.000Z\"},{\"instrument\":\"A\",\"venue\":\"X\",\"session_id\":\"S\",\"target_time\":\"2026-01-01T00:00:01.000Z\",\"evaluation_time\":\"2026-01-01T00:00:02.120Z\"},{\"instrument\":\"A\",\"venue\":\"X\",\"session_id\":\"S\",\"target_time\":\"2026-01-01T00:00:00.000Z\",\"evaluation_time\":\"2026-01-01T00:00:00.000Z\"}], 2000)",
        "args": [
          {
            "value": [
              {
                "instrument": "A",
                "venue": "X",
                "session_id": "S",
                "event_time": "2026-01-01T00:00:00.000Z",
                "available_time": "2026-01-01T00:00:00.100Z",
                "bid": 99,
                "ask": 101
              },
              {
                "instrument": "A",
                "venue": "X",
                "session_id": "S",
                "event_time": "2026-01-01T00:00:02.000Z",
                "available_time": "2026-01-01T00:00:02.120Z",
                "bid": 101,
                "ask": 103
              }
            ],
            "elided": null
          },
          {
            "value": [
              {
                "instrument": "A",
                "venue": "X",
                "session_id": "S",
                "target_time": "2026-01-01T00:00:01.000Z",
                "evaluation_time": "2026-01-01T00:00:01.000Z"
              },
              {
                "instrument": "A",
                "venue": "X",
                "session_id": "S",
                "target_time": "2026-01-01T00:00:01.000Z",
                "evaluation_time": "2026-01-01T00:00:02.120Z"
              },
              {
                "instrument": "A",
                "venue": "X",
                "session_id": "S",
                "target_time": "2026-01-01T00:00:00.000Z",
                "evaluation_time": "2026-01-01T00:00:00.000Z"
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": 2000,
            "elided": null
          }
        ],
        "output": [
          {
            "instrument": "A",
            "venue": "X",
            "session_id": "S",
            "target_time": "2026-01-01T00:00:01.000Z",
            "evaluation_time": "2026-01-01T00:00:01.000Z",
            "bid": null,
            "ask": null,
            "status": "right_not_available",
            "reason": "right_endpoint_arrives_after_evaluation",
            "interpolated": false,
            "observable": false,
            "left_event_time": "2026-01-01T00:00:00.000Z",
            "right_event_time": "2026-01-01T00:00:02.000Z",
            "left_available_time": "2026-01-01T00:00:00.100Z"
          },
          {
            "instrument": "A",
            "venue": "X",
            "session_id": "S",
            "target_time": "2026-01-01T00:00:01.000Z",
            "evaluation_time": "2026-01-01T00:00:02.120Z",
            "bid": 100,
            "ask": 102,
            "status": "linear",
            "reason": "both_endpoints_available",
            "interpolated": true,
            "observable": false,
            "left_event_time": "2026-01-01T00:00:00.000Z",
            "right_event_time": "2026-01-01T00:00:02.000Z",
            "left_available_time": "2026-01-01T00:00:00.100Z"
          },
          {
            "instrument": "A",
            "venue": "X",
            "session_id": "S",
            "target_time": "2026-01-01T00:00:00.000Z",
            "evaluation_time": "2026-01-01T00:00:00.000Z",
            "bid": null,
            "ask": null,
            "status": "exact_not_available",
            "reason": "exact_record_arrives_after_evaluation",
            "interpolated": false,
            "observable": false,
            "left_event_time": "2026-01-01T00:00:00.000Z",
            "right_event_time": "2026-01-01T00:00:00.000Z",
            "left_available_time": "2026-01-01T00:00:00.100Z"
          }
        ],
        "outputElided": {
          "kind": "array",
          "shown": 3,
          "total": 5
        },
        "outputShape": "array of 5 objects"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f03-a02/static/article-hero.svg"
          },
          {
            "file": "linear-leakage.svg",
            "url": "https://thefintechbuilder.com/content/d01-f03-a02/static/linear-leakage.svg"
          }
        ],
        "mermaid": [
          {
            "file": "interpolation-flow.md",
            "caption": "Interpolation eligibility and knowledge boundary",
            "source": "flowchart LR\n    A[\"Target plus evaluation cutoff\"] --> B{\"Exact event?\"}\n    B -->|Yes| C{\"Exact record available?\"}\n    C -->|No| D[\"exact_not_available\"]\n    C -->|Yes| E[\"exact observed quote\"]\n    B -->|No| F{\"Same-partition bracket?\"}\n    F -->|No| G[\"unavailable; no extrapolation\"]\n    F -->|Yes| H{\"Gap within inclusive limit?\"}\n    H -->|No| I[\"gap_too_wide\"]\n    H -->|Yes| J{\"Both endpoints available?\"}\n    J -->|No| K[\"block at knowledge boundary\"]\n    J -->|Yes| L[\"linear derived quote; observable=false\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R01",
          "title": "NIST Digital Library of Mathematical Functions, Section 3.3",
          "author": "National Institute of Standards and Technology",
          "url": null
        },
        {
          "key": "R02",
          "title": "SEC Quote Life Report Methodology",
          "author": "U.S. Securities and Exchange Commission, Division of Economic and Risk Analysis",
          "url": null
        },
        {
          "key": "R03",
          "title": "Frequently Asked Questions: Rule 605 of Regulation NMS",
          "author": "U.S. Securities and Exchange Commission staff",
          "url": null
        },
        {
          "key": "R04",
          "title": "On covariance estimation of non-synchronously observed diffusion processes",
          "author": "Takaki Hayashi and Nakahiro Yoshida",
          "url": null
        },
        {
          "key": "R05",
          "title": "RFC 3339: Date and Time on the Internet",
          "author": "IETF; Graham Klyne and Chris Newman",
          "url": null
        },
        {
          "key": "Evidence classification",
          "title": "Evidence classification",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/time-synchronization/linear-quote-interpolation/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Linear-Quote-Interpolation-Time-Synchronization-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/time-synchronization/linear-quote-interpolation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F03-A03",
      "name": "Refresh-Time Sampling",
      "headline": null,
      "slug": "refresh-time-sampling",
      "path": "market-data-engineering/time-synchronization/refresh-time-sampling",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F03",
        "family": "Time Synchronization",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/time-synchronization/refresh-time-sampling",
        "entry": "refreshTimeSample",
        "params": [
          "observations",
          "requiredInstruments",
          "maxStalenessMs"
        ],
        "exports": [
          "refreshTimeSample"
        ],
        "archetype": "record-transform",
        "signature": "refreshTimeSample(observations, requiredInstruments, maxStalenessMs)"
      },
      "api": {
        "summary": "Builds a common clock for several instruments by advancing only when every one of them has refreshed. The standard remedy for the bias that non-synchronous trading introduces into correlations.",
        "params": [
          {
            "name": "observations",
            "type": "Observation[]",
            "required": true,
            "description": "Observations across all instruments, each with `partition`, `instrument`, `event_time` and `available_at`.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "requiredInstruments",
            "type": "string[]",
            "required": true,
            "description": "The instruments that must all have refreshed before a refresh time is emitted.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "maxStalenessMs",
            "type": "number",
            "required": true,
            "description": "How old any instrument's value may be at a refresh time.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ rows, partitions }",
          "description": "The synchronised rows, plus per-partition diagnostics showing which instrument was the binding constraint at each step."
        },
        "warmup": null,
        "errors": [
          {
            "when": "requiredInstruments is empty",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "refreshTimeSample([{\"partition\":\"P1\",\"instrument\":\"A\",\"record_id\":\"a1\",\"revision\":0,\"event_time\":\"2026-01-01T00:00:01.000Z\",\"available_at\":\"2026-01-01T00:00:01.000Z\",\"value\":1},{\"partition\":\"P1\",\"instrument\":\"A\",\"record_id\":\"a3\",\"revision\":0,\"event_time\":\"2026-01-01T00:00:03.000Z\",\"available_at\":\"2026-01-01T00:00:03.000Z\",\"value\":3},{\"partition\":\"P1\",\"instrument\":\"A\",\"record_id\":\"a4\",\"revision\":0,\"event_time\":\"2026-01-01T00:00:04.000Z\",\"available_at\":\"2026-01-01T00:00:04.000Z\",\"value\":4}], [\"A\",\"B\"], 5000)",
        "args": [
          {
            "value": [
              {
                "partition": "P1",
                "instrument": "A",
                "record_id": "a1",
                "revision": 0,
                "event_time": "2026-01-01T00:00:01.000Z",
                "available_at": "2026-01-01T00:00:01.000Z",
                "value": 1
              },
              {
                "partition": "P1",
                "instrument": "A",
                "record_id": "a3",
                "revision": 0,
                "event_time": "2026-01-01T00:00:03.000Z",
                "available_at": "2026-01-01T00:00:03.000Z",
                "value": 3
              },
              {
                "partition": "P1",
                "instrument": "A",
                "record_id": "a4",
                "revision": 0,
                "event_time": "2026-01-01T00:00:04.000Z",
                "available_at": "2026-01-01T00:00:04.000Z",
                "value": 4
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": [
              "A",
              "B"
            ],
            "elided": null
          },
          {
            "value": 5000,
            "elided": null
          }
        ],
        "output": {
          "rows": [
            {
              "partition": "P1",
              "sequence": 1,
              "previous_refresh_available_at": null,
              "refresh_available_at": "2026-01-01T00:00:02.000Z",
              "controller_instruments": [
                "B"
              ],
              "status": "accepted",
              "values": {
                "A": 1,
                "B": 20
              },
              "sources": {
                "A": {
                  "record_id": "a1",
                  "revision": 0,
                  "event_time": "2026-01-01T00:00:01.000Z",
                  "available_at": "2026-01-01T00:00:01.000Z"
                },
                "B": {
                  "record_id": "b2",
                  "revision": 0,
                  "event_time": "2026-01-01T00:00:02.000Z",
                  "available_at": "2026-01-01T00:00:02.000Z"
                }
              },
              "event_age_ms": {
                "A": 1000,
                "B": 0
              },
              "arrivals_by_instrument": {
                "A": 1,
                "B": 1
              },
              "discarded_updates": 0
            },
            {
              "partition": "P1",
              "sequence": 2,
              "previous_refresh_available_at": "2026-01-01T00:00:02.000Z",
              "refresh_available_at": "2026-01-01T00:00:04.000Z",
              "controller_instruments": [
                "B"
              ],
              "status": "accepted",
              "values": {
                "A": 4,
                "B": 40
              },
              "sources": {
                "A": {
                  "record_id": "a4",
                  "revision": 0,
                  "event_time": "2026-01-01T00:00:04.000Z",
                  "available_at": "2026-01-01T00:00:04.000Z"
                },
                "B": {
                  "record_id": "b4",
                  "revision": 0,
                  "event_time": "2026-01-01T00:00:04.000Z",
                  "available_at": "2026-01-01T00:00:04.000Z"
                }
              },
              "event_age_ms": {
                "A": 0,
                "B": 0
              },
              "arrivals_by_instrument": {
                "A": 2,
                "B": 1
              },
              "discarded_updates": 1
            }
          ],
          "partitions": [
            {
              "partition": "P1",
              "input_updates": 5,
              "refresh_candidates": 2,
              "accepted_rows": 2,
              "stale_rows": 0,
              "discarded_updates": 1,
              "unmatched_tail_updates": 0,
              "loss_fraction": {
                "numerator": 1,
                "denominator": 5
              }
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: rows, partitions"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f03-a03/static/article-hero.svg"
          },
          {
            "file": "refresh-barrier.svg",
            "url": "https://thefintechbuilder.com/content/d01-f03-a03/static/refresh-barrier.svg"
          }
        ],
        "mermaid": [
          {
            "file": "refresh-sequence.md",
            "caption": "Availability-time refresh sequence",
            "source": "sequenceDiagram\n    participant A as Fast stream A\n    participant B as Medium stream B\n    participant C as Sparse stream C\n    participant S as Refresh sampler\n    A->>S: first new availability A1\n    A->>S: later availability A2\n    B->>S: first new availability B1\n    Note over S: wait, C is missing\n    C->>S: first new availability C1\n    S->>S: barrier = max(A1, B1, C1)\n    S-->>S: select latest known effective event per stream"
          }
        ]
      },
      "references": [
        {
          "key": "R01",
          "title": "Multivariate realised kernels",
          "author": "Ole E. Barndorff-Nielsen, Peter R. Hansen, Asger Lunde, and Neil Shephard",
          "url": null
        },
        {
          "key": "R02",
          "title": "On covariance estimation of non-synchronously observed diffusion processes",
          "author": "Takaki Hayashi and Nakahiro Yoshida",
          "url": null
        },
        {
          "key": "R03",
          "title": "RFC 3339",
          "author": "Internet Engineering Task Force; Graham Klyne and Chris Newman",
          "url": null
        },
        {
          "key": "Evidence classification",
          "title": "Evidence classification",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/time-synchronization/refresh-time-sampling/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Refresh-Time-Sampling-Time-Synchronization-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/time-synchronization/refresh-time-sampling/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F03-A04",
      "name": "Exchange-Calendar Alignment",
      "headline": null,
      "slug": "exchange-calendar-alignment",
      "path": "market-data-engineering/time-synchronization/exchange-calendar-alignment",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F03",
        "family": "Time Synchronization",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/time-synchronization/exchange-calendar-alignment",
        "entry": "validateCalendar",
        "params": [
          "bundle"
        ],
        "exports": [
          "localWallToUtc",
          "validateCalendar",
          "alignEvents",
          "sessionGrid"
        ],
        "archetype": "row-classify",
        "signature": "validateCalendar(bundle)"
      },
      "api": {
        "summary": "Validates a trading-calendar bundle before anything is aligned to it: that sessions do not overlap, that closures are consistent with sessions, and that the licence terms permitting redistribution are present.",
        "params": [
          {
            "name": "bundle",
            "type": "{ license, calendar, sessions, closed_dates }",
            "required": true,
            "description": "The calendar under test together with its licence metadata. Calendars are usually licensed data, which is why the licence block is part of the contract rather than an afterthought.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "void",
          "description": "Returns nothing on success. Validation is a gate, not a transform — the value of calling it is the failure."
        },
        "warmup": null,
        "errors": [
          {
            "when": "sessions overlap or are out of order",
            "behaviour": "throws"
          },
          {
            "when": "a closed date contradicts a defined session",
            "behaviour": "throws"
          },
          {
            "when": "required licence metadata is missing",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "validateCalendar({\"license\":\"CC0-1.0 teaching transcription; contains calendar facts, not market data\",\"calendar\":{\"calendar_id\":\"nyse-tape-a-core-teaching\",\"calendar_version\":\"2026-07-22\",\"retrieved_at\":\"2026-07-22\",\"venue\":\"New York Stock Exchange\",\"market\":\"NYSE Tape A core equities\",\"time_zone\":\"America/New_York\",\"tzdb_version\":\"2026c\",\"boundary\":\"[open, close)\",\"outside_coverage\":\"fail_closed\",\"local_time_policy\":\"reject_nonexistent_require_fold_for_ambiguous\",\"opening_auction_policy\":\"include_at_open\",\"closing_auction_policy\":\"exclude_at_close\",\"extended_hours_policy\":\"exclude\",\"supported_dates\":[\"2018-12-05\",\"2025-03-07\",\"2025-03-10\",\"2025-07-03\",\"2025-07-04\",\"2026-07-03\"]},\"sessions\":[{\"session_id\":\"XNYS-2025-03-07-CORE\",\"session_date\":\"2025-03-07\",\"local_open\":\"2025-03-07T09:30:00\",\"local_close\":\"2025-03-07T16:00:00\",\"open\":\"2025-03-07T14:30:00.000Z\",\"close\":\"2025-03-07T21:00:00.000Z\",\"session_type\":\"regular\",\"source_ids\":[\"R03\",\"R04\"]},{\"session_id\":\"XNYS-2025-03-10-CORE\",\"session_date\":\"2025-03-10\",\"local_open\":\"2025-03-10T09:30:00\",\"local_close\":\"2025-03-10T16:00:00\",\"open\":\"2025-03-10T13:30:00.000Z\",\"close\":\"2025-03-10T20:00:00.000Z\",\"session_type\":\"regular\",\"source_ids\":[\"R03\",\"R04\"]},{\"session_id\":\"XNYS-2025-07-03-CORE\",\"session_date\":\"2025-07-03\",\"local_open\":\"2025-07-03T09:30:00\",\"local_close\":\"2025-07-03T13:00:00\",\"open\":\"2025-07-03T13:30:00.000Z\",\"close\":\"2025-07-03T17:00:00.000Z\",\"session_type\":\"early_close\",\"source_ids\":[\"R02\",\"R03\",\"R04\"]}],\"closed_dates\":[{\"session_date\":\"2018-12-05\",\"closure_type\":\"exceptional_closure\",\"reason\":\"National Day of Mourning for President George H. W. Bush\",\"source_ids\":[\"R05\"]},{\"session_date\":\"2025-07-04\",\"closure_type\":\"holiday\",\"reason\":\"Independence Day\",\"source_ids\":[\"R02\",\"R03\"]},{\"session_date\":\"2026-07-03\",\"closure_type\":\"holiday\",\"reason\":\"Independence Day observed\",\"source_ids\":[\"R01\"]}]})",
        "args": [
          {
            "value": {
              "license": "CC0-1.0 teaching transcription; contains calendar facts, not market data",
              "calendar": {
                "calendar_id": "nyse-tape-a-core-teaching",
                "calendar_version": "2026-07-22",
                "retrieved_at": "2026-07-22",
                "venue": "New York Stock Exchange",
                "market": "NYSE Tape A core equities",
                "time_zone": "America/New_York",
                "tzdb_version": "2026c",
                "boundary": "[open, close)",
                "outside_coverage": "fail_closed",
                "local_time_policy": "reject_nonexistent_require_fold_for_ambiguous",
                "opening_auction_policy": "include_at_open",
                "closing_auction_policy": "exclude_at_close",
                "extended_hours_policy": "exclude",
                "supported_dates": [
                  "2018-12-05",
                  "2025-03-07",
                  "2025-03-10",
                  "2025-07-03",
                  "2025-07-04",
                  "2026-07-03"
                ]
              },
              "sessions": [
                {
                  "session_id": "XNYS-2025-03-07-CORE",
                  "session_date": "2025-03-07",
                  "local_open": "2025-03-07T09:30:00",
                  "local_close": "2025-03-07T16:00:00",
                  "open": "2025-03-07T14:30:00.000Z",
                  "close": "2025-03-07T21:00:00.000Z",
                  "session_type": "regular",
                  "source_ids": [
                    "R03",
                    "R04"
                  ]
                },
                {
                  "session_id": "XNYS-2025-03-10-CORE",
                  "session_date": "2025-03-10",
                  "local_open": "2025-03-10T09:30:00",
                  "local_close": "2025-03-10T16:00:00",
                  "open": "2025-03-10T13:30:00.000Z",
                  "close": "2025-03-10T20:00:00.000Z",
                  "session_type": "regular",
                  "source_ids": [
                    "R03",
                    "R04"
                  ]
                },
                {
                  "session_id": "XNYS-2025-07-03-CORE",
                  "session_date": "2025-07-03",
                  "local_open": "2025-07-03T09:30:00",
                  "local_close": "2025-07-03T13:00:00",
                  "open": "2025-07-03T13:30:00.000Z",
                  "close": "2025-07-03T17:00:00.000Z",
                  "session_type": "early_close",
                  "source_ids": [
                    "R02",
                    "R03",
                    "R04"
                  ]
                }
              ],
              "closed_dates": [
                {
                  "session_date": "2018-12-05",
                  "closure_type": "exceptional_closure",
                  "reason": "National Day of Mourning for President George H. W. Bush",
                  "source_ids": [
                    "R05"
                  ]
                },
                {
                  "session_date": "2025-07-04",
                  "closure_type": "holiday",
                  "reason": "Independence Day",
                  "source_ids": [
                    "R02",
                    "R03"
                  ]
                },
                {
                  "session_date": "2026-07-03",
                  "closure_type": "holiday",
                  "reason": "Independence Day observed",
                  "source_ids": [
                    "R01"
                  ]
                }
              ]
            },
            "elided": null
          }
        ],
        "outputElided": null,
        "outputShape": "undefined"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f03-a04/static/article-hero.svg"
          },
          {
            "file": "dst-session-alignment.svg",
            "url": "https://thefintechbuilder.com/content/d01-f03-a04/static/dst-session-alignment.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calendar-flow.md",
            "caption": "Calendar alignment decision flow",
            "source": "flowchart LR\n  A[\"Pinned venue and versioned calendar\"] --> B[\"Convert UTC event to named-zone date\"]\n  B --> C{\"Date explicitly supported?\"}\n  C -->|No| D[\"Fail closed: calendar_unsupported\"]\n  C -->|Closure| E[\"closed_date plus source evidence\"]\n  C -->|Open session| F{\"Kind allowed and open <= t < close?\"}\n  F -->|Yes| G[\"in_session plus lineage\"]\n  F -->|No| H[\"outside_session or excluded_by_policy\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R01 - NYSE Holidays and Trading Hours",
          "title": "R01 - NYSE Holidays and Trading Hours",
          "author": null,
          "url": null
        },
        {
          "key": "R02 - 2025 NYSE Trading Calendar",
          "title": "R02 - 2025 NYSE Trading Calendar",
          "author": null,
          "url": null
        },
        {
          "key": "R03 - NYSE 2025-2027 Holidays and Trading Hours snapshot",
          "title": "R03 - NYSE 2025-2027 Holidays and Trading Hours snapshot",
          "author": null,
          "url": null
        },
        {
          "key": "R04 - IANA Time Zone Database",
          "title": "R04 - IANA Time Zone Database",
          "author": null,
          "url": null
        },
        {
          "key": "R05 - New York Stock Exchange to Honor President George H. W. Bush",
          "title": "R05 - New York Stock Exchange to Honor President George H. W. Bush",
          "author": null,
          "url": null
        },
        {
          "key": "R06 - RFC 3339: Date and Time on the Internet",
          "title": "R06 - RFC 3339: Date and Time on the Internet",
          "author": null,
          "url": null
        },
        {
          "key": "R07 - RFC 9557: Date and Time on the Internet with Additional Information",
          "title": "R07 - RFC 9557: Date and Time on the Internet with Additional Information",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence classification",
          "title": "Evidence classification",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/time-synchronization/exchange-calendar-alignment/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Exchange-Calendar-Alignment-Time-Synchronization-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/time-synchronization/exchange-calendar-alignment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F03-A05",
      "name": "Asynchronous Return Alignment",
      "headline": null,
      "slug": "asynchronous-return-alignment",
      "path": "market-data-engineering/time-synchronization/asynchronous-return-alignment",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F03",
        "family": "Time Synchronization",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/time-synchronization/asynchronous-return-alignment",
        "entry": "classifyIntervalPair",
        "params": [
          "left",
          "right"
        ],
        "exports": [
          "classifyIntervalPair",
          "diagnoseAsynchronousReturnAlignment"
        ],
        "archetype": "row-classify",
        "signature": "classifyIntervalPair(left, right)"
      },
      "api": {
        "summary": "Compares two return intervals and reports exactly how they overlap. Correlating returns measured over intervals that only partly coincide is a quiet and common source of wrong numbers.",
        "params": [
          {
            "name": "left",
            "type": "ReturnInterval",
            "required": true,
            "description": "First return, carrying `event_start`, `event_end`, `available_at` and `return_value`.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "right",
            "type": "ReturnInterval",
            "required": true,
            "description": "Second return, in the same shape.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ geometry, event_overlap_start, event_overlap_end, event_overlap_ms, left_overlap_fraction, right_overlap_fraction, … }",
          "description": "The overlap geometry — disjoint, partial, nested or identical — with the overlapping window and what fraction of each interval it represents."
        },
        "warmup": null,
        "errors": [
          {
            "when": "an interval ends before it starts",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "classifyIntervalPair({\"return_id\":\"L1\",\"instrument\":\"L\",\"partition\":\"S\",\"event_start\":\"2026-01-01T00:00:00.000Z\",\"event_end\":\"2026-01-01T00:00:04.000Z\",\"available_at\":\"2026-01-01T00:00:04.000Z\",\"return_value\":0.01}, {\"return_id\":\"R1\",\"instrument\":\"R\",\"partition\":\"S\",\"event_start\":\"2026-01-01T00:00:00.000Z\",\"event_end\":\"2026-01-01T00:00:04.000Z\",\"available_at\":\"2026-01-01T00:00:04.000Z\",\"return_value\":0.01})",
        "args": [
          {
            "value": {
              "return_id": "L1",
              "instrument": "L",
              "partition": "S",
              "event_start": "2026-01-01T00:00:00.000Z",
              "event_end": "2026-01-01T00:00:04.000Z",
              "available_at": "2026-01-01T00:00:04.000Z",
              "return_value": 0.01
            },
            "elided": null
          },
          {
            "value": {
              "return_id": "R1",
              "instrument": "R",
              "partition": "S",
              "event_start": "2026-01-01T00:00:00.000Z",
              "event_end": "2026-01-01T00:00:04.000Z",
              "available_at": "2026-01-01T00:00:04.000Z",
              "return_value": 0.01
            },
            "elided": null
          }
        ],
        "output": {
          "left_return_id": "L1",
          "right_return_id": "R1",
          "partition": "S",
          "geometry": "exact",
          "event_overlap_start": "2026-01-01T00:00:00.000Z",
          "event_overlap_end": "2026-01-01T00:00:04.000Z",
          "event_overlap_ms": 4000,
          "left_overlap_fraction": 1,
          "right_overlap_fraction": 1,
          "pair_available_at": "2026-01-01T00:00:04.000Z",
          "jointly_available_at_evaluation": null
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: left_return_id, right_return_id, partition, geometry, event_overlap_start, event_overlap_end, event_overlap_ms, left_overlap_fraction, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f03-a05/static/article-hero.svg"
          },
          {
            "file": "return-overlaps.svg",
            "url": "https://thefintechbuilder.com/content/d01-f03-a05/static/return-overlaps.svg"
          }
        ],
        "mermaid": [
          {
            "file": "overlap-flow.md",
            "caption": "Diagnostic interval-overlap flow",
            "source": "flowchart LR\n    A[\"Correction-resolved returns\"] --> B[\"Validate identity, time, and partition\"]\n    B --> C[\"Compare same-partition event intervals\"]\n    C --> D[\"Classify geometry and coverage\"]\n    D --> E[\"Evaluate pair availability\"]\n    E --> F[\"Emit diagnostic only\"]\n    F -. \"separate specification\" .-> G[\"Optional downstream estimator\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R01",
          "title": "On covariance estimation of non-synchronously observed diffusion processes",
          "author": "Takaki Hayashi and Nakahiro Yoshida",
          "url": "https://doi.org/10.3150/bj/1116340299"
        },
        {
          "key": "R02",
          "title": "RFC 3339: Date and Time on the Internet: Timestamps",
          "author": "Internet Engineering Task Force; Graham Klyne and Chris Newman",
          "url": "https://www.rfc-editor.org/info/rfc3339/"
        },
        {
          "key": "Evidence classification",
          "title": "Evidence classification",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/time-synchronization/asynchronous-return-alignment/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Asynchronous-Return-Alignment-Time-Synchronization-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/time-synchronization/asynchronous-return-alignment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F04-A01",
      "name": "Missing-Bar Gap Classifier",
      "headline": null,
      "slug": "missing-bar-gap-classifier",
      "path": "market-data-engineering/data-quality/missing-bar-gap-classifier",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F04",
        "family": "Data Quality",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/data-quality/missing-bar-gap-classifier",
        "entry": "diagnoseGap",
        "params": [
          "row"
        ],
        "exports": [
          "diagnoseGap",
          "classifyGap",
          "classifyRows"
        ],
        "archetype": "row-classify",
        "signature": "diagnoseGap(row)"
      },
      "api": {
        "summary": "Decides why a bar is missing: the session was closed, the instrument was halted, the feed dropped, or a sequence number was skipped. A gap is only a data-quality incident in some of those cases, and treating them alike produces alert fatigue.",
        "params": [
          {
            "name": "row",
            "type": "{ case_id, scenario, timestamp, bar_state, session_status, halt_status, heartbeat_status, sequence_status }",
            "required": true,
            "description": "One gap observation with every status the decision depends on, gathered from the layers that can each independently explain it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ classification, decisive_layer, reason, evidence_ids, warnings }",
          "description": "The classification plus which layer settled it, so the diagnosis can be audited rather than trusted."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a required status field is absent",
            "behaviour": "reported as a warning on the result rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "diagnoseGap({\"case_id\":\"C01\",\"scenario\":\"canonical\",\"timestamp\":\"2026-07-13T13:30:00Z\",\"bar_state\":\"present\",\"session_status\":\"open\",\"halt_status\":\"inactive\",\"heartbeat_status\":\"healthy\",\"sequence_status\":\"continuous\",\"activity_status\":\"trades\",\"activity_independent\":true,\"evidence_ids\":[\"BAR-001\",\"CAL-2026C\"],\"expected_classification\":\"present\"})",
        "args": [
          {
            "value": {
              "case_id": "C01",
              "scenario": "canonical",
              "timestamp": "2026-07-13T13:30:00Z",
              "bar_state": "present",
              "session_status": "open",
              "halt_status": "inactive",
              "heartbeat_status": "healthy",
              "sequence_status": "continuous",
              "activity_status": "trades",
              "activity_independent": true,
              "evidence_ids": [
                "BAR-001",
                "CAL-2026C"
              ],
              "expected_classification": "present"
            },
            "elided": null
          }
        ],
        "output": {
          "classification": "present",
          "decisive_layer": "bar",
          "reason": "A validated bar is materialized.",
          "evidence_ids": [
            "BAR-001",
            "CAL-2026C"
          ],
          "warnings": []
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: classification, decisive_layer, reason, evidence_ids, warnings"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f04-a01/static/article-hero.svg"
          },
          {
            "file": "gap-classification-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d01-f04-a01/static/gap-classification-timeline.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "NYSE-HOURS",
          "title": "Holidays and trading hours",
          "author": "New York Stock Exchange",
          "url": "https://www.nyse.com/trade/hours-calendars"
        },
        {
          "key": "NYSE-HALTS",
          "title": "Trading halts",
          "author": "New York Stock Exchange",
          "url": "https://www.nyse.com/trade/trading-halts"
        },
        {
          "key": "NASDAQ-MOLDUDP64",
          "title": "MoldUDP64 Protocol Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/moldudp64.pdf"
        },
        {
          "key": "NASDAQ-ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "ICE-NYSE-BUSH-CLOSURE",
          "title": "NYSE Group closure for National Day of Mourning",
          "author": "Intercontinental Exchange / New York Stock Exchange",
          "url": "https://ir.theice.com/press/news-details/2018/New-York-Stock-Exchange-to-Honor-President-George-H-W-Bush/default.aspx"
        },
        {
          "key": "Package conventions",
          "title": "engineering choices, not external facts",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/data-quality/missing-bar-gap-classifier/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Missing-Bar-Gap-Classifier-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/data-quality/missing-bar-gap-classifier/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F04-A02",
      "name": "Feed-Latency Monitor",
      "headline": null,
      "slug": "feed-latency-monitor",
      "path": "market-data-engineering/data-quality/feed-latency-monitor",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F04",
        "family": "Data Quality",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/data-quality/feed-latency-monitor",
        "entry": "validateClockProfile",
        "params": [
          "profile"
        ],
        "exports": [
          "validateClockProfile",
          "percentile",
          "diagnoseEvent",
          "monitor"
        ],
        "archetype": "row-classify",
        "signature": "validateClockProfile(profile)"
      },
      "api": {
        "summary": "Validates that a latency measurement is meaningful before any latency is computed from it. Subtracting timestamps written by two unsynchronised clocks produces a number, and that number means nothing.",
        "params": [
          {
            "name": "profile",
            "type": "ClockProfile",
            "required": true,
            "description": "Which clock domain owns each timestamp, who wrote it, the cross-domain synchronisation status, and the maximum absolute offset between domains.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ …profile, status, usable_measurements, warnings }",
          "description": "The profile echoed back with a verdict on which latency measurements it can support and which would be meaningless."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a clock domain or timestamp owner is missing",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "validateClockProfile({\"source_clock_domain\":\"SYNTHETIC-VENUE-UTC\",\"ingress_clock_domain\":\"CONSUMER-PHC-UTC\",\"ready_clock_domain\":\"CONSUMER-PHC-UTC\",\"source_timestamp_owner\":\"synthetic venue encoder\",\"ingress_timestamp_owner\":\"consumer NIC hardware capture\",\"ready_timestamp_owner\":\"consumer feed-handler process\",\"cross_domain_sync_status\":\"synchronized\",\"max_abs_offset_ms\":0.05,\"measured_at\":\"2026-07-13T13:29:59Z\",\"evidence\":\"synthetic declared bound; not a production clock attestation\"})",
        "args": [
          {
            "value": {
              "source_clock_domain": "SYNTHETIC-VENUE-UTC",
              "ingress_clock_domain": "CONSUMER-PHC-UTC",
              "ready_clock_domain": "CONSUMER-PHC-UTC",
              "source_timestamp_owner": "synthetic venue encoder",
              "ingress_timestamp_owner": "consumer NIC hardware capture",
              "ready_timestamp_owner": "consumer feed-handler process",
              "cross_domain_sync_status": "synchronized",
              "max_abs_offset_ms": 0.05,
              "measured_at": "2026-07-13T13:29:59Z",
              "evidence": "synthetic declared bound; not a production clock attestation"
            },
            "elided": null
          }
        ],
        "output": {
          "source_clock_domain": "SYNTHETIC-VENUE-UTC",
          "ingress_clock_domain": "CONSUMER-PHC-UTC",
          "ready_clock_domain": "CONSUMER-PHC-UTC",
          "source_timestamp_owner": "synthetic venue encoder",
          "ingress_timestamp_owner": "consumer NIC hardware capture",
          "ready_timestamp_owner": "consumer feed-handler process",
          "cross_domain_sync_status": "synchronized",
          "max_abs_offset_ms": 0.05,
          "measured_at": "2026-07-13T13:29:59Z",
          "evidence": "synthetic declared bound; not a production clock attestation"
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: source_clock_domain, ingress_clock_domain, ready_clock_domain, source_timestamp_owner, ingress_timestamp_owner, ready_timestamp_owner, cross_domain_sync_status, max_abs_offset_ms, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f04-a02/static/article-hero.svg"
          },
          {
            "file": "latency-budget.svg",
            "url": "https://thefintechbuilder.com/content/d01-f04-a02/static/latency-budget.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "R01",
          "title": "FIX Session Layer",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/wp-content/uploads/download-manager-files/FIX_Session_Layer_June_2020.pdf"
        },
        {
          "key": "R02",
          "title": "FINRA Rule 4590, Synchronization of Member Business Clocks",
          "author": "Financial Industry Regulatory Authority",
          "url": "https://www.finra.org/rules-guidance/rulebooks/finra-rules/4590"
        },
        {
          "key": "R03",
          "title": "NIST Time Measurement and Analysis Service",
          "author": "National Institute of Standards and Technology",
          "url": "https://www.nist.gov/programs-projects/time-measurement-and-analysis-service-tmas"
        },
        {
          "key": "R04",
          "title": "SEC approval of the Consolidated Audit Trail plan",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/newsroom/press-releases/2016-240"
        },
        {
          "key": "R05",
          "title": "SEC action on NYSE market-data distribution",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/newsroom/press-releases/2012-2012-189htm"
        },
        {
          "key": "Historical evidence disposition",
          "title": "Historical evidence disposition",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/data-quality/feed-latency-monitor/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Feed-Latency-Monitor-Data-Quality-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/data-quality/feed-latency-monitor/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F04-A03",
      "name": "Price-Source Consensus Check",
      "headline": null,
      "slug": "price-source-consensus-check",
      "path": "market-data-engineering/data-quality/price-source-consensus-check",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F04",
        "family": "Data Quality",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/data-quality/price-source-consensus-check",
        "entry": "consensus",
        "params": [
          "snapshot",
          "policy"
        ],
        "exports": [
          "consensus"
        ],
        "archetype": "snapshot-evaluate",
        "signature": "consensus(snapshot, policy)"
      },
      "api": {
        "summary": "Reconciles quotes from several providers into one defensible price, or refuses to. Serious platforms never trust a single vendor, and two feeds never agree exactly — this is the layer that decides who is right.",
        "params": [
          {
            "name": "snapshot",
            "type": "{ as_of: string; quotes: SourceQuote[] }",
            "required": true,
            "description": "One quote per source at a moment in time, each with its own timestamp so staleness is per-source.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "policy",
            "type": "{ minimum_independent_sources: number; z_threshold: number; absolute_tolerance: number; maximum_tolerance: number; max_age_ms: number; expected_contract?: string }",
            "required": true,
            "description": "`minimum_independent_sources` is the quorum below which no consensus is declared. `z_threshold` sets how far from the robust centre a quote may sit before it is an outlier, bounded by `absolute_tolerance` and `maximum_tolerance` so the test behaves at both very tight and very wide spreads. `max_age_ms` excludes stale sources.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, reason, consensus_price, inliers, outliers, diagnostics }",
          "description": "A status rather than a bare number: a refusal to price is a legitimate and important outcome, and `reason` says why."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the policy is internally inconsistent, such as a negative tolerance",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "consensus({\"as_of\":\"2026-07-13T13:30:01.000Z\",\"quotes\":[{\"source_id\":\"A\",\"owner_id\":\"OWNER-A\",\"price\":100,\"instrument_id\":\"SYNTH-USD\",\"currency\":\"USD\",\"price_type\":\"last_trade\",\"adjustment\":\"unadjusted\",\"session\":\"regular\",\"event_time\":\"2026-07-13T13:30:01.000Z\"},{\"source_id\":\"B\",\"owner_id\":\"OWNER-B\",\"price\":100.01,\"instrument_id\":\"SYNTH-USD\",\"currency\":\"USD\",\"price_type\":\"last_trade\",\"adjustment\":\"unadjusted\",\"session\":\"regular\",\"event_time\":\"2026-07-13T13:30:01.000Z\"},{\"source_id\":\"C\",\"owner_id\":\"OWNER-C\",\"price\":100.02,\"instrument_id\":\"SYNTH-USD\",\"currency\":\"USD\",\"price_type\":\"last_trade\",\"adjustment\":\"unadjusted\",\"session\":\"regular\",\"event_time\":\"2026-07-13T13:30:01.000Z\"}]}, {\"minimum_independent_sources\":3,\"z_threshold\":3.5,\"absolute_tolerance\":0.03,\"maximum_tolerance\":0.15,\"max_age_ms\":500,\"expected_contract\":{\"instrument_id\":\"SYNTH-USD\",\"currency\":\"USD\",\"price_type\":\"last_trade\",\"adjustment\":\"unadjusted\",\"session\":\"regular\"}})",
        "args": [
          {
            "value": {
              "as_of": "2026-07-13T13:30:01.000Z",
              "quotes": [
                {
                  "source_id": "A",
                  "owner_id": "OWNER-A",
                  "price": 100,
                  "instrument_id": "SYNTH-USD",
                  "currency": "USD",
                  "price_type": "last_trade",
                  "adjustment": "unadjusted",
                  "session": "regular",
                  "event_time": "2026-07-13T13:30:01.000Z"
                },
                {
                  "source_id": "B",
                  "owner_id": "OWNER-B",
                  "price": 100.01,
                  "instrument_id": "SYNTH-USD",
                  "currency": "USD",
                  "price_type": "last_trade",
                  "adjustment": "unadjusted",
                  "session": "regular",
                  "event_time": "2026-07-13T13:30:01.000Z"
                },
                {
                  "source_id": "C",
                  "owner_id": "OWNER-C",
                  "price": 100.02,
                  "instrument_id": "SYNTH-USD",
                  "currency": "USD",
                  "price_type": "last_trade",
                  "adjustment": "unadjusted",
                  "session": "regular",
                  "event_time": "2026-07-13T13:30:01.000Z"
                }
              ]
            },
            "elided": null
          },
          {
            "value": {
              "minimum_independent_sources": 3,
              "z_threshold": 3.5,
              "absolute_tolerance": 0.03,
              "maximum_tolerance": 0.15,
              "max_age_ms": 500,
              "expected_contract": {
                "instrument_id": "SYNTH-USD",
                "currency": "USD",
                "price_type": "last_trade",
                "adjustment": "unadjusted",
                "session": "regular"
              }
            },
            "elided": null
          }
        ],
        "output": {
          "status": "consensus",
          "reason": "quorum_met",
          "consensus_price": 100.01,
          "inliers": [
            "A",
            "B",
            "C",
            "D"
          ],
          "outliers": [],
          "diagnostics": {
            "observed_source_count": 4,
            "eligible_independent_source_count": 4,
            "minimum_independent_sources": 3,
            "excluded": [],
            "initial_center": 100.01,
            "mad": 0.0049999999999954525,
            "robust_scale": 0.007412898443284585,
            "adaptive_tolerance": 0.025945144551496047,
            "absolute_tolerance": 0.03,
            "applied_tolerance": 0.03,
            "maximum_tolerance": 0.15,
            "zero_mad_policy": "not_applicable",
            "comparison_epsilon": 1e-12,
            "inlier_independent_source_count": 4
          }
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: status, reason, consensus_price, inliers, outliers, diagnostics"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f04-a03/static/article-hero.svg"
          },
          {
            "file": "consensus-band.svg",
            "url": "https://thefintechbuilder.com/content/d01-f04-a03/static/consensus-band.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "R01 - Median Absolute Deviation",
          "title": "R01 - Median Absolute Deviation",
          "author": "National Institute of Standards and Technology (NIST)",
          "url": "https://www.itl.nist.gov/div898/software/dataplot/refman2/auxillar/mad.htm"
        },
        {
          "key": "R02 - Detection of Outliers",
          "title": "R02 - Detection of Outliers",
          "author": "NIST/SEMATECH",
          "url": "https://www.itl.nist.gov/div898/handbook/eda/section3/eda35h.htm"
        },
        {
          "key": "R03 - Nasdaq TotalView-ITCH 5.0",
          "title": "R03 - Nasdaq TotalView-ITCH 5.0",
          "author": "Nasdaq",
          "url": "https://classic.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "R04 - FIX MarketDataSnapshotFullRefresh",
          "title": "R04 - FIX MarketDataSnapshotFullRefresh",
          "author": "FIX Trading Community",
          "url": "https://fiximate.fixtrading.org/legacy/en/FIX.5.0/body_514887.html"
        },
        {
          "key": "Evidence-role ledger",
          "title": "Evidence-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Historical-case acceptance criteria",
          "title": "Historical-case acceptance criteria",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/data-quality/price-source-consensus-check/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Price-Source-Consensus-Check-Data-Quality-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/data-quality/price-source-consensus-check/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F04-A04",
      "name": "Schema-Drift Detector",
      "headline": "Catch Structural and Semantic Contract Changes",
      "slug": "schema-drift-detector",
      "path": "market-data-engineering/data-quality/schema-drift-detector",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F04",
        "family": "Data Quality",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/data-quality/schema-drift-detector",
        "entry": "detectSchemaDrift",
        "params": [
          "baseline",
          "candidate",
          "policy"
        ],
        "exports": [
          "detectSchemaDrift"
        ],
        "archetype": "row-classify",
        "signature": "detectSchemaDrift(baseline, candidate, policy)"
      },
      "api": {
        "summary": "Compares two versions of a feed schema and classifies every change as compatible or breaking. Vendors rename and retype fields without announcement, and a silently renamed field is worse than an outage because nothing fails.",
        "params": [
          {
            "name": "baseline",
            "type": "Schema",
            "required": true,
            "description": "The schema currently relied upon.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "candidate",
            "type": "Schema",
            "required": true,
            "description": "The schema just observed on the feed.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "policy",
            "type": "DriftPolicy",
            "required": true,
            "description": "Which categories of change are tolerated, and which must fail.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ baseline_version, candidate_version, policy, status, coverage_complete, changes }",
          "description": "Every change with its classification, plus whether the comparison covered the whole schema — an incomplete comparison must not read as a clean bill of health."
        },
        "warmup": null,
        "errors": [
          {
            "when": "either schema is missing an identifier or version",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(fields)",
          "space": "O(fields)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "detectSchemaDrift({\"schema_id\":\"synthetic-trades\",\"version\":\"v1.0\",\"parent_version\":null,\"completeness\":\"complete\",\"fields\":{\"symbol\":{\"type\":\"string\",\"required\":true,\"nullable\":false,\"enum\":null,\"unit\":null,\"meaning\":\"Instrument symbol under the declared venue symbology\"},\"price\":{\"type\":\"number\",\"required\":true,\"nullable\":false,\"enum\":null,\"unit\":\"USD per share\",\"meaning\":\"Executed price\"},\"size\":{\"type\":\"integer\",\"required\":true,\"nullable\":false,\"enum\":null,\"unit\":\"shares\",\"meaning\":\"Executed quantity\"},\"sale_condition\":{\"type\":\"string\",\"required\":false,\"nullable\":true,\"enum\":[\" \",\"O\"],\"unit\":null,\"meaning\":\"Synthetic sale-condition code\"}}}, {\"schema_id\":\"synthetic-trades\",\"version\":\"v1.0-clone\",\"parent_version\":\"v1.0\",\"completeness\":\"complete\",\"fields\":{\"symbol\":{\"type\":\"string\",\"required\":true,\"nullable\":false,\"enum\":null,\"unit\":null,\"meaning\":\"Instrument symbol under the declared venue symbology\"},\"price\":{\"type\":\"number\",\"required\":true,\"nullable\":false,\"enum\":null,\"unit\":\"USD per share\",\"meaning\":\"Executed price\"},\"size\":{\"type\":\"integer\",\"required\":true,\"nullable\":false,\"enum\":null,\"unit\":\"shares\",\"meaning\":\"Executed quantity\"},\"sale_condition\":{\"type\":\"string\",\"required\":false,\"nullable\":true,\"enum\":[\" \",\"O\"],\"unit\":null,\"meaning\":\"Synthetic sale-condition code\"}}})",
        "args": [
          {
            "value": {
              "schema_id": "synthetic-trades",
              "version": "v1.0",
              "parent_version": null,
              "completeness": "complete",
              "fields": {
                "symbol": {
                  "type": "string",
                  "required": true,
                  "nullable": false,
                  "enum": null,
                  "unit": null,
                  "meaning": "Instrument symbol under the declared venue symbology"
                },
                "price": {
                  "type": "number",
                  "required": true,
                  "nullable": false,
                  "enum": null,
                  "unit": "USD per share",
                  "meaning": "Executed price"
                },
                "size": {
                  "type": "integer",
                  "required": true,
                  "nullable": false,
                  "enum": null,
                  "unit": "shares",
                  "meaning": "Executed quantity"
                },
                "sale_condition": {
                  "type": "string",
                  "required": false,
                  "nullable": true,
                  "enum": [
                    " ",
                    "O"
                  ],
                  "unit": null,
                  "meaning": "Synthetic sale-condition code"
                }
              }
            },
            "elided": null
          },
          {
            "value": {
              "schema_id": "synthetic-trades",
              "version": "v1.0-clone",
              "parent_version": "v1.0",
              "completeness": "complete",
              "fields": {
                "symbol": {
                  "type": "string",
                  "required": true,
                  "nullable": false,
                  "enum": null,
                  "unit": null,
                  "meaning": "Instrument symbol under the declared venue symbology"
                },
                "price": {
                  "type": "number",
                  "required": true,
                  "nullable": false,
                  "enum": null,
                  "unit": "USD per share",
                  "meaning": "Executed price"
                },
                "size": {
                  "type": "integer",
                  "required": true,
                  "nullable": false,
                  "enum": null,
                  "unit": "shares",
                  "meaning": "Executed quantity"
                },
                "sale_condition": {
                  "type": "string",
                  "required": false,
                  "nullable": true,
                  "enum": [
                    " ",
                    "O"
                  ],
                  "unit": null,
                  "meaning": "Synthetic sale-condition code"
                }
              }
            },
            "elided": null
          }
        ],
        "output": {
          "baseline_version": "v1.0",
          "candidate_version": "v1.0-clone",
          "policy": {
            "name": "strict_existing_consumer_v1",
            "direction": "candidate_producer_to_baseline_consumer",
            "added_field": "non_breaking",
            "removed_optional": "review",
            "removed_required": "breaking",
            "type_changed": "breaking",
            "optional_to_required": "non_breaking",
            "required_to_optional": "breaking",
            "nonnullable_to_nullable": "breaking",
            "nullable_to_nonnullable": "non_breaking",
            "enum_values_added": "breaking",
            "enum_values_removed": "review",
            "unit_changed": "breaking",
            "meaning_changed": "breaking"
          },
          "status": "unchanged",
          "coverage_complete": true,
          "changes": []
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: baseline_version, candidate_version, policy, status, coverage_complete, changes"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f04-a04/static/article-hero.svg"
          },
          {
            "file": "schema-compatibility-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d01-f04-a04/static/schema-compatibility-matrix.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "NYSE-TAQ-33B",
          "title": "Daily TAQ Client Specification v3.3b",
          "author": null,
          "url": null
        },
        {
          "key": "NYSE-TAQ-33C",
          "title": "Daily TAQ Client Specification v3.3c",
          "author": null,
          "url": null
        },
        {
          "key": "NYSE-DOCUMENT-INDEX",
          "title": "Market Data Documents",
          "author": null,
          "url": null
        },
        {
          "key": "JSON-CORE",
          "title": "JSON Schema Core 2020-12",
          "author": null,
          "url": null
        },
        {
          "key": "JSON-VALIDATION",
          "title": "JSON Schema Validation 2020-12",
          "author": null,
          "url": null
        },
        {
          "key": "AVRO-RESOLUTION",
          "title": "Apache Avro Specification",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/data-quality/schema-drift-detector/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Schema-Drift-Detector-Data-Quality-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/data-quality/schema-drift-detector/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F04-A05",
      "name": "Point-in-Time Availability Guard",
      "headline": null,
      "slug": "point-in-time-availability-guard",
      "path": "market-data-engineering/data-quality/point-in-time-availability-guard",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F04",
        "family": "Data Quality",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/data-quality/point-in-time-availability-guard",
        "entry": "asOfSnapshot",
        "params": [
          "records",
          "knowledgeTime"
        ],
        "exports": [
          "asOfSnapshot",
          "leakageAudit"
        ],
        "archetype": "snapshot-evaluate",
        "signature": "asOfSnapshot(records, knowledgeTime)"
      },
      "api": {
        "summary": "Reconstructs what was actually knowable at a given moment, using each record's `available_at` rather than its `observation_time`. This is the guard that stops a backtest reading a figure hours before it was published.",
        "params": [
          {
            "name": "records",
            "type": "Record[]",
            "required": true,
            "description": "Observations carrying `observation_time`, `available_at` and a `revision`, so restatements are distinguishable from originals.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "knowledgeTime",
            "type": "string",
            "required": true,
            "description": "ISO 8601 moment to reconstruct. Only records available at or before this instant are eligible.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record[]",
          "length": "fewer",
          "description": "The latest revision of each entity/feature that had actually been published by the knowledge time."
        },
        "warmup": null,
        "errors": [
          {
            "when": "knowledgeTime is not a valid ISO 8601 timestamp",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "asOfSnapshot([{\"entity\":\"ALFA\",\"feature\":\"weekly_metric\",\"observation_time\":\"2026-01-02T00:00:00Z\",\"available_at\":\"2026-01-04T14:00:00Z\",\"revision\":0,\"value\":10,\"record_id\":\"ALFA-00-r0\"},{\"entity\":\"ALFA\",\"feature\":\"weekly_metric\",\"observation_time\":\"2026-01-02T00:00:00Z\",\"available_at\":\"2026-01-11T14:00:00Z\",\"revision\":1,\"value\":10.07,\"record_id\":\"ALFA-00-r1\"},{\"entity\":\"ALFA\",\"feature\":\"weekly_metric\",\"observation_time\":\"2026-01-02T00:00:00Z\",\"available_at\":\"2026-01-30T14:00:00Z\",\"revision\":2,\"value\":10.14,\"record_id\":\"ALFA-00-r2\"}], \"2026-02-01T12:00:00Z\")",
        "args": [
          {
            "value": [
              {
                "entity": "ALFA",
                "feature": "weekly_metric",
                "observation_time": "2026-01-02T00:00:00Z",
                "available_at": "2026-01-04T14:00:00Z",
                "revision": 0,
                "value": 10,
                "record_id": "ALFA-00-r0"
              },
              {
                "entity": "ALFA",
                "feature": "weekly_metric",
                "observation_time": "2026-01-02T00:00:00Z",
                "available_at": "2026-01-11T14:00:00Z",
                "revision": 1,
                "value": 10.07,
                "record_id": "ALFA-00-r1"
              },
              {
                "entity": "ALFA",
                "feature": "weekly_metric",
                "observation_time": "2026-01-02T00:00:00Z",
                "available_at": "2026-01-30T14:00:00Z",
                "revision": 2,
                "value": 10.14,
                "record_id": "ALFA-00-r2"
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 180
            }
          },
          {
            "value": "2026-02-01T12:00:00Z",
            "elided": null
          }
        ],
        "output": [
          {
            "entity": "ALFA",
            "feature": "weekly_metric",
            "observation_time": "2026-01-23T00:00:00Z",
            "available_at": "2026-01-25T14:00:00Z",
            "revision": 0,
            "value": 10.75,
            "record_id": "ALFA-03-r0"
          },
          {
            "entity": "BETA",
            "feature": "weekly_metric",
            "observation_time": "2026-01-23T00:00:00Z",
            "available_at": "2026-01-25T15:00:00Z",
            "revision": 0,
            "value": 13.75,
            "record_id": "BETA-03-r0"
          },
          {
            "entity": "GAMM",
            "feature": "weekly_metric",
            "observation_time": "2026-01-23T00:00:00Z",
            "available_at": "2026-01-25T16:00:00Z",
            "revision": 0,
            "value": 16.75,
            "record_id": "GAMM-03-r0"
          }
        ],
        "outputElided": null,
        "outputShape": "array of 3 objects"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d01-f04-a05/static/article-hero.svg"
          },
          {
            "file": "availability-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d01-f04-a05/static/availability-timeline.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SEC-APPLE-10Q-INDEX",
          "title": "Apple 2024 third-quarter Form 10-Q filing detail",
          "author": "U.S. Securities and Exchange Commission; filer Apple Inc.",
          "url": "https://www.sec.gov/Archives/edgar/data/320193/000032019324000081/0000320193-24-000081-index.htm"
        },
        {
          "key": "SEC-APPLE-10Q",
          "title": "Apple Form 10-Q for the period ended 2024-06-29",
          "author": "Apple Inc.; filed with the U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/Archives/edgar/data/320193/000032019324000081/aapl-20240629.htm"
        },
        {
          "key": "SEC-TIMESTAMPS",
          "title": "Webmaster Frequently Asked Questions",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/about/webmaster-frequently-asked-questions"
        },
        {
          "key": "SEC-APIS",
          "title": "EDGAR Application Programming Interfaces",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/search-filings/edgar-application-programming-interfaces"
        },
        {
          "key": "SEC-SUBMISSION-GUIDE",
          "title": "Attach and Submit a Filing Through the EDGAR Filing Website",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/submit-filings/filer-support-resources/how-do-i-guides/attach-submit-filing-through-edgar-filing-website"
        },
        {
          "key": "ALFRED-VINTAGES",
          "title": "FRED Series Vintage Dates",
          "author": "Federal Reserve Bank of St. Louis",
          "url": "https://fred.stlouisfed.org/docs/api/fred/series/series_vintagedates.html"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/data-quality/point-in-time-availability-guard/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Point-In-Time-Availability-Guard-Data-Quality-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/data-quality/point-in-time-availability-guard/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F04-A06",
      "name": "Provider Adjustment-Basis Drift Detector",
      "headline": null,
      "slug": "provider-adjustment-basis-drift-detector",
      "path": "market-data-engineering/data-quality/provider-adjustment-basis-drift-detector",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F04",
        "family": "Data Quality",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/data-quality/provider-adjustment-basis-drift-detector",
        "entry": "detectAdjustmentBasisDrift",
        "params": [
          "input"
        ],
        "exports": [
          "detectAdjustmentBasisDrift"
        ],
        "archetype": "row-classify",
        "signature": "detectAdjustmentBasisDrift(input)"
      },
      "api": {
        "summary": "Compares archived provider adjustment factors and isolates unexplained residual drift after newly knowable corporate actions.",
        "params": [
          {
            "name": "input",
            "type": "object",
            "required": true,
            "description": "Topic-specific point-in-time audit contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "object",
          "description": "Structured state, audit rows, diagnostics, and provenance."
        },
        "warmup": null,
        "errors": [],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "detectAdjustmentBasisDrift({\"provider\":\"synthetic-provider\",\"dataset\":\"daily-equity-bars\",\"instrument_id\":\"SYNTH-ABC\",\"price_field\":\"close\",\"basis_id\":\"split-adjusted-v1\",\"baseline_observed_at\":\"2026-06-12T20:00:00Z\",\"candidate_observed_at\":\"2026-06-16T20:00:00Z\",\"tolerance_bps\":1,\"baseline_rows\":[{\"date\":\"2026-06-10\",\"raw_price\":100,\"adjusted_price\":100},{\"date\":\"2026-06-11\",\"raw_price\":102,\"adjusted_price\":102},{\"date\":\"2026-06-12\",\"raw_price\":104,\"adjusted_price\":104}],\"candidate_rows\":[{\"date\":\"2026-06-10\",\"raw_price\":100,\"adjusted_price\":50},{\"date\":\"2026-06-11\",\"raw_price\":102,\"adjusted_price\":51},{\"date\":\"2026-06-12\",\"raw_price\":104,\"adjusted_price\":52.26}],\"actions\":[{\"event_id\":\"SPLIT-2FOR1\",\"effective_date\":\"2026-06-15\",\"available_at\":\"2026-06-13T12:00:00Z\",\"status\":\"confirmed\",\"adjustment_multiplier\":0.5}]})",
        "args": [
          {
            "value": {
              "provider": "synthetic-provider",
              "dataset": "daily-equity-bars",
              "instrument_id": "SYNTH-ABC",
              "price_field": "close",
              "basis_id": "split-adjusted-v1",
              "baseline_observed_at": "2026-06-12T20:00:00Z",
              "candidate_observed_at": "2026-06-16T20:00:00Z",
              "tolerance_bps": 1,
              "baseline_rows": [
                {
                  "date": "2026-06-10",
                  "raw_price": 100,
                  "adjusted_price": 100
                },
                {
                  "date": "2026-06-11",
                  "raw_price": 102,
                  "adjusted_price": 102
                },
                {
                  "date": "2026-06-12",
                  "raw_price": 104,
                  "adjusted_price": 104
                }
              ],
              "candidate_rows": [
                {
                  "date": "2026-06-10",
                  "raw_price": 100,
                  "adjusted_price": 50
                },
                {
                  "date": "2026-06-11",
                  "raw_price": 102,
                  "adjusted_price": 51
                },
                {
                  "date": "2026-06-12",
                  "raw_price": 104,
                  "adjusted_price": 52.26
                }
              ],
              "actions": [
                {
                  "event_id": "SPLIT-2FOR1",
                  "effective_date": "2026-06-15",
                  "available_at": "2026-06-13T12:00:00Z",
                  "status": "confirmed",
                  "adjustment_multiplier": 0.5
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "provider": "synthetic-provider",
          "dataset": "daily-equity-bars",
          "instrument_id": "SYNTH-ABC",
          "price_field": "close",
          "basis_id": "split-adjusted-v1",
          "baseline_observed_at": "2026-06-12T20:00:00Z",
          "candidate_observed_at": "2026-06-16T20:00:00Z",
          "tolerance_bps": 1,
          "state": "basis-drift",
          "overlap_count": 3,
          "stable_count": 0,
          "expected_restatement_count": 2,
          "drift_count": 1,
          "max_residual_bps": 49.875415
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: provider, dataset, instrument_id, price_field, basis_id, baseline_observed_at, candidate_observed_at, tolerance_bps, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f04-a06/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Provider adjustment-basis drift calculation flow",
            "source": "flowchart LR\n    A[\"Archive two matching provider snapshots\"] --> B[\"Compute adjusted/raw factor by shared date\"]\n    C[\"Select actions newly knowable between snapshots\"] --> D[\"Build expected multiplier for pre-effective dates\"]\n    B --> E[\"Observed factor multiplier\"]\n    D --> F[\"Log residual in basis points\"]\n    E --> F\n    F --> G{\"Residual ≤ tolerance?\"}\n    G -->|Yes, no expected action| H[\"Stable\"]\n    G -->|Yes, expected action| I[\"Expected restatement\"]\n    G -->|No| J[\"Basis drift\"]\n    J --> K[\"Audit invariant: counts sum to overlap and unmatched dates remain visible\"]"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "Alpha Vantage API documentation",
          "author": null,
          "url": null
        },
        {
          "key": "S2",
          "title": "Alpha Vantage support: adjustment method",
          "author": null,
          "url": null
        },
        {
          "key": "S3",
          "title": "Massive Stocks Splits API",
          "author": null,
          "url": null
        },
        {
          "key": "S4",
          "title": "Massive Stocks flat-file overview",
          "author": null,
          "url": null
        },
        {
          "key": "Publication decision",
          "title": "Publication decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/data-quality/provider-adjustment-basis-drift-detector/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/data-quality/provider-adjustment-basis-drift-detector/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F05-A01",
      "name": "Trade-and-Quote Event Normalization",
      "headline": null,
      "slug": "trade-and-quote-event-normalization",
      "path": "market-data-engineering/order-book-feed-engineering/trade-and-quote-event-normalization",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F05",
        "family": "Order-Book Feed Engineering",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/order-book-feed-engineering/trade-and-quote-event-normalization",
        "entry": "normalizeEvents",
        "params": [
          "events"
        ],
        "exports": [
          "normalizeEvents",
          "reconstructL2",
          "aggregatePriceLevels",
          "reconstructL3",
          "recoverSequenceStream",
          "reconcileSnapshotIncrementals",
          "consolidateVenues",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "normalizeEvents(events)"
      },
      "api": {
        "summary": "Normalises raw venue trade and quote messages into one canonical event shape. Every venue names, orders and timestamps its fields differently; this is the boundary where that stops being everyone else's problem.",
        "params": [
          {
            "name": "events",
            "type": "RawEvent[]",
            "required": true,
            "description": "Raw venue messages with their native field names, sequence numbers and timestamps.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ events, rejected, diagnostics }",
          "description": "Canonical events plus the ones rejected and why — a normaliser that silently drops malformed messages hides a feed problem rather than surfacing it."
        },
        "warmup": null,
        "errors": [
          {
            "when": "an event carries no recognisable type",
            "behaviour": "recorded in rejected rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "normalizeEvents([{\"venue\":\"XNAS\",\"instrument\":\"SYN1\",\"sequence\":100,\"event_time_ns\":1000000,\"receive_time_ns\":1000210,\"price_scale\":10000,\"kind\":\"quote\",\"bid_price_atoms\":1000000,\"bid_quantity\":70,\"ask_price_atoms\":1000200,\"ask_quantity\":65},{\"venue\":\"XNAS\",\"instrument\":\"SYN1\",\"sequence\":101,\"event_time_ns\":1000300,\"receive_time_ns\":1000545,\"price_scale\":10000,\"kind\":\"trade\",\"trade_id\":\"T01\",\"price_atoms\":1000200,\"quantity\":11,\"aggressor_side\":\"buy\"},{\"venue\":\"XNAS\",\"instrument\":\"SYN1\",\"sequence\":102,\"event_time_ns\":1000600,\"receive_time_ns\":1000880,\"price_scale\":10000,\"kind\":\"quote\",\"bid_price_atoms\":1000200,\"bid_quantity\":74,\"ask_price_atoms\":1000400,\"ask_quantity\":67}])",
        "args": [
          {
            "value": [
              {
                "venue": "XNAS",
                "instrument": "SYN1",
                "sequence": 100,
                "event_time_ns": 1000000,
                "receive_time_ns": 1000210,
                "price_scale": 10000,
                "kind": "quote",
                "bid_price_atoms": 1000000,
                "bid_quantity": 70,
                "ask_price_atoms": 1000200,
                "ask_quantity": 65
              },
              {
                "venue": "XNAS",
                "instrument": "SYN1",
                "sequence": 101,
                "event_time_ns": 1000300,
                "receive_time_ns": 1000545,
                "price_scale": 10000,
                "kind": "trade",
                "trade_id": "T01",
                "price_atoms": 1000200,
                "quantity": 11,
                "aggressor_side": "buy"
              },
              {
                "venue": "XNAS",
                "instrument": "SYN1",
                "sequence": 102,
                "event_time_ns": 1000600,
                "receive_time_ns": 1000880,
                "price_scale": 10000,
                "kind": "quote",
                "bid_price_atoms": 1000200,
                "bid_quantity": 74,
                "ask_price_atoms": 1000400,
                "ask_quantity": 67
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 24
            }
          }
        ],
        "output": {
          "schema_version": 1,
          "event_count": 24,
          "trade_count": 8,
          "quote_count": 16,
          "venue_count": 1,
          "max_latency_ns": 350,
          "events": [
            {
              "schema_version": 1,
              "venue": "XNAS",
              "instrument": "SYN1",
              "sequence": 100,
              "event_time_ns": 1000000,
              "receive_time_ns": 1000210,
              "latency_ns": 210,
              "price_scale": 10000,
              "kind": "quote",
              "bid_price_atoms": 1000000,
              "bid_price": 100,
              "bid_quantity": 70,
              "ask_price_atoms": 1000200,
              "ask_price": 100.02
            },
            {
              "schema_version": 1,
              "venue": "XNAS",
              "instrument": "SYN1",
              "sequence": 101,
              "event_time_ns": 1000300,
              "receive_time_ns": 1000545,
              "latency_ns": 245,
              "price_scale": 10000,
              "kind": "trade",
              "trade_id": "T01",
              "price_atoms": 1000200,
              "price": 100.02,
              "quantity": 11,
              "aggressor_side": "buy"
            },
            {
              "schema_version": 1,
              "venue": "XNAS",
              "instrument": "SYN1",
              "sequence": 102,
              "event_time_ns": 1000600,
              "receive_time_ns": 1000880,
              "latency_ns": 280,
              "price_scale": 10000,
              "kind": "quote",
              "bid_price_atoms": 1000200,
              "bid_price": 100.02,
              "bid_quantity": 74,
              "ask_price_atoms": 1000400,
              "ask_price": 100.04
            }
          ],
          "state": "normalized"
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: schema_version, event_count, trade_count, quote_count, venue_count, max_latency_ns, events, state"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "d11-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a01/static/d11-handoff.svg"
          },
          {
            "file": "failure-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a01/static/failure-map.svg"
          },
          {
            "file": "sequence-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a01/static/sequence-boundary.svg"
          },
          {
            "file": "state-transition.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a01/static/state-transition.svg"
          },
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Topic-specific source roles",
          "title": "Topic-specific source roles",
          "author": null,
          "url": null
        },
        {
          "key": "SRC-ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification_5.0.pdf"
        },
        {
          "key": "SRC-GLIMPSE",
          "title": "Nasdaq GLIMPSE 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQGlimpseSpecification_5.0.pdf"
        },
        {
          "key": "SRC-MOLD",
          "title": "MoldUDP64 protocol",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/moldudp64.pdf"
        },
        {
          "key": "SRC-FIX",
          "title": "FIX recommended practices for book management",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/wp-content/uploads/download-manager-files/MDOWG_Book_Mgt-v20.pdf"
        },
        {
          "key": "SRC-CBOE",
          "title": "Cboe Multicast PITCH specification",
          "author": "Cboe Global Markets",
          "url": "https://www.cboe.com/document/tech-spec/document/technical-specifications/cboe-titanium-u.s.-equitiesoptions-multicast-pitch-specification"
        },
        {
          "key": "SRC-COINBASE",
          "title": "Coinbase Exchange WebSocket channels",
          "author": "Coinbase",
          "url": "https://docs.cdp.coinbase.com/exchange/websocket-feed/channels"
        },
        {
          "key": "SRC-UTP",
          "title": "UTP Quote Data Feed",
          "author": "UTP Plan",
          "url": "https://www.utpplan.com/DOC/uqdfspecification.pdf"
        },
        {
          "key": "SRC-UTP-2026",
          "title": "UTP odd-lot data service update",
          "author": "UTP Plan / Nasdaq Trader",
          "url": "https://m.nasdaqtrader.com/TraderNews.aspx?id=UTP2026-05"
        },
        {
          "key": "SRC-UTP-CURRENT",
          "title": "UTP Data Feed Services Specification",
          "author": "UTP Plan",
          "url": "https://utpplan.com/DOC/UtpBinaryOutputSpec-3.0a.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/order-book-feed-engineering/trade-and-quote-event-normalization/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/order-book-feed-engineering/trade-and-quote-event-normalization/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F05-A02",
      "name": "Level-2 Snapshot-and-Delta Reconstruction",
      "headline": null,
      "slug": "level-2-snapshot-and-delta-reconstruction",
      "path": "market-data-engineering/order-book-feed-engineering/level-2-snapshot-and-delta-reconstruction",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F05",
        "family": "Order-Book Feed Engineering",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/order-book-feed-engineering/level-2-snapshot-and-delta-reconstruction",
        "entry": "reconstructL2",
        "params": [
          "snapshot"
        ],
        "exports": [
          "normalizeEvents",
          "reconstructL2",
          "aggregatePriceLevels",
          "reconstructL3",
          "recoverSequenceStream",
          "reconcileSnapshotIncrementals",
          "consolidateVenues",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "reconstructL2(snapshot)"
      },
      "api": {
        "summary": "Rebuilds an aggregated price-level book from a snapshot plus the deltas that follow it. Level 2 shows quantity per price, not individual orders — the distinction matters because a delta that is applied twice corrupts the book invisibly.",
        "params": [
          {
            "name": "snapshot",
            "type": "L2Snapshot",
            "required": true,
            "description": "The starting snapshot with its sequence number, followed by the incremental updates to apply in order.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ book, applied, gaps, state }",
          "description": "The reconstructed book with the updates applied and any sequence gaps encountered — a book rebuilt across a gap is wrong and must be said so."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a delta's sequence precedes the snapshot",
            "behaviour": "reported as a gap rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(updates × levels)",
          "space": "O(levels)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "reconstructL2({\"bids\":[{\"price_ticks\":10000,\"quantity\":20},{\"price_ticks\":9999,\"quantity\":25},{\"price_ticks\":9998,\"quantity\":30}],\"asks\":[{\"price_ticks\":10002,\"quantity\":18},{\"price_ticks\":10003,\"quantity\":22},{\"price_ticks\":10004,\"quantity\":26}]}, {\"snapshot_sequence\":500,\"deltas\":[{\"sequence\":501,\"side\":\"bid\",\"price_ticks\":10000,\"quantity\":12},{\"sequence\":502,\"side\":\"ask\",\"price_ticks\":10002,\"quantity\":19},{\"sequence\":503,\"side\":\"bid\",\"price_ticks\":9999,\"quantity\":26}]})",
        "args": [
          {
            "value": {
              "bids": [
                {
                  "price_ticks": 10000,
                  "quantity": 20
                },
                {
                  "price_ticks": 9999,
                  "quantity": 25
                },
                {
                  "price_ticks": 9998,
                  "quantity": 30
                }
              ],
              "asks": [
                {
                  "price_ticks": 10002,
                  "quantity": 18
                },
                {
                  "price_ticks": 10003,
                  "quantity": 22
                },
                {
                  "price_ticks": 10004,
                  "quantity": 26
                }
              ]
            },
            "elided": null
          },
          {
            "value": {
              "snapshot_sequence": 500,
              "deltas": [
                {
                  "sequence": 501,
                  "side": "bid",
                  "price_ticks": 10000,
                  "quantity": 12
                },
                {
                  "sequence": 502,
                  "side": "ask",
                  "price_ticks": 10002,
                  "quantity": 19
                },
                {
                  "sequence": 503,
                  "side": "bid",
                  "price_ticks": 9999,
                  "quantity": 26
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "quantity_semantics": "absolute-replacement",
          "snapshot_sequence": 500,
          "last_sequence": 524,
          "applied_sequences": [
            501,
            502,
            503,
            504,
            505,
            506
          ],
          "applied_count": 24,
          "discarded_sequences": [],
          "discarded_count": 0,
          "bids": [
            {
              "price_ticks": 10000,
              "quantity": 17
            },
            {
              "price_ticks": 9998,
              "quantity": 14
            },
            {
              "price_ticks": 9997,
              "quantity": 28
            }
          ],
          "asks": [
            {
              "price_ticks": 10002,
              "quantity": 24
            },
            {
              "price_ticks": 10003,
              "quantity": 38
            },
            {
              "price_ticks": 10004,
              "quantity": 21
            }
          ],
          "best_bid_ticks": 10000,
          "best_ask_ticks": 10002,
          "state": "current"
        },
        "outputElided": null,
        "outputShape": "object with 12 fields: quantity_semantics, snapshot_sequence, last_sequence, applied_sequences, applied_count, discarded_sequences, discarded_count, bids, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "d11-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a02/static/d11-handoff.svg"
          },
          {
            "file": "failure-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a02/static/failure-map.svg"
          },
          {
            "file": "sequence-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a02/static/sequence-boundary.svg"
          },
          {
            "file": "state-transition.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a02/static/state-transition.svg"
          },
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Topic-specific source roles",
          "title": "Topic-specific source roles",
          "author": null,
          "url": null
        },
        {
          "key": "SRC-ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification_5.0.pdf"
        },
        {
          "key": "SRC-GLIMPSE",
          "title": "Nasdaq GLIMPSE 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQGlimpseSpecification_5.0.pdf"
        },
        {
          "key": "SRC-MOLD",
          "title": "MoldUDP64 protocol",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/moldudp64.pdf"
        },
        {
          "key": "SRC-FIX",
          "title": "FIX recommended practices for book management",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/wp-content/uploads/download-manager-files/MDOWG_Book_Mgt-v20.pdf"
        },
        {
          "key": "SRC-CBOE",
          "title": "Cboe Multicast PITCH specification",
          "author": "Cboe Global Markets",
          "url": "https://www.cboe.com/document/tech-spec/document/technical-specifications/cboe-titanium-u.s.-equitiesoptions-multicast-pitch-specification"
        },
        {
          "key": "SRC-COINBASE",
          "title": "Coinbase Exchange WebSocket channels",
          "author": "Coinbase",
          "url": "https://docs.cdp.coinbase.com/exchange/websocket-feed/channels"
        },
        {
          "key": "SRC-UTP",
          "title": "UTP Quote Data Feed",
          "author": "UTP Plan",
          "url": "https://www.utpplan.com/DOC/uqdfspecification.pdf"
        },
        {
          "key": "SRC-UTP-2026",
          "title": "UTP odd-lot data service update",
          "author": "UTP Plan / Nasdaq Trader",
          "url": "https://m.nasdaqtrader.com/TraderNews.aspx?id=UTP2026-05"
        },
        {
          "key": "SRC-UTP-CURRENT",
          "title": "UTP Data Feed Services Specification",
          "author": "UTP Plan",
          "url": "https://utpplan.com/DOC/UtpBinaryOutputSpec-3.0a.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/order-book-feed-engineering/level-2-snapshot-and-delta-reconstruction/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/order-book-feed-engineering/level-2-snapshot-and-delta-reconstruction/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F05-A03",
      "name": "Level-3 Order-by-Order Reconstruction",
      "headline": null,
      "slug": "level-3-order-by-order-reconstruction",
      "path": "market-data-engineering/order-book-feed-engineering/level-3-order-by-order-reconstruction",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F05",
        "family": "Order-Book Feed Engineering",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/order-book-feed-engineering/level-3-order-by-order-reconstruction",
        "entry": "reconstructL3",
        "params": [
          "snapshot_orders"
        ],
        "exports": [
          "normalizeEvents",
          "reconstructL2",
          "aggregatePriceLevels",
          "reconstructL3",
          "recoverSequenceStream",
          "reconcileSnapshotIncrementals",
          "consolidateVenues",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "reconstructL3(snapshot_orders)"
      },
      "api": {
        "summary": "Rebuilds the book order by order rather than by price level. Level 3 preserves queue position, which is the only way to answer where in the queue an order actually sits — and therefore the only basis for a realistic fill model.",
        "params": [
          {
            "name": "snapshot_orders",
            "type": "L3Order[]",
            "required": true,
            "description": "Individual resting orders with their identifiers, prices, quantities and arrival order.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ book, orders, queue_state, diagnostics }",
          "description": "The order-level book with queue positions preserved."
        },
        "warmup": null,
        "errors": [
          {
            "when": "an update references an order id not in the book",
            "behaviour": "recorded in diagnostics rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(orders)",
          "space": "O(orders)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "reconstructL3([{\"order_id\":\"B1\",\"side\":\"bid\",\"price_ticks\":10001,\"quantity\":12},{\"order_id\":\"B2\",\"side\":\"bid\",\"price_ticks\":10000,\"quantity\":14},{\"order_id\":\"B3\",\"side\":\"bid\",\"price_ticks\":10000,\"quantity\":16}], {\"snapshot_sequence\":800,\"events\":[{\"sequence\":801,\"action\":\"add\",\"order_id\":\"N1\",\"side\":\"bid\",\"price_ticks\":10001,\"quantity\":9},{\"sequence\":802,\"action\":\"execute\",\"order_id\":\"A1\",\"quantity\":3},{\"sequence\":803,\"action\":\"reduce\",\"order_id\":\"B1\",\"quantity\":2}]})",
        "args": [
          {
            "value": [
              {
                "order_id": "B1",
                "side": "bid",
                "price_ticks": 10001,
                "quantity": 12
              },
              {
                "order_id": "B2",
                "side": "bid",
                "price_ticks": 10000,
                "quantity": 14
              },
              {
                "order_id": "B3",
                "side": "bid",
                "price_ticks": 10000,
                "quantity": 16
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 12
            }
          },
          {
            "value": {
              "snapshot_sequence": 800,
              "events": [
                {
                  "sequence": 801,
                  "action": "add",
                  "order_id": "N1",
                  "side": "bid",
                  "price_ticks": 10001,
                  "quantity": 9
                },
                {
                  "sequence": 802,
                  "action": "execute",
                  "order_id": "A1",
                  "quantity": 3
                },
                {
                  "sequence": 803,
                  "action": "reduce",
                  "order_id": "B1",
                  "quantity": 2
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "snapshot_sequence": 800,
          "last_sequence": 820,
          "order_count": 16,
          "event_count": 20,
          "action_counts": {
            "add": 7,
            "reduce": 4,
            "execute": 4,
            "delete": 3,
            "replace": 2
          },
          "orders": [
            {
              "order_id": "B1",
              "side": "bid",
              "price_ticks": 10001,
              "quantity": 10,
              "priority_rank": 1
            },
            {
              "order_id": "B5",
              "side": "bid",
              "price_ticks": 9999,
              "quantity": 17,
              "priority_rank": 5
            },
            {
              "order_id": "B6",
              "side": "bid",
              "price_ticks": 9998,
              "quantity": 22,
              "priority_rank": 6
            }
          ],
          "bids": [
            {
              "price_ticks": 10001,
              "quantity": 22,
              "order_count": 3
            },
            {
              "price_ticks": 10000,
              "quantity": 15,
              "order_count": 1
            },
            {
              "price_ticks": 9999,
              "quantity": 30,
              "order_count": 2
            }
          ],
          "asks": [
            {
              "price_ticks": 10002,
              "quantity": 13,
              "order_count": 2
            },
            {
              "price_ticks": 10003,
              "quantity": 16,
              "order_count": 1
            },
            {
              "price_ticks": 10004,
              "quantity": 31,
              "order_count": 2
            }
          ],
          "state": "current"
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: snapshot_sequence, last_sequence, order_count, event_count, action_counts, orders, bids, asks, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "d11-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a03/static/d11-handoff.svg"
          },
          {
            "file": "failure-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a03/static/failure-map.svg"
          },
          {
            "file": "sequence-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a03/static/sequence-boundary.svg"
          },
          {
            "file": "state-transition.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a03/static/state-transition.svg"
          },
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Topic-specific source roles",
          "title": "Topic-specific source roles",
          "author": null,
          "url": null
        },
        {
          "key": "SRC-ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification_5.0.pdf"
        },
        {
          "key": "SRC-GLIMPSE",
          "title": "Nasdaq GLIMPSE 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQGlimpseSpecification_5.0.pdf"
        },
        {
          "key": "SRC-MOLD",
          "title": "MoldUDP64 protocol",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/moldudp64.pdf"
        },
        {
          "key": "SRC-FIX",
          "title": "FIX recommended practices for book management",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/wp-content/uploads/download-manager-files/MDOWG_Book_Mgt-v20.pdf"
        },
        {
          "key": "SRC-CBOE",
          "title": "Cboe Multicast PITCH specification",
          "author": "Cboe Global Markets",
          "url": "https://www.cboe.com/document/tech-spec/document/technical-specifications/cboe-titanium-u.s.-equitiesoptions-multicast-pitch-specification"
        },
        {
          "key": "SRC-COINBASE",
          "title": "Coinbase Exchange WebSocket channels",
          "author": "Coinbase",
          "url": "https://docs.cdp.coinbase.com/exchange/websocket-feed/channels"
        },
        {
          "key": "SRC-UTP",
          "title": "UTP Quote Data Feed",
          "author": "UTP Plan",
          "url": "https://www.utpplan.com/DOC/uqdfspecification.pdf"
        },
        {
          "key": "SRC-UTP-2026",
          "title": "UTP odd-lot data service update",
          "author": "UTP Plan / Nasdaq Trader",
          "url": "https://m.nasdaqtrader.com/TraderNews.aspx?id=UTP2026-05"
        },
        {
          "key": "SRC-UTP-CURRENT",
          "title": "UTP Data Feed Services Specification",
          "author": "UTP Plan",
          "url": "https://utpplan.com/DOC/UtpBinaryOutputSpec-3.0a.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/order-book-feed-engineering/level-3-order-by-order-reconstruction/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/order-book-feed-engineering/level-3-order-by-order-reconstruction/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F05-A04",
      "name": "Sequence-Gap Detection and Recovery",
      "headline": null,
      "slug": "sequence-gap-detection-and-recovery",
      "path": "market-data-engineering/order-book-feed-engineering/sequence-gap-detection-and-recovery",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F05",
        "family": "Order-Book Feed Engineering",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/order-book-feed-engineering/sequence-gap-detection-and-recovery",
        "entry": "recoverSequenceStream",
        "params": [
          "arrivals"
        ],
        "exports": [
          "normalizeEvents",
          "reconstructL2",
          "aggregatePriceLevels",
          "reconstructL3",
          "recoverSequenceStream",
          "reconcileSnapshotIncrementals",
          "consolidateVenues",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "recoverSequenceStream(arrivals)"
      },
      "api": {
        "summary": "Detects missing sequence numbers and decides whether the stream can continue or must resynchronise from a snapshot. A gap is not a nuisance — every message after it is applied to a book that is already wrong.",
        "params": [
          {
            "name": "arrivals",
            "type": "Arrival[]",
            "required": true,
            "description": "Messages with their sequence numbers, in arrival order — which is not necessarily sequence order.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, gaps, recovered, resync_required, … }",
          "description": "Each gap with whether it was recoverable from buffered messages or requires a snapshot resync."
        },
        "warmup": null,
        "errors": [
          {
            "when": "sequence numbers are absent",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "recoverSequenceStream([{\"sequence\":100,\"source\":\"live\"},{\"sequence\":102,\"source\":\"live\"},{\"sequence\":103,\"source\":\"live\"}], {\"start_sequence\":100})",
        "args": [
          {
            "value": [
              {
                "sequence": 100,
                "source": "live"
              },
              {
                "sequence": 102,
                "source": "live"
              },
              {
                "sequence": 103,
                "source": "live"
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 18
            }
          },
          {
            "value": {
              "start_sequence": 100
            },
            "elided": null
          }
        ],
        "output": {
          "start_sequence": 100,
          "applied_sequences": [
            100,
            101,
            102,
            103,
            104,
            105
          ],
          "next_expected": 117,
          "missing_sequences": [],
          "buffered_sequences": [],
          "duplicate_sequences": [
            107
          ],
          "recovery_requests": [
            {
              "from_sequence": 101,
              "to_sequence": 101
            },
            {
              "from_sequence": 104,
              "to_sequence": 104
            },
            {
              "from_sequence": 106,
              "to_sequence": 106
            }
          ],
          "recovery_request_count": 5,
          "replay_arrival_count": 6,
          "trace": [
            {
              "arrival_sequence": 100,
              "source": "live",
              "next_expected": 101,
              "missing": [],
              "buffered": []
            },
            {
              "arrival_sequence": 102,
              "source": "live",
              "next_expected": 101,
              "missing": [
                101
              ],
              "buffered": [
                102
              ]
            },
            {
              "arrival_sequence": 103,
              "source": "live",
              "next_expected": 101,
              "missing": [
                101
              ],
              "buffered": [
                102,
                103
              ]
            }
          ],
          "state": "current"
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: start_sequence, applied_sequences, next_expected, missing_sequences, buffered_sequences, duplicate_sequences, recovery_requests, recovery_request_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "d11-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a04/static/d11-handoff.svg"
          },
          {
            "file": "failure-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a04/static/failure-map.svg"
          },
          {
            "file": "sequence-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a04/static/sequence-boundary.svg"
          },
          {
            "file": "state-transition.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a04/static/state-transition.svg"
          },
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Topic-specific source roles",
          "title": "Topic-specific source roles",
          "author": null,
          "url": null
        },
        {
          "key": "SRC-ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification_5.0.pdf"
        },
        {
          "key": "SRC-GLIMPSE",
          "title": "Nasdaq GLIMPSE 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQGlimpseSpecification_5.0.pdf"
        },
        {
          "key": "SRC-MOLD",
          "title": "MoldUDP64 protocol",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/moldudp64.pdf"
        },
        {
          "key": "SRC-FIX",
          "title": "FIX recommended practices for book management",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/wp-content/uploads/download-manager-files/MDOWG_Book_Mgt-v20.pdf"
        },
        {
          "key": "SRC-CBOE",
          "title": "Cboe Multicast PITCH specification",
          "author": "Cboe Global Markets",
          "url": "https://www.cboe.com/document/tech-spec/document/technical-specifications/cboe-titanium-u.s.-equitiesoptions-multicast-pitch-specification"
        },
        {
          "key": "SRC-COINBASE",
          "title": "Coinbase Exchange WebSocket channels",
          "author": "Coinbase",
          "url": "https://docs.cdp.coinbase.com/exchange/websocket-feed/channels"
        },
        {
          "key": "SRC-UTP",
          "title": "UTP Quote Data Feed",
          "author": "UTP Plan",
          "url": "https://www.utpplan.com/DOC/uqdfspecification.pdf"
        },
        {
          "key": "SRC-UTP-2026",
          "title": "UTP odd-lot data service update",
          "author": "UTP Plan / Nasdaq Trader",
          "url": "https://m.nasdaqtrader.com/TraderNews.aspx?id=UTP2026-05"
        },
        {
          "key": "SRC-UTP-CURRENT",
          "title": "UTP Data Feed Services Specification",
          "author": "UTP Plan",
          "url": "https://utpplan.com/DOC/UtpBinaryOutputSpec-3.0a.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/order-book-feed-engineering/sequence-gap-detection-and-recovery/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/order-book-feed-engineering/sequence-gap-detection-and-recovery/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F05-A05",
      "name": "Price-Level Quantity Aggregation",
      "headline": null,
      "slug": "price-level-quantity-aggregation",
      "path": "market-data-engineering/order-book-feed-engineering/price-level-quantity-aggregation",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F05",
        "family": "Order-Book Feed Engineering",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/order-book-feed-engineering/price-level-quantity-aggregation",
        "entry": "aggregatePriceLevels",
        "params": [
          "orders"
        ],
        "exports": [
          "normalizeEvents",
          "reconstructL2",
          "aggregatePriceLevels",
          "reconstructL3",
          "recoverSequenceStream",
          "reconcileSnapshotIncrementals",
          "consolidateVenues",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "aggregatePriceLevels(orders)"
      },
      "api": {
        "summary": "Collapses individual orders into quantity per price level — the Level 3 to Level 2 projection, and the form most analytics actually consume.",
        "params": [
          {
            "name": "orders",
            "type": "Order[]",
            "required": true,
            "description": "Individual resting orders with price, quantity and side.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ bids, asks, level_count, … }",
          "description": "Aggregated levels per side, sorted outward from the touch."
        },
        "warmup": null,
        "errors": [
          {
            "when": "an order has a non-positive quantity",
            "behaviour": "excluded and reported"
          }
        ],
        "complexity": {
          "time": "O(orders log levels)",
          "space": "O(levels)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "aggregatePriceLevels([{\"order_id\":\"B00\",\"side\":\"bid\",\"price_ticks\":10000,\"quantity\":4},{\"order_id\":\"A01\",\"side\":\"ask\",\"price_ticks\":10002,\"quantity\":9},{\"order_id\":\"B02\",\"side\":\"bid\",\"price_ticks\":9999,\"quantity\":14}], {\"depth_limit\":5})",
        "args": [
          {
            "value": [
              {
                "order_id": "B00",
                "side": "bid",
                "price_ticks": 10000,
                "quantity": 4
              },
              {
                "order_id": "A01",
                "side": "ask",
                "price_ticks": 10002,
                "quantity": 9
              },
              {
                "order_id": "B02",
                "side": "bid",
                "price_ticks": 9999,
                "quantity": 14
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 32
            }
          },
          {
            "value": {
              "depth_limit": 5
            },
            "elided": null
          }
        ],
        "output": {
          "order_count": 32,
          "full_bid_level_count": 8,
          "full_ask_level_count": 8,
          "depth_limit": 5,
          "bids": [
            {
              "price_ticks": 10000,
              "quantity": 12,
              "order_count": 2
            },
            {
              "price_ticks": 9999,
              "quantity": 32,
              "order_count": 2
            },
            {
              "price_ticks": 9998,
              "quantity": 14,
              "order_count": 2
            }
          ],
          "asks": [
            {
              "price_ticks": 10002,
              "quantity": 22,
              "order_count": 2
            },
            {
              "price_ticks": 10003,
              "quantity": 23,
              "order_count": 2
            },
            {
              "price_ticks": 10004,
              "quantity": 24,
              "order_count": 2
            }
          ],
          "visible_bid_quantity": 108,
          "visible_ask_quantity": 120,
          "full_bid_quantity": 200,
          "full_ask_quantity": 204,
          "hidden_by_depth_limit_bid_quantity": 92,
          "hidden_by_depth_limit_ask_quantity": 84,
          "state": "aggregated"
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: order_count, full_bid_level_count, full_ask_level_count, depth_limit, bids, asks, visible_bid_quantity, visible_ask_quantity, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "d11-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a05/static/d11-handoff.svg"
          },
          {
            "file": "failure-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a05/static/failure-map.svg"
          },
          {
            "file": "sequence-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a05/static/sequence-boundary.svg"
          },
          {
            "file": "state-transition.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a05/static/state-transition.svg"
          },
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Topic-specific source roles",
          "title": "Topic-specific source roles",
          "author": null,
          "url": null
        },
        {
          "key": "SRC-ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification_5.0.pdf"
        },
        {
          "key": "SRC-GLIMPSE",
          "title": "Nasdaq GLIMPSE 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQGlimpseSpecification_5.0.pdf"
        },
        {
          "key": "SRC-MOLD",
          "title": "MoldUDP64 protocol",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/moldudp64.pdf"
        },
        {
          "key": "SRC-FIX",
          "title": "FIX recommended practices for book management",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/wp-content/uploads/download-manager-files/MDOWG_Book_Mgt-v20.pdf"
        },
        {
          "key": "SRC-CBOE",
          "title": "Cboe Multicast PITCH specification",
          "author": "Cboe Global Markets",
          "url": "https://www.cboe.com/document/tech-spec/document/technical-specifications/cboe-titanium-u.s.-equitiesoptions-multicast-pitch-specification"
        },
        {
          "key": "SRC-COINBASE",
          "title": "Coinbase Exchange WebSocket channels",
          "author": "Coinbase",
          "url": "https://docs.cdp.coinbase.com/exchange/websocket-feed/channels"
        },
        {
          "key": "SRC-UTP",
          "title": "UTP Quote Data Feed",
          "author": "UTP Plan",
          "url": "https://www.utpplan.com/DOC/uqdfspecification.pdf"
        },
        {
          "key": "SRC-UTP-2026",
          "title": "UTP odd-lot data service update",
          "author": "UTP Plan / Nasdaq Trader",
          "url": "https://m.nasdaqtrader.com/TraderNews.aspx?id=UTP2026-05"
        },
        {
          "key": "SRC-UTP-CURRENT",
          "title": "UTP Data Feed Services Specification",
          "author": "UTP Plan",
          "url": "https://utpplan.com/DOC/UtpBinaryOutputSpec-3.0a.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/order-book-feed-engineering/price-level-quantity-aggregation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/order-book-feed-engineering/price-level-quantity-aggregation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F05-A06",
      "name": "Snapshot/Incremental-Feed Reconciliation",
      "headline": null,
      "slug": "snapshot-incremental-feed-reconciliation",
      "path": "market-data-engineering/order-book-feed-engineering/snapshot-incremental-feed-reconciliation",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F05",
        "family": "Order-Book Feed Engineering",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/order-book-feed-engineering/snapshot-incremental-feed-reconciliation",
        "entry": "reconcileSnapshotIncrementals",
        "params": [
          "snapshot"
        ],
        "exports": [
          "normalizeEvents",
          "reconstructL2",
          "aggregatePriceLevels",
          "reconstructL3",
          "recoverSequenceStream",
          "reconcileSnapshotIncrementals",
          "consolidateVenues",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "reconcileSnapshotIncrementals(snapshot)"
      },
      "api": {
        "summary": "Reconciles a periodic snapshot against the book built from incrementals. Any divergence means the incremental path has been silently wrong — possibly for hours — and this is the only routine that catches it.",
        "params": [
          {
            "name": "snapshot",
            "type": "Snapshot",
            "required": true,
            "description": "The authoritative snapshot, together with the incrementally-maintained book to compare it against.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, differences, matched_levels, … }",
          "description": "Level-by-level differences, so a divergence can be localised rather than triggering a blanket rebuild."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the snapshot and book are for different instruments",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(levels)",
          "space": "O(differences)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "reconcileSnapshotIncrementals({\"bids\":[{\"price_ticks\":10000,\"quantity\":20},{\"price_ticks\":9999,\"quantity\":25},{\"price_ticks\":9998,\"quantity\":30}],\"asks\":[{\"price_ticks\":10002,\"quantity\":18},{\"price_ticks\":10003,\"quantity\":22},{\"price_ticks\":10004,\"quantity\":26}]}, {\"snapshot_sequence\":200,\"incrementals\":[{\"sequence\":201,\"side\":\"bid\",\"price_ticks\":10000,\"quantity\":10},{\"sequence\":202,\"side\":\"ask\",\"price_ticks\":10002,\"quantity\":13},{\"sequence\":203,\"side\":\"bid\",\"price_ticks\":9999,\"quantity\":16}],\"checkpoint\":{\"bids\":[{\"price_ticks\":10000,\"quantity\":23},{\"price_ticks\":9999,\"quantity\":29},{\"price_ticks\":9998,\"quantity\":35}],\"asks\":[{\"price_ticks\":10002,\"quantity\":26},{\"price_ticks\":10004,\"quantity\":38},{\"price_ticks\":10005,\"quantity\":15}]},\"checkpoint_sequence\":224})",
        "args": [
          {
            "value": {
              "bids": [
                {
                  "price_ticks": 10000,
                  "quantity": 20
                },
                {
                  "price_ticks": 9999,
                  "quantity": 25
                },
                {
                  "price_ticks": 9998,
                  "quantity": 30
                }
              ],
              "asks": [
                {
                  "price_ticks": 10002,
                  "quantity": 18
                },
                {
                  "price_ticks": 10003,
                  "quantity": 22
                },
                {
                  "price_ticks": 10004,
                  "quantity": 26
                }
              ]
            },
            "elided": null
          },
          {
            "value": {
              "snapshot_sequence": 200,
              "incrementals": [
                {
                  "sequence": 201,
                  "side": "bid",
                  "price_ticks": 10000,
                  "quantity": 10
                },
                {
                  "sequence": 202,
                  "side": "ask",
                  "price_ticks": 10002,
                  "quantity": 13
                },
                {
                  "sequence": 203,
                  "side": "bid",
                  "price_ticks": 9999,
                  "quantity": 16
                }
              ],
              "checkpoint": {
                "bids": [
                  {
                    "price_ticks": 10000,
                    "quantity": 23
                  },
                  {
                    "price_ticks": 9999,
                    "quantity": 29
                  },
                  {
                    "price_ticks": 9998,
                    "quantity": 35
                  }
                ],
                "asks": [
                  {
                    "price_ticks": 10002,
                    "quantity": 26
                  },
                  {
                    "price_ticks": 10004,
                    "quantity": 38
                  },
                  {
                    "price_ticks": 10005,
                    "quantity": 15
                  }
                ]
              },
              "checkpoint_sequence": 224
            },
            "elided": null
          }
        ],
        "output": {
          "snapshot_sequence": 200,
          "checkpoint_sequence": 224,
          "compared_level_count": 12,
          "difference_count": 0,
          "mismatch_counts": {
            "quantity-mismatch": 0,
            "missing-reconstructed-level": 0,
            "missing-checkpoint-level": 0
          },
          "replayed_incremental_count": 24,
          "pending_after_checkpoint_count": 0,
          "differences": [],
          "reconstructed": {
            "bids": [
              {
                "price_ticks": 10000,
                "quantity": 23
              },
              {
                "price_ticks": 9999,
                "quantity": 29
              },
              {
                "price_ticks": 9998,
                "quantity": 35
              }
            ],
            "asks": [
              {
                "price_ticks": 10002,
                "quantity": 26
              },
              {
                "price_ticks": 10004,
                "quantity": 38
              },
              {
                "price_ticks": 10005,
                "quantity": 15
              }
            ]
          },
          "checkpoint": {
            "bids": [
              {
                "price_ticks": 10000,
                "quantity": 23
              },
              {
                "price_ticks": 9999,
                "quantity": 29
              },
              {
                "price_ticks": 9998,
                "quantity": 35
              }
            ],
            "asks": [
              {
                "price_ticks": 10002,
                "quantity": 26
              },
              {
                "price_ticks": 10004,
                "quantity": 38
              },
              {
                "price_ticks": 10005,
                "quantity": 15
              }
            ]
          },
          "state": "reconciled"
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: snapshot_sequence, checkpoint_sequence, compared_level_count, difference_count, mismatch_counts, replayed_incremental_count, pending_after_checkpoint_count, differences, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "d11-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a06/static/d11-handoff.svg"
          },
          {
            "file": "failure-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a06/static/failure-map.svg"
          },
          {
            "file": "sequence-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a06/static/sequence-boundary.svg"
          },
          {
            "file": "state-transition.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a06/static/state-transition.svg"
          },
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a06/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Topic-specific source roles",
          "title": "Topic-specific source roles",
          "author": null,
          "url": null
        },
        {
          "key": "SRC-ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification_5.0.pdf"
        },
        {
          "key": "SRC-GLIMPSE",
          "title": "Nasdaq GLIMPSE 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQGlimpseSpecification_5.0.pdf"
        },
        {
          "key": "SRC-MOLD",
          "title": "MoldUDP64 protocol",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/moldudp64.pdf"
        },
        {
          "key": "SRC-FIX",
          "title": "FIX recommended practices for book management",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/wp-content/uploads/download-manager-files/MDOWG_Book_Mgt-v20.pdf"
        },
        {
          "key": "SRC-CBOE",
          "title": "Cboe Multicast PITCH specification",
          "author": "Cboe Global Markets",
          "url": "https://www.cboe.com/document/tech-spec/document/technical-specifications/cboe-titanium-u.s.-equitiesoptions-multicast-pitch-specification"
        },
        {
          "key": "SRC-COINBASE",
          "title": "Coinbase Exchange WebSocket channels",
          "author": "Coinbase",
          "url": "https://docs.cdp.coinbase.com/exchange/websocket-feed/channels"
        },
        {
          "key": "SRC-UTP",
          "title": "UTP Quote Data Feed",
          "author": "UTP Plan",
          "url": "https://www.utpplan.com/DOC/uqdfspecification.pdf"
        },
        {
          "key": "SRC-UTP-2026",
          "title": "UTP odd-lot data service update",
          "author": "UTP Plan / Nasdaq Trader",
          "url": "https://m.nasdaqtrader.com/TraderNews.aspx?id=UTP2026-05"
        },
        {
          "key": "SRC-UTP-CURRENT",
          "title": "UTP Data Feed Services Specification",
          "author": "UTP Plan",
          "url": "https://utpplan.com/DOC/UtpBinaryOutputSpec-3.0a.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/order-book-feed-engineering/snapshot-incremental-feed-reconciliation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/order-book-feed-engineering/snapshot-incremental-feed-reconciliation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D01-F05-A07",
      "name": "Multi-Venue Best-Quote and Book Consolidation",
      "headline": null,
      "slug": "multi-venue-best-quote-and-book-consolidation",
      "path": "market-data-engineering/order-book-feed-engineering/multi-venue-best-quote-and-book-consolidation",
      "taxonomy": {
        "domainId": "D01",
        "domain": "Market Data Engineering",
        "familyId": "D01-F05",
        "family": "Order-Book Feed Engineering",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-data-engineering/order-book-feed-engineering/multi-venue-best-quote-and-book-consolidation",
        "entry": "consolidateVenues",
        "params": [
          "quotes"
        ],
        "exports": [
          "normalizeEvents",
          "reconstructL2",
          "aggregatePriceLevels",
          "reconstructL3",
          "recoverSequenceStream",
          "reconcileSnapshotIncrementals",
          "consolidateVenues",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "consolidateVenues(quotes)"
      },
      "api": {
        "summary": "Merges books from several venues into one consolidated view and identifies the best bid and offer across them. Venue clocks differ, so a naive merge can produce a consolidated book that was never simultaneously true.",
        "params": [
          {
            "name": "quotes",
            "type": "VenueQuote[]",
            "required": true,
            "description": "Per-venue quotes with their own timestamps, which is what makes staleness assessable per venue rather than globally.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ best_bid, best_ask, consolidated, contributors, stale_venues, … }",
          "description": "The consolidated top of book with which venue contributed each side, and any venue excluded as stale."
        },
        "warmup": null,
        "errors": [
          {
            "when": "no venue supplies a usable quote",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(venues × levels)",
          "space": "O(levels)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "consolidateVenues([{\"venue\":\"X1\",\"receive_time_ns\":950000,\"eligible\":true,\"status\":\"open\",\"bids\":[{\"price_ticks\":10000,\"quantity\":10},{\"price_ticks\":9999,\"quantity\":16},{\"price_ticks\":9998,\"quantity\":22}],\"asks\":[{\"price_ticks\":10003,\"quantity\":9},{\"price_ticks\":10004,\"quantity\":15},{\"price_ticks\":10005,\"quantity\":21}]},{\"venue\":\"X2\",\"receive_time_ns\":980000,\"eligible\":true,\"status\":\"open\",\"bids\":[{\"price_ticks\":10001,\"quantity\":6},{\"price_ticks\":10000,\"quantity\":12},{\"price_ticks\":9999,\"quantity\":18}],\"asks\":[{\"price_ticks\":10002,\"quantity\":7},{\"price_ticks\":10003,\"quantity\":11},{\"price_ticks\":10004,\"quantity\":17}]},{\"venue\":\"X3\",\"receive_time_ns\":850000,\"eligible\":true,\"status\":\"open\",\"bids\":[{\"price_ticks\":10001,\"quantity\":20},{\"price_ticks\":10000,\"quantity\":20}],\"asks\":[{\"price_ticks\":10003,\"quantity\":20},{\"price_ticks\":10004,\"quantity\":20}]}], {\"as_of_receive_time_ns\":1000000,\"max_staleness_ns\":100000})",
        "args": [
          {
            "value": [
              {
                "venue": "X1",
                "receive_time_ns": 950000,
                "eligible": true,
                "status": "open",
                "bids": [
                  {
                    "price_ticks": 10000,
                    "quantity": 10
                  },
                  {
                    "price_ticks": 9999,
                    "quantity": 16
                  },
                  {
                    "price_ticks": 9998,
                    "quantity": 22
                  }
                ],
                "asks": [
                  {
                    "price_ticks": 10003,
                    "quantity": 9
                  },
                  {
                    "price_ticks": 10004,
                    "quantity": 15
                  },
                  {
                    "price_ticks": 10005,
                    "quantity": 21
                  }
                ]
              },
              {
                "venue": "X2",
                "receive_time_ns": 980000,
                "eligible": true,
                "status": "open",
                "bids": [
                  {
                    "price_ticks": 10001,
                    "quantity": 6
                  },
                  {
                    "price_ticks": 10000,
                    "quantity": 12
                  },
                  {
                    "price_ticks": 9999,
                    "quantity": 18
                  }
                ],
                "asks": [
                  {
                    "price_ticks": 10002,
                    "quantity": 7
                  },
                  {
                    "price_ticks": 10003,
                    "quantity": 11
                  },
                  {
                    "price_ticks": 10004,
                    "quantity": 17
                  }
                ]
              },
              {
                "venue": "X3",
                "receive_time_ns": 850000,
                "eligible": true,
                "status": "open",
                "bids": [
                  {
                    "price_ticks": 10001,
                    "quantity": 20
                  },
                  {
                    "price_ticks": 10000,
                    "quantity": 20
                  }
                ],
                "asks": [
                  {
                    "price_ticks": 10003,
                    "quantity": 20
                  },
                  {
                    "price_ticks": 10004,
                    "quantity": 20
                  }
                ]
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": {
              "as_of_receive_time_ns": 1000000,
              "max_staleness_ns": 100000
            },
            "elided": null
          }
        ],
        "output": {
          "as_of_receive_time_ns": 1000000,
          "max_staleness_ns": 100000,
          "eligible_venue_count": 3,
          "excluded": [
            {
              "venue": "X3",
              "reason": "stale"
            },
            {
              "venue": "X4",
              "reason": "not-open"
            }
          ],
          "best_bid_ticks": 10001,
          "best_bid_quantity": 10,
          "best_bid_venues": [
            "X2",
            "X5"
          ],
          "best_ask_ticks": 10002,
          "best_ask_quantity": 12,
          "best_ask_venues": [
            "X2",
            "X5"
          ],
          "consolidated_book": {
            "bids": [
              {
                "price_ticks": 10001,
                "quantity": 10,
                "venues": [
                  "X2",
                  "X5"
                ]
              },
              {
                "price_ticks": 10000,
                "quantity": 31,
                "venues": [
                  "X1",
                  "X2",
                  "X5"
                ]
              },
              {
                "price_ticks": 9999,
                "quantity": 48,
                "venues": [
                  "X1",
                  "X2",
                  "X5"
                ]
              }
            ],
            "asks": [
              {
                "price_ticks": 10002,
                "quantity": 12,
                "venues": [
                  "X2",
                  "X5"
                ]
              },
              {
                "price_ticks": 10003,
                "quantity": 30,
                "venues": [
                  "X1",
                  "X2",
                  "X5"
                ]
              },
              {
                "price_ticks": 10004,
                "quantity": 47,
                "venues": [
                  "X1",
                  "X2",
                  "X5"
                ]
              }
            ]
          },
          "consolidated_levels": [
            {
              "side": "bid",
              "price_ticks": 10001,
              "quantity": 10,
              "venues": [
                "X2",
                "X5"
              ]
            },
            {
              "side": "bid",
              "price_ticks": 10000,
              "quantity": 31,
              "venues": [
                "X1",
                "X2",
                "X5"
              ]
            },
            {
              "side": "bid",
              "price_ticks": 9999,
              "quantity": 48,
              "venues": [
                "X1",
                "X2",
                "X5"
              ]
            }
          ],
          "state": "normal"
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: as_of_receive_time_ns, max_staleness_ns, eligible_venue_count, excluded, best_bid_ticks, best_bid_quantity, best_bid_venues, best_ask_ticks, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "d11-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a07/static/d11-handoff.svg"
          },
          {
            "file": "failure-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a07/static/failure-map.svg"
          },
          {
            "file": "sequence-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a07/static/sequence-boundary.svg"
          },
          {
            "file": "state-transition.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a07/static/state-transition.svg"
          },
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d01-f05-a07/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Topic-specific source roles",
          "title": "Topic-specific source roles",
          "author": null,
          "url": null
        },
        {
          "key": "SRC-ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification_5.0.pdf"
        },
        {
          "key": "SRC-GLIMPSE",
          "title": "Nasdaq GLIMPSE 5.0",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQGlimpseSpecification_5.0.pdf"
        },
        {
          "key": "SRC-MOLD",
          "title": "MoldUDP64 protocol",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/moldudp64.pdf"
        },
        {
          "key": "SRC-FIX",
          "title": "FIX recommended practices for book management",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/wp-content/uploads/download-manager-files/MDOWG_Book_Mgt-v20.pdf"
        },
        {
          "key": "SRC-CBOE",
          "title": "Cboe Multicast PITCH specification",
          "author": "Cboe Global Markets",
          "url": "https://www.cboe.com/document/tech-spec/document/technical-specifications/cboe-titanium-u.s.-equitiesoptions-multicast-pitch-specification"
        },
        {
          "key": "SRC-COINBASE",
          "title": "Coinbase Exchange WebSocket channels",
          "author": "Coinbase",
          "url": "https://docs.cdp.coinbase.com/exchange/websocket-feed/channels"
        },
        {
          "key": "SRC-UTP",
          "title": "UTP Quote Data Feed",
          "author": "UTP Plan",
          "url": "https://www.utpplan.com/DOC/uqdfspecification.pdf"
        },
        {
          "key": "SRC-UTP-2026",
          "title": "UTP odd-lot data service update",
          "author": "UTP Plan / Nasdaq Trader",
          "url": "https://m.nasdaqtrader.com/TraderNews.aspx?id=UTP2026-05"
        },
        {
          "key": "SRC-UTP-CURRENT",
          "title": "UTP Data Feed Services Specification",
          "author": "UTP Plan",
          "url": "https://utpplan.com/DOC/UtpBinaryOutputSpec-3.0a.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-data-engineering/order-book-feed-engineering/multi-venue-best-quote-and-book-consolidation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-data-engineering/order-book-feed-engineering/multi-venue-best-quote-and-book-consolidation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F01-A01",
      "name": "Backward Split Adjustment",
      "headline": null,
      "slug": "backward-split-adjustment",
      "path": "corporate-actions-and-security-master-data/adjustment-factors/backward-split-adjustment",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F01",
        "family": "Adjustment Factors",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/adjustment-factors/backward-split-adjustment",
        "entry": "calculate",
        "params": [
          "input"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(input)"
      },
      "api": {
        "summary": "Restates prices before a split onto the post-split basis so the series is continuous across the event. Without it a 2-for-1 split reads as a 50% crash, and every indicator and return computed over it is wrong.",
        "params": [
          {
            "name": "input",
            "type": "{ prices: number[]; volumes: number[]; eventIndex: number; postSplitSharesPerPreSplitShare: number }",
            "required": true,
            "description": "`prices` and `volumes` are the raw series; `eventIndex` is the first observation trading on the new basis. `postSplitSharesPerPreSplitShare` states the ratio in the only direction that is unambiguous — 2 means each old share became two, so pre-event prices are divided by 2 and volumes multiplied by it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ adjustedPrices, adjustedVolumes, eventIndex, ratioConvention }",
          "description": "The adjusted series plus the ratio convention that was applied, echoed back — because the single most common error in this calculation is inverting the ratio, and a result that states its own convention can be checked."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the ratio is not positive",
            "behaviour": "throws"
          },
          {
            "when": "eventIndex falls outside the series",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F01-A01.json",
        "call": "calculate({\"prices\":[120,123,60,62],\"volumes\":[1000,1200,2400,2000],\"eventIndex\":2,\"postSplitSharesPerPreSplitShare\":2})",
        "args": [
          {
            "value": {
              "prices": [
                120,
                123,
                60,
                62
              ],
              "volumes": [
                1000,
                1200,
                2400,
                2000
              ],
              "eventIndex": 2,
              "postSplitSharesPerPreSplitShare": 2
            },
            "elided": null
          }
        ],
        "output": {
          "adjustedPrices": [
            60,
            61.5,
            60,
            62
          ],
          "adjustedVolumes": [
            2000,
            2400,
            2400,
            2000
          ],
          "eventIndex": 2,
          "ratioConvention": "post_split_shares_per_pre_split_share"
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: adjustedPrices, adjustedVolumes, eventIndex, ratioConvention"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a01/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a01/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Backward Split Adjustment calculation flow",
            "source": "flowchart LR\n    A[\"Raw series and sourced event\"] --> B[\"Validate identity, dates, and units\"]\n    B --> C[\"Normalize ratio as post shares per pre share\"]\n    C --> D{\"Observation before eventIndex?\"}\n    D -->|Yes| E[\"Price ÷ r; share quantity × r\"]\n    D -->|No| F[\"Keep observation unchanged\"]\n    E --> G[\"Derived series with audit metadata\"]\n    F --> G\n    B -->|Invalid or ambiguous| H[\"Reject with diagnostic\"]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Backward Split Adjustment evidence lifecycle",
            "source": "stateDiagram-v2\n    [*] --> RawPreserved\n    RawPreserved --> EventValidated\n    EventValidated --> RatioNormalized\n    EventValidated --> Rejected: invalid or ambiguous evidence\n    RatioNormalized --> Eligible: available for declared as-of view\n    RatioNormalized --> NotYetAvailable: unavailable at decision time\n    Eligible --> Applied: transform pre-boundary observations\n    Applied --> Audited\n    NotYetAvailable --> Audited\n    Rejected --> Audited"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "Apple Reports Third Quarter Results",
          "author": "Apple Inc.",
          "url": null
        },
        {
          "key": "R2",
          "title": "Apple Form 8-K, accession 0001193125-20-213158",
          "author": "Apple Inc.; filed with the U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "R3",
          "title": "Apple 2020 Form 10-K",
          "author": "Apple Inc.; filed with the U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "R4",
          "title": "CRSP US Stock Data Descriptions Guide",
          "author": "Center for Research in Security Prices, surfaced through WRDS",
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/adjustment-factors/backward-split-adjustment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/adjustment-factors/backward-split-adjustment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F01-A02",
      "name": "Forward Split Adjustment",
      "headline": "carry later observations onto an earlier share basis",
      "slug": "forward-split-adjustment",
      "path": "corporate-actions-and-security-master-data/adjustment-factors/forward-split-adjustment",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F01",
        "family": "Adjustment Factors",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/adjustment-factors/forward-split-adjustment",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Restates a series onto a chosen basis date rather than onto the latest one, so a figure quoted in a historical report can still be reproduced after subsequent splits.",
        "params": [
          {
            "name": "data",
            "type": "{ targetBasisAt: string; knowledgeAt: string; roundDecimalPlaces?: number; observations: Observation[]; eventRevisions: EventRevision[] }",
            "required": true,
            "description": "`targetBasisAt` is the basis to express results on, and `knowledgeAt` bounds which event revisions may be used. `eventRevisions` carries the revision history rather than a single event, so a corrected ratio does not retroactively rewrite what was knowable earlier.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ basis, selectedRevisions, observations, warnings }",
          "description": "Adjusted observations, which revision of each event was selected, and warnings for anything that could not be applied — surfaced rather than dropped."
        },
        "warmup": null,
        "errors": [
          {
            "when": "targetBasisAt or knowledgeAt is not a valid timestamp",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n + e)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F01-A02.json",
        "call": "calculate({\"targetBasisAt\":\"2020-08-30T23:59:59Z\",\"knowledgeAt\":\"2020-09-02T00:00:00Z\",\"roundDecimalPlaces\":6,\"observations\":[{\"timestamp\":\"2020-08-28T20:00:00Z\",\"price\":120,\"volume\":1000,\"sharesOutstanding\":1000000},{\"timestamp\":\"2020-08-31T00:00:00Z\",\"price\":30,\"volume\":4000,\"sharesOutstanding\":4000000},{\"timestamp\":\"2020-09-01T00:00:00Z\",\"price\":31,\"volume\":3600,\"sharesOutstanding\":4000000}],\"eventRevisions\":[{\"eventId\":\"SYNTH-SPLIT-2020\",\"revisionId\":\"SYNTH-SPLIT-2020-R1\",\"supersedesRevisionId\":null,\"publishedAt\":\"2020-07-30T20:30:00Z\",\"effectiveAt\":\"2020-08-31T00:00:00Z\",\"newShares\":4,\"oldShares\":1,\"status\":\"active\",\"sourceId\":\"synthetic-fixture\"}]})",
        "args": [
          {
            "value": {
              "targetBasisAt": "2020-08-30T23:59:59Z",
              "knowledgeAt": "2020-09-02T00:00:00Z",
              "roundDecimalPlaces": 6,
              "observations": [
                {
                  "timestamp": "2020-08-28T20:00:00Z",
                  "price": 120,
                  "volume": 1000,
                  "sharesOutstanding": 1000000
                },
                {
                  "timestamp": "2020-08-31T00:00:00Z",
                  "price": 30,
                  "volume": 4000,
                  "sharesOutstanding": 4000000
                },
                {
                  "timestamp": "2020-09-01T00:00:00Z",
                  "price": 31,
                  "volume": 3600,
                  "sharesOutstanding": 4000000
                }
              ],
              "eventRevisions": [
                {
                  "eventId": "SYNTH-SPLIT-2020",
                  "revisionId": "SYNTH-SPLIT-2020-R1",
                  "supersedesRevisionId": null,
                  "publishedAt": "2020-07-30T20:30:00Z",
                  "effectiveAt": "2020-08-31T00:00:00Z",
                  "newShares": 4,
                  "oldShares": 1,
                  "status": "active",
                  "sourceId": "synthetic-fixture"
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "basis": {
            "targetBasisAt": "2020-08-30T23:59:59Z",
            "knowledgeAt": "2020-09-02T00:00:00Z",
            "ratioConvention": "new_shares_per_old_share",
            "boundaryRule": "targetBasisAt < effectiveAt <= observation.timestamp",
            "priceDirection": "multiply_post_boundary_values_to_earlier_basis",
            "quantityDirection": "divide_post_boundary_share_quantities_to_earlier_basis",
            "roundDecimalPlaces": 6
          },
          "selectedRevisions": [
            {
              "eventId": "SYNTH-SPLIT-2020",
              "revisionId": "SYNTH-SPLIT-2020-R1",
              "supersedesRevisionId": null,
              "publishedAt": "2020-07-30T20:30:00Z",
              "effectiveAt": "2020-08-31T00:00:00Z",
              "newShares": 4,
              "oldShares": 1,
              "status": "active",
              "sourceId": "synthetic-fixture"
            }
          ],
          "observations": [
            {
              "timestamp": "2020-08-28T20:00:00Z",
              "rawPrice": 120,
              "adjustedPrice": 120,
              "rawVolume": 1000,
              "adjustedVolume": 1000,
              "rawSharesOutstanding": 1000000,
              "adjustedSharesOutstanding": 1000000,
              "cumulativePriceFactor": 1,
              "cumulativeQuantityFactor": 1,
              "appliedEventIds": []
            },
            {
              "timestamp": "2020-08-31T00:00:00Z",
              "rawPrice": 30,
              "adjustedPrice": 120,
              "rawVolume": 4000,
              "adjustedVolume": 1000,
              "rawSharesOutstanding": 4000000,
              "adjustedSharesOutstanding": 1000000,
              "cumulativePriceFactor": 4,
              "cumulativeQuantityFactor": 0.25,
              "appliedEventIds": [
                "SYNTH-SPLIT-2020"
              ]
            },
            {
              "timestamp": "2020-09-01T00:00:00Z",
              "rawPrice": 31,
              "adjustedPrice": 124,
              "rawVolume": 3600,
              "adjustedVolume": 900,
              "rawSharesOutstanding": 4000000,
              "adjustedSharesOutstanding": 1000000,
              "cumulativePriceFactor": 4,
              "cumulativeQuantityFactor": 0.25,
              "appliedEventIds": [
                "SYNTH-SPLIT-2020"
              ]
            }
          ],
          "warnings": [
            "rounded outputs may not reverse exactly"
          ]
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: basis, selectedRevisions, observations, warnings"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a02/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a02/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Forward Split Adjustment calculation flow",
            "source": "flowchart LR\n    A[\"Raw observation and event revisions\"] --> B[\"Validate UTC, ratio, order, lineage\"]\n    B --> C[\"Latest revision published by knowledgeAt\"]\n    C --> D{\"Selected status active?\"}\n    D -->|No| E[\"Keep cancellation lineage; factor 1\"]\n    D -->|Yes| F{\"targetBasisAt < effectiveAt <= observation time?\"}\n    F -->|No| G[\"Factor 1\"]\n    F -->|Yes| H[\"Compound newShares / oldShares\"]\n    E --> I[\"Audited raw and adjusted output\"]\n    G --> I\n    H --> I"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Corporate-action revision lifecycle",
            "source": "stateDiagram-v2\n    [*] --> Unavailable\n    Unavailable --> Active: first revision published\n    Active --> Active: corrected active revision\n    Active --> Cancelled: cancellation published\n    Cancelled --> Active: later reinstatement revision\n    Active --> Eligible: effective boundary reached\n    Eligible --> Applied: observation is after anchor\n    Applied --> Audited\n    Cancelled --> Audited"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "Apple reports third quarter results",
          "author": null,
          "url": null
        },
        {
          "key": "R2",
          "title": "Apple Form 8-K filing detail, accession 0000320193-20-000060",
          "author": null,
          "url": null
        },
        {
          "key": "R3",
          "title": "Apple Form 8-K, accession 0001193125-20-213158",
          "author": null,
          "url": null
        },
        {
          "key": "R4",
          "title": "Apple 2020 Form 10-K, accession 0000320193-20-000096",
          "author": null,
          "url": null
        },
        {
          "key": "R5",
          "title": "Apple dividend and split history",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence classification",
          "title": "Evidence classification",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/adjustment-factors/forward-split-adjustment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/adjustment-factors/forward-split-adjustment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F01-A03",
      "name": "Cash-Dividend Total-Return Adjustment",
      "headline": "From Price Drop to Exact Return",
      "slug": "cash-dividend-total-return-adjustment",
      "path": "corporate-actions-and-security-master-data/adjustment-factors/cash-dividend-total-return-adjustment",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F01",
        "family": "Adjustment Factors",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/adjustment-factors/cash-dividend-total-return-adjustment",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Builds a total-return series by reinvesting cash dividends at the ex-date. Price charts ignore dividends, so every long-horizon number taken from one understates reality — by roughly 2% a year on a broad equity index.",
        "params": [
          {
            "name": "data",
            "type": "{ asOf: string; returnVariant: \"gross\" | \"net\"; priceCurrency: string; anchorBasis: string; specialDistributionPolicy: string; observations: Observation[]; eventRevisions: EventRevision[] }",
            "required": true,
            "description": "`returnVariant` selects gross or net of withholding tax — the same index quotes both, and they diverge materially over a decade. `specialDistributionPolicy` decides how non-recurring distributions are treated. Point-in-time by construction: `asOf` is the knowledge time, and only revisions available at or before it are eligible. Passing the event date instead of the knowledge date is what lets a backtest use information it could not have had.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ methodology, returnVariant, anchor, adjustedPrices, cumulativeFactors, eventAdjustments, … }",
          "description": "The adjusted series plus the cumulative factor chain and per-event adjustments, so any single figure can be traced back to the events that produced it."
        },
        "warmup": null,
        "errors": [
          {
            "when": "returnVariant is not recognised, or asOf is invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n + e)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F01-A03.json",
        "call": "calculate({\"asOf\":\"2026-01-09T23:00:00Z\",\"returnVariant\":\"gross\",\"priceCurrency\":\"USD\",\"anchorBasis\":\"latest_raw_close\",\"specialDistributionPolicy\":\"exclude\",\"observations\":[{\"date\":\"2026-01-02\",\"close\":100,\"availableAt\":\"2026-01-02T21:01:00Z\"},{\"date\":\"2026-01-05\",\"close\":102,\"availableAt\":\"2026-01-05T21:01:00Z\"},{\"date\":\"2026-01-06\",\"close\":99,\"availableAt\":\"2026-01-06T21:01:00Z\"}],\"eventRevisions\":[{\"eventId\":\"SYNTH-DIV-A\",\"revision\":1,\"status\":\"confirmed\",\"classification\":\"ordinary\",\"exDate\":\"2026-01-06\",\"grossDividend\":2.5,\"dividendCurrency\":\"USD\",\"withholdingRate\":0.15,\"fxRateToPriceCurrency\":1,\"fxObservedAt\":null,\"availableAt\":\"2026-01-05T15:00:00Z\",\"sourceId\":\"SYNTHETIC-ACTION-FEED\"},{\"eventId\":\"SYNTH-DIV-A\",\"revision\":2,\"status\":\"confirmed\",\"classification\":\"ordinary\",\"exDate\":\"2026-01-06\",\"grossDividend\":3,\"dividendCurrency\":\"USD\",\"withholdingRate\":0.15,\"fxRateToPriceCurrency\":1,\"fxObservedAt\":null,\"availableAt\":\"2026-01-05T18:00:00Z\",\"sourceId\":\"SYNTHETIC-ACTION-FEED\"},{\"eventId\":\"SYNTH-SPECIAL-B\",\"revision\":1,\"status\":\"confirmed\",\"classification\":\"special\",\"exDate\":\"2026-01-08\",\"grossDividend\":3,\"dividendCurrency\":\"USD\",\"withholdingRate\":0.15,\"fxRateToPriceCurrency\":1,\"fxObservedAt\":null,\"availableAt\":\"2026-01-07T18:00:00Z\",\"sourceId\":\"SYNTHETIC-ACTION-FEED\"}]})",
        "args": [
          {
            "value": {
              "asOf": "2026-01-09T23:00:00Z",
              "returnVariant": "gross",
              "priceCurrency": "USD",
              "anchorBasis": "latest_raw_close",
              "specialDistributionPolicy": "exclude",
              "observations": [
                {
                  "date": "2026-01-02",
                  "close": 100,
                  "availableAt": "2026-01-02T21:01:00Z"
                },
                {
                  "date": "2026-01-05",
                  "close": 102,
                  "availableAt": "2026-01-05T21:01:00Z"
                },
                {
                  "date": "2026-01-06",
                  "close": 99,
                  "availableAt": "2026-01-06T21:01:00Z"
                }
              ],
              "eventRevisions": [
                {
                  "eventId": "SYNTH-DIV-A",
                  "revision": 1,
                  "status": "confirmed",
                  "classification": "ordinary",
                  "exDate": "2026-01-06",
                  "grossDividend": 2.5,
                  "dividendCurrency": "USD",
                  "withholdingRate": 0.15,
                  "fxRateToPriceCurrency": 1,
                  "fxObservedAt": null,
                  "availableAt": "2026-01-05T15:00:00Z",
                  "sourceId": "SYNTHETIC-ACTION-FEED"
                },
                {
                  "eventId": "SYNTH-DIV-A",
                  "revision": 2,
                  "status": "confirmed",
                  "classification": "ordinary",
                  "exDate": "2026-01-06",
                  "grossDividend": 3,
                  "dividendCurrency": "USD",
                  "withholdingRate": 0.15,
                  "fxRateToPriceCurrency": 1,
                  "fxObservedAt": null,
                  "availableAt": "2026-01-05T18:00:00Z",
                  "sourceId": "SYNTHETIC-ACTION-FEED"
                },
                {
                  "eventId": "SYNTH-SPECIAL-B",
                  "revision": 1,
                  "status": "confirmed",
                  "classification": "special",
                  "exDate": "2026-01-08",
                  "grossDividend": 3,
                  "dividendCurrency": "USD",
                  "withholdingRate": 0.15,
                  "fxRateToPriceCurrency": 1,
                  "fxObservedAt": null,
                  "availableAt": "2026-01-07T18:00:00Z",
                  "sourceId": "SYNTHETIC-ACTION-FEED"
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "methodology": "backward_adjusted_ex_date_close_total_return",
          "returnVariant": "gross",
          "priceCurrency": "USD",
          "asOf": "2026-01-09T23:00:00Z",
          "anchor": {
            "basis": "latest_raw_close",
            "date": "2026-01-09",
            "rawClose": 100
          },
          "adjustedPrices": [
            97.058823529412,
            99,
            99,
            101,
            98,
            100
          ],
          "cumulativeFactors": [
            0.970588235294,
            0.970588235294,
            1,
            1,
            1,
            1
          ],
          "eventAdjustments": [
            {
              "exDate": "2026-01-06",
              "exIndex": 2,
              "eventIds": [
                "SYNTH-DIV-A"
              ],
              "selectedRevisions": [
                2
              ],
              "sourceIds": [
                "SYNTHETIC-ACTION-FEED"
              ],
              "priorClose": 102,
              "exDateClose": 99,
              "grossDividendPriceCurrency": 3,
              "effectiveDividend": 3,
              "backwardFactor": 0.970588235294,
              "factorAppliesTo": "indices < 2"
            }
          ],
          "returnLinks": [
            {
              "date": "2026-01-05",
              "priceReturn": 0.02,
              "totalReturn": 0.02,
              "effectiveDividend": 0
            },
            {
              "date": "2026-01-06",
              "priceReturn": -0.029411764706,
              "totalReturn": 0,
              "effectiveDividend": 3
            },
            {
              "date": "2026-01-07",
              "priceReturn": 0.020202020202,
              "totalReturn": 0.020202020202,
              "effectiveDividend": 0
            }
          ],
          "excludedEvents": [
            {
              "eventId": "SYNTH-CANCELLED-C",
              "selectedRevision": 2,
              "reason": "cancelled"
            },
            {
              "eventId": "SYNTH-SPECIAL-B",
              "selectedRevision": 1,
              "reason": "special_excluded_by_policy"
            }
          ],
          "rounding": {
            "internal": "unrounded IEEE-754 binary64",
            "serializedDecimalPlaces": 12,
            "factorCompounding": "multiply unrounded factors, round only serialized output"
          }
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: methodology, returnVariant, priceCurrency, asOf, anchor, adjustedPrices, cumulativeFactors, eventAdjustments, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a03/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a03/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Revision-aware total-return calculation",
            "source": "flowchart LR\n    A[\"Raw closes and event revisions\"] --> B[\"Validate order, prices, timestamps, and currencies\"]\n    B --> C[\"Select latest revision available by as-of\"]\n    C --> D{\"Confirmed and eligible?\"}\n    D -->|No| E[\"Exclude with reason\"]\n    D -->|Yes| F[\"Resolve ex-date, class, FX, and withholding\"]\n    F --> G{\"Cash below prior close?\"}\n    G -->|No| H[\"Reject undefined case\"]\n    G -->|Yes| I[\"Calculate return link and ex-date-close factor\"]\n    I --> J[\"Compound unrounded factors backward\"]\n    J --> K[\"Emit anchor, links, sources, revisions, and rounding\"]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Point-in-time event revision lifecycle",
            "source": "stateDiagram-v2\n    [*] --> Unavailable\n    Unavailable --> Available: publication reaches as-of\n    Available --> Selected: highest available revision\n    Selected --> Eligible: confirmed and policy included\n    Selected --> Excluded: cancelled or policy excluded\n    Eligible --> Applied: ex-date and inputs resolved\n    Applied --> Audited\n    Excluded --> Audited\n    Available --> Available: later revision retained"
          }
        ]
      },
      "references": [
        {
          "key": "R1 - S&P DJI Index Mathematics Methodology",
          "title": "R1 - S&P DJI Index Mathematics Methodology",
          "author": null,
          "url": null
        },
        {
          "key": "R2 - FR Global Equity Corporate Action Methodology",
          "title": "R2 - FR Global Equity Corporate Action Methodology",
          "author": null,
          "url": null
        },
        {
          "key": "R3 - Apple July 30, 2020 Form 8-K filing detail",
          "title": "R3 - Apple July 30, 2020 Form 8-K filing detail",
          "author": null,
          "url": null
        },
        {
          "key": "R4 - Apple Reports Third Quarter Results, Exhibit 99.1",
          "title": "R4 - Apple Reports Third Quarter Results, Exhibit 99.1",
          "author": null,
          "url": null
        },
        {
          "key": "R5 - Apple Dividend History",
          "title": "R5 - Apple Dividend History",
          "author": null,
          "url": null
        },
        {
          "key": "R6 - RFC 3339 and RFC 9557",
          "title": "R6 - RFC 3339 and RFC 9557",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/adjustment-factors/cash-dividend-total-return-adjustment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/adjustment-factors/cash-dividend-total-return-adjustment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F01-A04",
      "name": "CRSP Cumulative Price Adjustment",
      "headline": "Respect the Vendor Basis, Sign, and Gaps",
      "slug": "crsp-cumulative-price-adjustment",
      "path": "corporate-actions-and-security-master-data/adjustment-factors/crsp-cumulative-price-adjustment",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F01",
        "family": "Adjustment Factors",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/adjustment-factors/crsp-cumulative-price-adjustment",
        "entry": "calculate",
        "params": [
          "input"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(input)"
      },
      "api": {
        "summary": "The CRSP cumulative adjustment-factor convention, which is what academic finance means by an adjusted price. Reproducing published research requires this convention specifically, not a plausible equivalent.",
        "params": [
          {
            "name": "input",
            "type": "{ crspConvention: string; crspSourceVersion: string; packageSecurityKey: string; crspBaseDate: string; crspGapPolicy: string; roundingDecimals: number; crspFactorEvents: FactorEvent[]; records: Record[] }",
            "required": true,
            "description": "`crspConvention` and `crspSourceVersion` pin which vintage of the convention is being applied — CRSP has revised it, and results differ. `crspGapPolicy` decides what happens across missing observations, and `roundingDecimals` fixes the rounding so the same input reproduces bit-for-bit.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ crspConvention, crspBaseDate, crspPriceFormula, crspFactorEvents, crspFactorChangeDates, records, … }",
          "description": "Adjusted records together with the exact formula and factor-change dates applied — the provenance a replication needs in order to be checkable."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the convention or source version is unrecognised",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n + e)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F01-A04.json",
        "call": "calculate({\"crspConvention\":\"CRSPAccess-ts_print-cumfacpr-archived\",\"crspSourceVersion\":\"Archived CRSP Stock and Index Data Description Guide convention; synthetic extract v1\",\"packageSecurityKey\":\"SYNTHETIC-SECURITY-001\",\"crspBaseDate\":\"2024-06-10\",\"crspGapPolicy\":\"stop-at-unknown-exchange\",\"roundingDecimals\":6,\"crspFactorEvents\":[{\"crspExdt\":\"2024-06-10\",\"crspFacpr\":1,\"syntheticLabel\":\"Synthetic 2-for-1 split-like CRSP event\"}],\"records\":[{\"date\":\"2024-06-06\",\"crspPrc\":120,\"crspCumfacpr\":0.5,\"crspPriceKind\":\"trade\",\"coverageStatus\":\"observed\"},{\"date\":\"2024-06-07\",\"crspPrc\":-123,\"crspCumfacpr\":0.5,\"crspPriceKind\":\"bid_ask_average\",\"coverageStatus\":\"observed\"},{\"date\":\"2024-06-10\",\"crspPrc\":60,\"crspCumfacpr\":1,\"crspPriceKind\":\"trade\",\"coverageStatus\":\"observed\"}]})",
        "args": [
          {
            "value": {
              "crspConvention": "CRSPAccess-ts_print-cumfacpr-archived",
              "crspSourceVersion": "Archived CRSP Stock and Index Data Description Guide convention; synthetic extract v1",
              "packageSecurityKey": "SYNTHETIC-SECURITY-001",
              "crspBaseDate": "2024-06-10",
              "crspGapPolicy": "stop-at-unknown-exchange",
              "roundingDecimals": 6,
              "crspFactorEvents": [
                {
                  "crspExdt": "2024-06-10",
                  "crspFacpr": 1,
                  "syntheticLabel": "Synthetic 2-for-1 split-like CRSP event"
                }
              ],
              "records": [
                {
                  "date": "2024-06-06",
                  "crspPrc": 120,
                  "crspCumfacpr": 0.5,
                  "crspPriceKind": "trade",
                  "coverageStatus": "observed"
                },
                {
                  "date": "2024-06-07",
                  "crspPrc": -123,
                  "crspCumfacpr": 0.5,
                  "crspPriceKind": "bid_ask_average",
                  "coverageStatus": "observed"
                },
                {
                  "date": "2024-06-10",
                  "crspPrc": 60,
                  "crspCumfacpr": 1,
                  "crspPriceKind": "trade",
                  "coverageStatus": "observed"
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "crspConvention": "CRSPAccess-ts_print-cumfacpr-archived",
          "crspSourceVersion": "Archived CRSP Stock and Index Data Description Guide convention; synthetic extract v1",
          "packageSecurityKey": "SYNTHETIC-SECURITY-001",
          "crspBaseDate": "2024-06-10",
          "crspGapPolicy": "stop-at-unknown-exchange",
          "crspPriceFormula": "CRSP adjusted price = CRSP PRC * CRSP CUMFACPR",
          "crspFactorEvents": [
            {
              "crspExdt": "2024-06-10",
              "crspFacpr": 1,
              "syntheticLabel": "Synthetic 2-for-1 split-like CRSP event"
            }
          ],
          "crspFactorChangeDates": [
            "2024-06-10"
          ],
          "roundingDecimals": 6,
          "records": [
            {
              "date": "2024-06-06",
              "crspPrc": 120,
              "crspCumfacpr": 0.5,
              "crspAdjustedPrice": 60,
              "crspAdjustedMagnitude": 60,
              "crspRecoveredPrc": 120,
              "crspPriceKind": "trade",
              "coverageStatus": "observed",
              "status": "CRSP_ADJUSTED_TRADE"
            },
            {
              "date": "2024-06-07",
              "crspPrc": -123,
              "crspCumfacpr": 0.5,
              "crspAdjustedPrice": -61.5,
              "crspAdjustedMagnitude": 61.5,
              "crspRecoveredPrc": -123,
              "crspPriceKind": "bid_ask_average",
              "coverageStatus": "observed",
              "status": "CRSP_ADJUSTED_BID_ASK_AVERAGE"
            },
            {
              "date": "2024-06-10",
              "crspPrc": 60,
              "crspCumfacpr": 1,
              "crspAdjustedPrice": 60,
              "crspAdjustedMagnitude": 60,
              "crspRecoveredPrc": 60,
              "crspPriceKind": "trade",
              "coverageStatus": "observed",
              "status": "CRSP_ADJUSTED_TRADE"
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: crspConvention, crspSourceVersion, packageSecurityKey, crspBaseDate, crspGapPolicy, crspPriceFormula, crspFactorEvents, crspFactorChangeDates, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a04/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a04/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Archived CRSPAccess cumulative-price calculation flow",
            "source": "flowchart LR\n    A[\"Archived CRSPAccess row\"] --> B{\"CRSP coverage state\"}\n    B -->|Observed| C{\"CRSP price kind\"}\n    B -->|Unknown-exchange gap| G[\"CRSP factor gap: missing\"]\n    B -->|Post-delisting unpriced| D[\"CRSP delisting state: missing\"]\n    C -->|Trade or bid/ask average| E[\"CRSP PRC × CRSP CUMFACPR\"]\n    C -->|Zero missing sentinel| M[\"CRSP price missing\"]\n    E --> F[\"Signed CRSP result + magnitude + reverse check\"]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "CRSP evidence and result lifecycle",
            "source": "stateDiagram-v2\n    [*] --> VersionScoped\n    VersionScoped --> BaseAnchored: CRSP base row has CUMFACPR 1.0\n    BaseAnchored --> Calculable: observed CRSP price and positive factor\n    BaseAnchored --> Missing: zero price, factor gap, or unpriced delisting\n    Calculable --> Derived: CRSP PRC multiplied by CRSP CUMFACPR\n    Derived --> Audited: sign, magnitude, source, and reverse check retained\n    Missing --> Audited: reason retained without imputation"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "CRSP Stock and Index Data Description Guide, CRSPAccess",
          "author": null,
          "url": null
        },
        {
          "key": "R2",
          "title": "CRSP Programmer's Guide",
          "author": null,
          "url": null
        },
        {
          "key": "R3",
          "title": "Important Notice: CRSP US Stock & Indexes Databases Flat File Format 2.0 (CIZ)",
          "author": null,
          "url": null
        },
        {
          "key": "R4",
          "title": "CRSP Policies & Statements",
          "author": null,
          "url": null
        },
        {
          "key": "Historical-example evidence decision",
          "title": "Historical-example evidence decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/adjustment-factors/crsp-cumulative-price-adjustment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/adjustment-factors/crsp-cumulative-price-adjustment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F01-A05",
      "name": "CRSP Cumulative Share/Volume Adjustment",
      "headline": null,
      "slug": "crsp-cumulative-share-volume-adjustment",
      "path": "corporate-actions-and-security-master-data/adjustment-factors/crsp-cumulative-share-volume-adjustment",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F01",
        "family": "Adjustment Factors",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/adjustment-factors/crsp-cumulative-share-volume-adjustment",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "The volume counterpart of the CRSP price adjustment. Volume moves the opposite way to price across a split, and adjusting one without the other silently corrupts every turnover and liquidity measure downstream.",
        "params": [
          {
            "name": "data",
            "type": "{ schemaVersion: string; sourceRelease: string; crspBasisDate: string; extractCoverage: object; records: Record[] }",
            "required": true,
            "description": "`crspBasisDate` sets the basis the adjusted volumes are expressed on. `extractCoverage` states the window the extract actually spans, so a partial extract cannot be mistaken for a complete history.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ schemaVersion, sourceRelease, crspBasisDate, extractCoverage, roundingDigits, rows }",
          "description": "Adjusted volume rows with the provenance and rounding that produced them."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the extract coverage does not span the requested records",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F01-A05.json",
        "call": "calculate({\"schemaVersion\":\"CRSP_US_STOCK_CIZ_2_0\",\"sourceRelease\":\"synthetic-ciz-2.0-fixture-v1\",\"crspBasisDate\":\"2024-09-05\",\"extractCoverage\":\"full_history\",\"records\":[{\"packageSecurityKey\":\"SYNTHETIC-CRSP-CIZ-001\",\"date\":\"2024-08-28\",\"frequency\":\"daily\",\"crspFactorField\":\"DlyCumFacShr\",\"crspCumulativeShareFactor\":4,\"crspFactorStatus\":\"observed\",\"rawSharesOutstandingThousands\":250,\"rawVolumeShares\":100},{\"packageSecurityKey\":\"SYNTHETIC-CRSP-CIZ-001\",\"date\":\"2024-08-29\",\"frequency\":\"daily\",\"crspFactorField\":\"DlyCumFacShr\",\"crspCumulativeShareFactor\":4,\"crspFactorStatus\":\"observed\",\"rawSharesOutstandingThousands\":250,\"rawVolumeShares\":125},{\"packageSecurityKey\":\"SYNTHETIC-CRSP-CIZ-001\",\"date\":\"2024-08-30\",\"frequency\":\"daily\",\"crspFactorField\":\"DlyCumFacShr\",\"crspCumulativeShareFactor\":1,\"crspFactorStatus\":\"observed\",\"rawSharesOutstandingThousands\":1000,\"rawVolumeShares\":460}]})",
        "args": [
          {
            "value": {
              "schemaVersion": "CRSP_US_STOCK_CIZ_2_0",
              "sourceRelease": "synthetic-ciz-2.0-fixture-v1",
              "crspBasisDate": "2024-09-05",
              "extractCoverage": "full_history",
              "records": [
                {
                  "packageSecurityKey": "SYNTHETIC-CRSP-CIZ-001",
                  "date": "2024-08-28",
                  "frequency": "daily",
                  "crspFactorField": "DlyCumFacShr",
                  "crspCumulativeShareFactor": 4,
                  "crspFactorStatus": "observed",
                  "rawSharesOutstandingThousands": 250,
                  "rawVolumeShares": 100
                },
                {
                  "packageSecurityKey": "SYNTHETIC-CRSP-CIZ-001",
                  "date": "2024-08-29",
                  "frequency": "daily",
                  "crspFactorField": "DlyCumFacShr",
                  "crspCumulativeShareFactor": 4,
                  "crspFactorStatus": "observed",
                  "rawSharesOutstandingThousands": 250,
                  "rawVolumeShares": 125
                },
                {
                  "packageSecurityKey": "SYNTHETIC-CRSP-CIZ-001",
                  "date": "2024-08-30",
                  "frequency": "daily",
                  "crspFactorField": "DlyCumFacShr",
                  "crspCumulativeShareFactor": 1,
                  "crspFactorStatus": "observed",
                  "rawSharesOutstandingThousands": 1000,
                  "rawVolumeShares": 460
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "rows": [
            {
              "crspAdjustedSharesOutstandingThousands": 1000,
              "crspAdjustedVolumeShares": 400
            },
            {
              "crspAdjustedSharesOutstandingThousands": 1000,
              "crspAdjustedVolumeShares": 500
            },
            {
              "crspAdjustedSharesOutstandingThousands": 1000,
              "crspAdjustedVolumeShares": 460
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 1 field: rows"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a05/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a05/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f01-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "CRSP CIZ 2.0 calculation flow",
            "source": "flowchart LR\n    A[\"CRSP CIZ 2.0 row and release\"] --> B{\"DlyCumFacShr or MthCumFacShr?\"}\n    B -->|No| X[\"Reject field substitution\"]\n    B -->|Yes| C{\"CRSP factor and raw quantity present?\"}\n    C -->|No| M[\"Return explicit missing status\"]\n    C -->|Yes| D{\"Monthly volume with mixed basis?\"}\n    D -->|Yes| R[\"Require licensed daily reconstruction\"]\n    D -->|No| E[\"Multiply by CRSP share factor\"]\n    E --> F[\"Round once at 12 decimals\"]\n    F --> G[\"Retain CRSP release, basis, and status\"]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "CRSP evidence-state lifecycle",
            "source": "stateDiagram-v2\n    [*] --> ValidateCRSPField\n    ValidateCRSPField --> Rejected: price factor or wrong frequency\n    ValidateCRSPField --> Missing: raw value or CRSP factor absent\n    ValidateCRSPField --> CheckFrequency: valid share factor\n    CheckFrequency --> DailyComputed: daily quantity\n    CheckFrequency --> MonthlyComputed: clean monthly evidence\n    CheckFrequency --> DailyReconstructionRequired: mixed or unknown month\n    CheckFrequency --> GapQualified: CRSP factor continued across gap\n    DailyComputed --> Audited\n    MonthlyComputed --> Audited\n    GapQualified --> Audited\n    Missing --> Audited\n    Rejected --> Audited\n    DailyReconstructionRequired --> Audited"
          }
        ]
      },
      "references": [
        {
          "key": "R1 - CRSP US Stock & Indexes Database Guide, Flat File Format 2.0 (CIZ)",
          "title": "R1 - CRSP US Stock & Indexes Database Guide, Flat File Format 2.0 (CIZ)",
          "author": null,
          "url": null
        },
        {
          "key": "R2 - Important Notice: CRSP US Stock & Indexes Flat File Format 2.0 (CIZ)",
          "title": "R2 - Important Notice: CRSP US Stock & Indexes Flat File Format 2.0 (CIZ)",
          "author": null,
          "url": null
        },
        {
          "key": "R3 - June 2025 Monthly Update: CRSP US Stock & Index Release Notes",
          "title": "R3 - June 2025 Monthly Update: CRSP US Stock & Index Release Notes",
          "author": null,
          "url": null
        },
        {
          "key": "R4 - May 2026 Monthly Update: CRSP US Stock & Index Databases Release Notes",
          "title": "R4 - May 2026 Monthly Update: CRSP US Stock & Index Databases Release Notes",
          "author": null,
          "url": null
        },
        {
          "key": "R5 - CRSP US Stock & Indexes Database Data Descriptions Guide",
          "title": "R5 - CRSP US Stock & Indexes Database Data Descriptions Guide",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/adjustment-factors/crsp-cumulative-share-volume-adjustment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/adjustment-factors/crsp-cumulative-share-volume-adjustment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F02-A01",
      "name": "Rights-Issue TERP Adjustment",
      "headline": null,
      "slug": "rights-issue-terp-adjustment",
      "path": "corporate-actions-and-security-master-data/complex-distributions/rights-issue-terp-adjustment",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F02",
        "family": "Complex Distributions",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/complex-distributions/rights-issue-terp-adjustment",
        "entry": "calculate",
        "params": [
          "input"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(input)"
      },
      "api": {
        "summary": "Computes the theoretical ex-rights price. A rights issue is not a dividend and not a split: shareholders receive the right to buy new shares below market, so value transfers rather than disappears, and TERP is the price that makes the series continuous.",
        "params": [
          {
            "name": "input",
            "type": "{ asOf: string; revisions: EventRevision[] }",
            "required": true,
            "description": "Each revision carries the cum price, the subscription price, and the ratio of new to existing shares. Point-in-time by construction: `asOf` is the knowledge time, and only revisions available at or before it are eligible. Passing the event date instead of the knowledge date is what lets a backtest use information it could not have had.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ terp, referencePrice, subscriptionCashQuote, valuePerOldShare, adjustmentFactor, … }",
          "description": "TERP with every input that produced it, plus the value per old share — the quantity that shows the transfer is a transfer and not a loss."
        },
        "warmup": null,
        "errors": [
          {
            "when": "no revision is available at asOf",
            "behaviour": "returned as a state on the result rather than thrown"
          },
          {
            "when": "the subscription ratio is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(revisions)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F02-A01.json",
        "call": "calculate({\"asOf\":\"2024-05-24T00:00:00Z\",\"revisions\":[{\"eventId\":\"NG-2024-RIGHTS\",\"revisionId\":\"NG-PROSPECTUS-2024-05-23\",\"revisionSequence\":1,\"availableAt\":\"2024-05-23T23:59:59Z\",\"status\":\"confirmed\",\"recordAt\":\"2024-05-20T18:00:00+01:00\",\"exAt\":\"2024-05-24T08:00:00+01:00\",\"rightsTradingStartAt\":\"2024-05-24T08:00:00+01:00\",\"paymentDeadlineAt\":\"2024-06-10T11:00:00+01:00\",\"newSharesTradeAt\":\"2024-06-12T08:00:00+01:00\",\"terms\":{\"oldShares\":24,\"newShares\":7,\"rawCumRightsPrice\":1127.5,\"cashDisadvantage\":39.12,\"quoteCurrency\":\"GBp\",\"subscriptionPrice\":645,\"subscriptionCurrency\":\"GBp\",\"fxQuotePerSubscription\":1,\"feesPerNewShareQuote\":0,\"taxesPerNewShareQuote\":0,\"holdingOldShares\":100,\"outOfMoneyPolicy\":\"reject\",\"priceSourceId\":\"NG-PROSPECTUS-P52-LSE-DOL-QUOTE\",\"priceDate\":\"2024-05-22\"}}]})",
        "args": [
          {
            "value": {
              "asOf": "2024-05-24T00:00:00Z",
              "revisions": [
                {
                  "eventId": "NG-2024-RIGHTS",
                  "revisionId": "NG-PROSPECTUS-2024-05-23",
                  "revisionSequence": 1,
                  "availableAt": "2024-05-23T23:59:59Z",
                  "status": "confirmed",
                  "recordAt": "2024-05-20T18:00:00+01:00",
                  "exAt": "2024-05-24T08:00:00+01:00",
                  "rightsTradingStartAt": "2024-05-24T08:00:00+01:00",
                  "paymentDeadlineAt": "2024-06-10T11:00:00+01:00",
                  "newSharesTradeAt": "2024-06-12T08:00:00+01:00",
                  "terms": {
                    "oldShares": 24,
                    "newShares": 7,
                    "rawCumRightsPrice": 1127.5,
                    "cashDisadvantage": 39.12,
                    "quoteCurrency": "GBp",
                    "subscriptionPrice": 645,
                    "subscriptionCurrency": "GBp",
                    "fxQuotePerSubscription": 1,
                    "feesPerNewShareQuote": 0,
                    "taxesPerNewShareQuote": 0,
                    "holdingOldShares": 100,
                    "outOfMoneyPolicy": "reject",
                    "priceSourceId": "NG-PROSPECTUS-P52-LSE-DOL-QUOTE",
                    "priceDate": "2024-05-22"
                  }
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "eventId": "NG-2024-RIGHTS",
          "revisionId": "NG-PROSPECTUS-2024-05-23",
          "availableAt": "2024-05-23T23:59:59Z",
          "quoteCurrency": "GBp",
          "referencePrice": 1088.38,
          "subscriptionCashQuote": 645,
          "terp": 988.261935,
          "valuePerOldShare": 100.118065,
          "valuePerNewShareRight": 343.261935,
          "adjustmentFactor": 0.908012,
          "issueDiscountToTerp": 0.347339,
          "inTheMoney": true,
          "applied": true,
          "entitlement": {
            "exactNewShares": 29.166667,
            "wholeNewShares": 29,
            "fractionalNewShare": 0.166667
          }
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 15
        },
        "outputShape": "object with 15 fields: eventId, revisionId, availableAt, quoteCurrency, referencePrice, subscriptionCashQuote, terp, valuePerOldShare, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a01/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a01/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "TERP evidence and calculation flow",
            "source": "flowchart LR\n    A[\"Event revisions\"] --> B[\"Select latest available at asOf\"]\n    B --> C{\"Confirmed and timed correctly?\"}\n    C -->|No| X[\"Reject with diagnostic\"]\n    C -->|Yes| D[\"Normalize price, currency, FX, fees, taxes\"]\n    D --> E{\"Subscription cash below reference?\"}\n    E -->|Yes| F[\"Derive TERP and two rights values\"]\n    E -->|No| G[\"Reject or explicit no adjustment\"]\n    F --> H[\"Emit revision and units\"]\n    G --> H\n    H --> I[\"Keep observed ex-rights trade separate\"]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Rights-issue operational lifecycle",
            "source": "stateDiagram-v2\n    [*] --> RecordSnapshot: 20 May 18:00 London\n    RecordSnapshot --> TermsAvailable: prospectus published 23 May\n    TermsAvailable --> ExRights: 24 May 08:00\n    ExRights --> NilPaid: nil-paid dealings begin\n    NilPaid --> Accepted: pay and accept by 10 June 11:00\n    NilPaid --> RenouncedOrLapsed: transfer or do not accept\n    Accepted --> FullyPaidShares: dealings begin 12 June 08:00\n    RenouncedOrLapsed --> AllocatedByTerms: proceeds depend on offer rules"
          }
        ]
      },
      "references": [
        {
          "key": "R1 - National Grid plc Rights Issue Prospectus",
          "title": "R1 - National Grid plc Rights Issue Prospectus",
          "author": null,
          "url": null
        },
        {
          "key": "R2 - National Grid 7-for-24 Rights Issue announcement",
          "title": "R2 - National Grid 7-for-24 Rights Issue announcement",
          "author": null,
          "url": null
        },
        {
          "key": "R3 - National Grid Rights Issue and Prospectus hub",
          "title": "R3 - National Grid Rights Issue and Prospectus hub",
          "author": null,
          "url": null
        },
        {
          "key": "R4 - S&P DJI Equity Indices Policies & Practices",
          "title": "R4 - S&P DJI Equity Indices Policies & Practices",
          "author": null,
          "url": null
        },
        {
          "key": "R5 - FTSE Russell Corporate Actions and Events Guide",
          "title": "R5 - FTSE Russell Corporate Actions and Events Guide",
          "author": null,
          "url": null
        },
        {
          "key": "R6 - RFC 3339: Date and Time on the Internet",
          "title": "R6 - RFC 3339: Date and Time on the Internet",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/complex-distributions/rights-issue-terp-adjustment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/complex-distributions/rights-issue-terp-adjustment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F02-A02",
      "name": "Spin-Off Price Adjustment",
      "headline": "Separate Parent Price from Distributed Value",
      "slug": "spin-off-price-adjustment",
      "path": "corporate-actions-and-security-master-data/complex-distributions/spin-off-price-adjustment",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F02",
        "family": "Complex Distributions",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/complex-distributions/spin-off-price-adjustment",
        "entry": "calculate",
        "params": [
          "input"
        ],
        "exports": [
          "calculate",
          "roundHalfUp6"
        ],
        "archetype": "record-transform",
        "signature": "calculate(input)"
      },
      "api": {
        "summary": "Splits a parent's price history at a spin-off. One company becomes two, so the parent's own history must be restated by the value that left with the child — otherwise the parent shows a fall it never suffered.",
        "params": [
          {
            "name": "input",
            "type": "{ asOf: string; revisions: EventRevision[] }",
            "required": true,
            "description": "Revisions carry the parent cum price and the value distributed per parent share, usually derived from the child's when-issued price. Point-in-time by construction: `asOf` is the knowledge time, and only revisions available at or before it are eligible. Passing the event date instead of the knowledge date is what lets a backtest use information it could not have had.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, parentCumPrice, distributedValuePerParent, theoreticalParentExReference, adjustmentFactor, … }",
          "description": "The theoretical ex-distribution reference for the parent and the factor to apply to its history, with a `status` that distinguishes a completed calculation from one awaiting a reliable child valuation."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the distributed value cannot be established at asOf",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(revisions)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F02-A02.json",
        "call": "calculate({\"asOf\":\"2026-06-02T20:00:00Z\",\"revisions\":[{\"eventId\":\"SYNTH-SPIN-2026\",\"revisionId\":\"SYNTH-SPIN-2026-R1\",\"revisionSequence\":1,\"availableAt\":\"2026-05-21T12:00:00Z\",\"status\":\"confirmed\",\"quoteCurrency\":\"USD\",\"recordAt\":\"2026-05-20T20:00:00Z\",\"whenIssuedStartAt\":\"2026-05-27T13:30:00Z\",\"distributionAt\":\"2026-06-01T12:00:00Z\",\"parentExAt\":\"2026-06-01T13:30:00Z\",\"childRegularWayAt\":\"2026-06-01T13:30:00Z\",\"unavailableChildPricePolicy\":\"pending\",\"parentCumObservation\":{\"price\":120,\"currency\":\"USD\",\"priceType\":\"regular_way_cum_distribution\",\"observedAt\":\"2026-05-29T20:00:00Z\",\"availableAt\":\"2026-05-29T20:00:05Z\",\"sourceId\":\"SYNTH-PARENT-CLOSE\"},\"parentExObservation\":{\"price\":108,\"currency\":\"USD\",\"priceType\":\"regular_way_ex_distribution\",\"observedAt\":\"2026-06-01T20:00:00Z\",\"availableAt\":\"2026-06-01T20:00:05Z\",\"sourceId\":\"SYNTH-PARENT-EX-CLOSE\"}}]})",
        "args": [
          {
            "value": {
              "asOf": "2026-06-02T20:00:00Z",
              "revisions": [
                {
                  "eventId": "SYNTH-SPIN-2026",
                  "revisionId": "SYNTH-SPIN-2026-R1",
                  "revisionSequence": 1,
                  "availableAt": "2026-05-21T12:00:00Z",
                  "status": "confirmed",
                  "quoteCurrency": "USD",
                  "recordAt": "2026-05-20T20:00:00Z",
                  "whenIssuedStartAt": "2026-05-27T13:30:00Z",
                  "distributionAt": "2026-06-01T12:00:00Z",
                  "parentExAt": "2026-06-01T13:30:00Z",
                  "childRegularWayAt": "2026-06-01T13:30:00Z",
                  "unavailableChildPricePolicy": "pending",
                  "parentCumObservation": {
                    "price": 120,
                    "currency": "USD",
                    "priceType": "regular_way_cum_distribution",
                    "observedAt": "2026-05-29T20:00:00Z",
                    "availableAt": "2026-05-29T20:00:05Z",
                    "sourceId": "SYNTH-PARENT-CLOSE"
                  },
                  "parentExObservation": {
                    "price": 108,
                    "currency": "USD",
                    "priceType": "regular_way_ex_distribution",
                    "observedAt": "2026-06-01T20:00:00Z",
                    "availableAt": "2026-06-01T20:00:05Z",
                    "sourceId": "SYNTH-PARENT-EX-CLOSE"
                  }
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "eventId": "SYNTH-SPIN-2026",
          "revisionId": "SYNTH-SPIN-2026-R1",
          "availableAt": "2026-05-21T12:00:00Z",
          "status": "ready",
          "quoteCurrency": "USD",
          "parentCumPrice": 120,
          "distributedValuePerParent": 13.5,
          "theoreticalParentExReference": 106.5,
          "backwardAdjustmentFactor": 0.8875,
          "factorDirection": "multiply_pre_event_parent_prices",
          "factorAnchor": "post_event_parent_only_basis",
          "rounding": "shortest_decimal_half_up_6_on_output_only",
          "components": [
            {
              "securityId": "SYNTH-CHILD-A",
              "entitlementRatio": 0.25,
              "priceType": "when_issued",
              "priceQuote": 44,
              "valuePerParent": 11,
              "holderEntitlement": {
                "exactChildShares": 5.75,
                "wholeChildShares": 5,
                "fractionalChildShare": 0.75,
                "fractionalReferenceValue": 33,
                "actualCashInLieuKnown": false
              }
            },
            {
              "securityId": "SYNTH-CHILD-B",
              "entitlementRatio": 0.1,
              "priceType": "regular_way",
              "priceQuote": 25,
              "valuePerParent": 2.5,
              "holderEntitlement": {
                "exactChildShares": 2.3,
                "wholeChildShares": 2,
                "fractionalChildShare": 0.3,
                "fractionalReferenceValue": 7.5,
                "actualCashInLieuKnown": false
              }
            }
          ],
          "economicValueAllocation": {
            "parentWeight": 0.8875,
            "children": [
              {
                "securityId": "SYNTH-CHILD-A",
                "weight": 0.091667
              },
              {
                "securityId": "SYNTH-CHILD-B",
                "weight": 0.020833
              }
            ]
          }
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 16
        },
        "outputShape": "object with 16 fields: eventId, revisionId, availableAt, status, quoteCurrency, parentCumPrice, distributedValuePerParent, theoreticalParentExReference, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a02/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a02/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Evidence-to-output calculation flow",
            "source": "flowchart LR\n    A[\"Select revision at asOf\"] --> B[\"Validate parent cum observation\"]\n    B --> C[\"Value each child and FX\"]\n    C --> D{\"All references available?\"}\n    D -->|No| E[\"Pending or reject\"]\n    D -->|Yes| F[\"Sum distributed value\"]\n    F --> G[\"Parent-only factor\"]\n    F --> H{\"Parent ex observation?\"}\n    H -->|Yes| I[\"Gross and net combined return\"]\n    H -->|No| J[\"Return bridge unavailable\"]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Spin-off event and market-line lifecycle",
            "source": "stateDiagram-v2\n    [*] --> Announced\n    Announced --> RecordSet: record boundary\n    RecordSet --> WhenIssued: conditional child trading\n    WhenIssued --> Distributed: legal distribution\n    Distributed --> ParentEx: parent without entitlement\n    ParentEx --> ChildRegularWay: issued child trades normally\n    WhenIssued --> PendingValue: price unavailable\n    PendingValue --> ChildRegularWay: causal observation arrives\n    Announced --> Cancelled: confirmed cancellation"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": null,
          "url": null
        },
        {
          "key": "R2",
          "title": "FTSE Russell Corporate Actions and Events Guide",
          "author": null,
          "url": null
        },
        {
          "key": "R3",
          "title": "GE Board approves GE Vernova spin-off",
          "author": null,
          "url": null
        },
        {
          "key": "R4",
          "title": "GE Vernova Information Statement, SEC exhibit 99.1",
          "author": null,
          "url": null
        },
        {
          "key": "R5",
          "title": "GE Form 8-K reporting completion",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/complex-distributions/spin-off-price-adjustment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/complex-distributions/spin-off-price-adjustment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F02-A03",
      "name": "Stock-Dividend Adjustment",
      "headline": "Convert Price and Quantity Bases Without Inventing Value",
      "slug": "stock-dividend-adjustment",
      "path": "corporate-actions-and-security-master-data/complex-distributions/stock-dividend-adjustment",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F02",
        "family": "Complex Distributions",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/complex-distributions/stock-dividend-adjustment",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate",
          "settleEntitlement",
          "roundOutput"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Applies a stock dividend, where shareholders receive additional shares instead of cash. Economically close to a split, but reported differently and often with a different volume convention — which is the part that gets missed.",
        "params": [
          {
            "name": "data",
            "type": "{ method: string; securityId: string; asOf: string; anchorAt: string; volumePolicy: string; events: Event[]; observations: Observation[] }",
            "required": true,
            "description": "`volumePolicy` decides whether traded volume is restated alongside price; the two conventions are both in use and disagree. `anchorAt` fixes the basis date. Point-in-time by construction: `asOf` is the knowledge time, and only revisions available at or before it are eligible. Passing the event date instead of the knowledge date is what lets a backtest use information it could not have had.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ method, appliedEvents, unavailableEventIds, cancelledEventIds, observations, … }",
          "description": "Adjusted observations plus which events were applied, which were not yet knowable, and which were cancelled — a cancelled event that silently still applies is a class of bug this makes visible."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the volume policy or method is unrecognised",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n + e)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F02-A03.json",
        "call": "calculate({\"method\":\"backward_post_event_same_class\",\"securityId\":\"SYNTH-CLASS-A\",\"asOf\":\"2026-02-04T12:00:00Z\",\"anchorAt\":\"2026-02-03T21:00:00Z\",\"volumePolicy\":\"adjust_to_anchor_basis\",\"events\":[{\"eventId\":\"SD-001\",\"subjectSecurityId\":\"SYNTH-CLASS-A\",\"distributedSecurityId\":\"SYNTH-CLASS-A\",\"exAt\":\"2026-01-15T14:30:00Z\",\"recordDate\":\"2026-01-15\",\"payableDate\":\"2026-01-20\",\"revisions\":[{\"publishedAt\":\"2026-01-05T18:00:00Z\",\"status\":\"confirmed\",\"rateNewSharesPerOld\":0.1,\"sourceId\":\"SYNTH-NOTICE-1\"}]},{\"eventId\":\"SD-002\",\"subjectSecurityId\":\"SYNTH-CLASS-A\",\"distributedSecurityId\":\"SYNTH-CLASS-A\",\"exAt\":\"2026-02-03T14:30:00Z\",\"recordDate\":\"2026-01-30\",\"payableDate\":\"2026-02-02\",\"revisions\":[{\"publishedAt\":\"2026-01-20T18:00:00Z\",\"status\":\"confirmed\",\"rateNewSharesPerOld\":0.15,\"sourceId\":\"SYNTH-NOTICE-2-R1\"},{\"publishedAt\":\"2026-01-25T18:00:00Z\",\"status\":\"confirmed\",\"rateNewSharesPerOld\":0.2,\"sourceId\":\"SYNTH-NOTICE-2-R2\"}]}],\"observations\":[{\"at\":\"2026-01-02T21:00:00Z\",\"availableAt\":\"2026-01-02T21:00:05Z\",\"sourceId\":\"SYNTH-CLOSES-V1\",\"price\":50,\"shares\":200,\"volume\":80},{\"at\":\"2026-02-02T21:00:00Z\",\"availableAt\":\"2026-02-02T21:00:05Z\",\"sourceId\":\"SYNTH-CLOSES-V1\",\"price\":55,\"shares\":220,\"volume\":90},{\"at\":\"2026-02-03T14:30:00Z\",\"availableAt\":\"2026-02-03T14:30:05Z\",\"sourceId\":\"SYNTH-CLOSES-V1\",\"price\":46,\"shares\":264,\"volume\":100}]})",
        "args": [
          {
            "value": {
              "method": "backward_post_event_same_class",
              "securityId": "SYNTH-CLASS-A",
              "asOf": "2026-02-04T12:00:00Z",
              "anchorAt": "2026-02-03T21:00:00Z",
              "volumePolicy": "adjust_to_anchor_basis",
              "events": [
                {
                  "eventId": "SD-001",
                  "subjectSecurityId": "SYNTH-CLASS-A",
                  "distributedSecurityId": "SYNTH-CLASS-A",
                  "exAt": "2026-01-15T14:30:00Z",
                  "recordDate": "2026-01-15",
                  "payableDate": "2026-01-20",
                  "revisions": [
                    {
                      "publishedAt": "2026-01-05T18:00:00Z",
                      "status": "confirmed",
                      "rateNewSharesPerOld": 0.1,
                      "sourceId": "SYNTH-NOTICE-1"
                    }
                  ]
                },
                {
                  "eventId": "SD-002",
                  "subjectSecurityId": "SYNTH-CLASS-A",
                  "distributedSecurityId": "SYNTH-CLASS-A",
                  "exAt": "2026-02-03T14:30:00Z",
                  "recordDate": "2026-01-30",
                  "payableDate": "2026-02-02",
                  "revisions": [
                    {
                      "publishedAt": "2026-01-20T18:00:00Z",
                      "status": "confirmed",
                      "rateNewSharesPerOld": 0.15,
                      "sourceId": "SYNTH-NOTICE-2-R1"
                    },
                    {
                      "publishedAt": "2026-01-25T18:00:00Z",
                      "status": "confirmed",
                      "rateNewSharesPerOld": 0.2,
                      "sourceId": "SYNTH-NOTICE-2-R2"
                    }
                  ]
                }
              ],
              "observations": [
                {
                  "at": "2026-01-02T21:00:00Z",
                  "availableAt": "2026-01-02T21:00:05Z",
                  "sourceId": "SYNTH-CLOSES-V1",
                  "price": 50,
                  "shares": 200,
                  "volume": 80
                },
                {
                  "at": "2026-02-02T21:00:00Z",
                  "availableAt": "2026-02-02T21:00:05Z",
                  "sourceId": "SYNTH-CLOSES-V1",
                  "price": 55,
                  "shares": 220,
                  "volume": 90
                },
                {
                  "at": "2026-02-03T14:30:00Z",
                  "availableAt": "2026-02-03T14:30:05Z",
                  "sourceId": "SYNTH-CLOSES-V1",
                  "price": 46,
                  "shares": 264,
                  "volume": 100
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "method": "backward_post_event_same_class",
          "securityId": "SYNTH-CLASS-A",
          "asOf": "2026-02-04T12:00:00Z",
          "anchorAt": "2026-02-03T21:00:00Z",
          "volumePolicy": "adjust_to_anchor_basis",
          "appliedEvents": [
            {
              "eventId": "SD-001",
              "exAt": "2026-01-15T14:30:00Z",
              "revisionPublishedAt": "2026-01-05T18:00:00Z",
              "knownByExDate": true,
              "rateNewSharesPerOld": 0.1,
              "shareFactor": 1.1,
              "priceFactor": 0.909090909091,
              "sourceId": "SYNTH-NOTICE-1"
            },
            {
              "eventId": "SD-002",
              "exAt": "2026-02-03T14:30:00Z",
              "revisionPublishedAt": "2026-01-25T18:00:00Z",
              "knownByExDate": true,
              "rateNewSharesPerOld": 0.2,
              "shareFactor": 1.2,
              "priceFactor": 0.833333333333,
              "sourceId": "SYNTH-NOTICE-2-R2"
            }
          ],
          "unavailableEventIds": [],
          "cancelledEventIds": [],
          "rows": [
            {
              "at": "2026-01-02T21:00:00Z",
              "availableAt": "2026-01-02T21:00:05Z",
              "sourceId": "SYNTH-CLOSES-V1",
              "rawPrice": 50,
              "adjustedPrice": 37.878787878788,
              "rawShares": 200,
              "adjustedShares": 264,
              "rawVolume": 80,
              "adjustedVolume": 105.6,
              "cumulativeShareFactor": 1.32,
              "appliedEventIds": [
                "SD-001",
                "SD-002"
              ]
            },
            {
              "at": "2026-02-02T21:00:00Z",
              "availableAt": "2026-02-02T21:00:05Z",
              "sourceId": "SYNTH-CLOSES-V1",
              "rawPrice": 55,
              "adjustedPrice": 45.833333333333,
              "rawShares": 220,
              "adjustedShares": 264,
              "rawVolume": 90,
              "adjustedVolume": 108,
              "cumulativeShareFactor": 1.2,
              "appliedEventIds": [
                "SD-002"
              ]
            },
            {
              "at": "2026-02-03T14:30:00Z",
              "availableAt": "2026-02-03T14:30:05Z",
              "sourceId": "SYNTH-CLOSES-V1",
              "rawPrice": 46,
              "adjustedPrice": 46,
              "rawShares": 264,
              "adjustedShares": 264,
              "rawVolume": 100,
              "adjustedVolume": 100,
              "cumulativeShareFactor": 1,
              "appliedEventIds": []
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: method, securityId, asOf, anchorAt, volumePolicy, appliedEvents, unavailableEventIds, cancelledEventIds, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a03/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a03/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Revision selection and adjustment flow",
            "source": "flowchart LR\n    A[\"Raw event revisions\"] --> B[\"Keep publishedAt not later than asOf\"]\n    B --> C[\"Choose latest unique revision\"]\n    C --> D{\"Status and class valid?\"}\n    D -->|Cancelled| E[\"Report cancellation\"]\n    D -->|Wrong class| F[\"Reject method\"]\n    D -->|Confirmed same class| G{\"Observation before exAt?\"}\n    G -->|No| H[\"Keep new-basis row\"]\n    G -->|Yes| I[\"Compound factor\"]\n    I --> J[\"Divide price\"]\n    I --> K[\"Multiply shares\"]\n    I --> L[\"Adjust or preserve volume\"]\n    J --> M[\"Audited output\"]\n    K --> M\n    L --> M"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Event evidence lifecycle",
            "source": "stateDiagram-v2\n    [*] --> Unavailable\n    Unavailable --> Announced: first publication\n    Announced --> Confirmed: authoritative terms\n    Announced --> Cancelled: source cancellation\n    Confirmed --> Effective: exAt reached\n    Confirmed --> Revised: later publication\n    Revised --> Confirmed: terms replace prior revision\n    Revised --> Cancelled: later cancellation\n    Effective --> Restated: later correction selected by current asOf\n    Effective --> Historical: earlier asOf retains earlier evidence\n    Cancelled --> [*]\n    Restated --> [*]\n    Historical --> [*]"
          }
        ]
      },
      "references": [
        {
          "key": "R1 - NVIDIA 2021 stock-split announcement filed with the SEC",
          "title": "R1 - NVIDIA 2021 stock-split announcement filed with the SEC",
          "author": "NVIDIA Corporation",
          "url": null
        },
        {
          "key": "R2 - NVIDIA 2021 Stock Split FAQ",
          "title": "R2 - NVIDIA 2021 Stock Split FAQ",
          "author": "NVIDIA Corporation",
          "url": null
        },
        {
          "key": "R3 - FINRA Rule 11140",
          "title": "R3 - FINRA Rule 11140",
          "author": "Financial Industry Regulatory Authority",
          "url": null
        },
        {
          "key": "R4 - Nasdaq Daily List File Format and Specifications",
          "title": "R4 - Nasdaq Daily List File Format and Specifications",
          "author": "Nasdaq",
          "url": null
        },
        {
          "key": "R5 - FTSE Russell Corporate Actions and Events Guide for Market Capitalisation Weighted Indices",
          "title": "R5 - FTSE Russell Corporate Actions and Events Guide for Market Capitalisation Weighted Indices",
          "author": "FTSE Russell, LSEG",
          "url": null
        },
        {
          "key": "R6 - S&P DJI Index Mathematics Methodology",
          "title": "R6 - S&P DJI Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": null
        },
        {
          "key": "Evidence classification",
          "title": "Evidence classification",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/complex-distributions/stock-dividend-adjustment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/complex-distributions/stock-dividend-adjustment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F02-A04",
      "name": "Special-Dividend Adjustment",
      "headline": "Preserve Return Meaning Across the Ex-Date",
      "slug": "special-dividend-adjustment",
      "path": "corporate-actions-and-security-master-data/complex-distributions/special-dividend-adjustment",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F02",
        "family": "Complex Distributions",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/complex-distributions/special-dividend-adjustment",
        "entry": "calculate",
        "params": [
          "rawData"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(rawData)"
      },
      "api": {
        "summary": "Handles a distribution large or irregular enough that treating it as an ordinary dividend misstates the series. The hard part is not the arithmetic but the classification, and this makes that decision explicit and auditable.",
        "params": [
          {
            "name": "rawData",
            "type": "{ securityId: string; eventId: string; asOf: string; methodology: string; eventRevisions: EventRevision[]; referencePrice: object; precedingActions: object[]; fxRate?: object; taxProfile?: object; exPriceObservation?: object }",
            "required": true,
            "description": "`precedingActions` matters because adjustments compose in order — a split applied before or after this distribution gives different answers. `fxRate` and `taxProfile` cover cross-currency distributions and withholding. Point-in-time by construction: `asOf` is the knowledge time, and only revisions available at or before it are eligible. Passing the event date instead of the knowledge date is what lets a backtest use information it could not have had.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ eventState, classificationDecision, classificationReason, adjustmentApplied, grossDividendOnEventBasis, netDividendOnEventBasis, … }",
          "description": "The classification *and the reason for it*, alongside gross and net amounts on the event's own basis. The reason is the point: this is a judgement, and a judgement without its rationale cannot be reviewed."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the methodology is unrecognised",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(revisions + actions)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F02-A04.json",
        "call": "calculate({\"securityId\":\"SYNTHETIC-SECURITY-004\",\"eventId\":\"SYNTHETIC-SPECIAL-DIVIDEND-2026-01\",\"asOf\":\"2026-03-16T20:10:00Z\",\"methodology\":{\"id\":\"SYNTHETIC-NET-RETURN-POLICY\",\"version\":\"1.0\",\"sourceId\":\"SYNTHETIC-METHODOLOGY-NOTE\",\"classificationMode\":\"source-designated\",\"priceAdjustmentCashBasis\":\"net\",\"referenceAnchor\":\"previous-session-official-close\",\"outputDecimals\":8},\"eventRevisions\":[{\"revisionId\":\"R1\",\"securityId\":\"SYNTHETIC-SECURITY-004\",\"eventId\":\"SYNTHETIC-SPECIAL-DIVIDEND-2026-01\",\"status\":\"announced\",\"issuerClassification\":\"special\",\"grossAmount\":15,\"currency\":\"EUR\",\"announcedAt\":\"2026-02-02T12:00:00Z\",\"availableAt\":\"2026-02-02T12:05:00Z\",\"exAt\":\"2026-03-16T13:30:00Z\",\"paymentAt\":\"2026-03-20T12:00:00Z\",\"actionOrder\":20,\"amountBasisOrder\":0,\"sourceId\":\"SYNTHETIC-ISSUER-NOTICE-R1\"},{\"revisionId\":\"R2\",\"securityId\":\"SYNTHETIC-SECURITY-004\",\"eventId\":\"SYNTHETIC-SPECIAL-DIVIDEND-2026-01\",\"status\":\"announced\",\"issuerClassification\":\"special\",\"grossAmount\":16,\"currency\":\"EUR\",\"announcedAt\":\"2026-02-05T14:00:00Z\",\"availableAt\":\"2026-02-05T14:10:00Z\",\"exAt\":\"2026-03-16T13:30:00Z\",\"paymentAt\":\"2026-03-20T12:00:00Z\",\"actionOrder\":20,\"amountBasisOrder\":0,\"sourceId\":\"SYNTHETIC-ISSUER-NOTICE-R2\"}],\"referencePrice\":{\"value\":100,\"currency\":\"USD\",\"anchorType\":\"previous-session-official-close\",\"anchorAt\":\"2026-03-13T20:00:00Z\",\"observedAt\":\"2026-03-13T20:00:00Z\",\"availableAt\":\"2026-03-13T20:00:05Z\",\"sourceId\":\"SYNTHETIC-OFFICIAL-CLOSE\"},\"precedingActions\":[{\"actionId\":\"SYNTHETIC-2-FOR-1-SPLIT\",\"actionOrder\":10,\"priceFactor\":0.5,\"perShareAmountFactor\":0.5,\"effectiveAt\":\"2026-03-16T13:30:00Z\",\"observedAt\":\"2026-02-01T10:00:00Z\",\"availableAt\":\"2026-02-01T10:05:00Z\",\"sourceId\":\"SYNTHETIC-ACTION-SOURCE\"}],\"fxRate\":{\"baseCurrency\":\"EUR\",\"quoteCurrency\":\"USD\",\"rate\":1.1,\"observedAt\":\"2026-03-13T20:00:00Z\",\"availableAt\":\"2026-03-13T20:00:05Z\",\"sourceId\":\"SYNTHETIC-FX-CLOSE\"},\"taxProfile\":{\"withholdingRate\":0.25,\"jurisdiction\":\"SYNTHETIC-JURISDICTION\",\"investorCategory\":\"SYNTHETIC-NONRESIDENT\",\"observedAt\":\"2026-01-05T09:00:00Z\",\"availableAt\":\"2026-01-05T09:05:00Z\",\"sourceId\":\"SYNTHETIC-TAX-RULE\"},\"exPriceObservation\":{\"value\":43.75,\"currency\":\"USD\",\"observedAt\":\"2026-03-16T20:00:00Z\",\"availableAt\":\"2026-03-16T20:00:05Z\",\"sourceId\":\"SYNTHETIC-EX-CLOSE\"}})",
        "args": [
          {
            "value": {
              "securityId": "SYNTHETIC-SECURITY-004",
              "eventId": "SYNTHETIC-SPECIAL-DIVIDEND-2026-01",
              "asOf": "2026-03-16T20:10:00Z",
              "methodology": {
                "id": "SYNTHETIC-NET-RETURN-POLICY",
                "version": "1.0",
                "sourceId": "SYNTHETIC-METHODOLOGY-NOTE",
                "classificationMode": "source-designated",
                "priceAdjustmentCashBasis": "net",
                "referenceAnchor": "previous-session-official-close",
                "outputDecimals": 8
              },
              "eventRevisions": [
                {
                  "revisionId": "R1",
                  "securityId": "SYNTHETIC-SECURITY-004",
                  "eventId": "SYNTHETIC-SPECIAL-DIVIDEND-2026-01",
                  "status": "announced",
                  "issuerClassification": "special",
                  "grossAmount": 15,
                  "currency": "EUR",
                  "announcedAt": "2026-02-02T12:00:00Z",
                  "availableAt": "2026-02-02T12:05:00Z",
                  "exAt": "2026-03-16T13:30:00Z",
                  "paymentAt": "2026-03-20T12:00:00Z",
                  "actionOrder": 20,
                  "amountBasisOrder": 0,
                  "sourceId": "SYNTHETIC-ISSUER-NOTICE-R1"
                },
                {
                  "revisionId": "R2",
                  "securityId": "SYNTHETIC-SECURITY-004",
                  "eventId": "SYNTHETIC-SPECIAL-DIVIDEND-2026-01",
                  "status": "announced",
                  "issuerClassification": "special",
                  "grossAmount": 16,
                  "currency": "EUR",
                  "announcedAt": "2026-02-05T14:00:00Z",
                  "availableAt": "2026-02-05T14:10:00Z",
                  "exAt": "2026-03-16T13:30:00Z",
                  "paymentAt": "2026-03-20T12:00:00Z",
                  "actionOrder": 20,
                  "amountBasisOrder": 0,
                  "sourceId": "SYNTHETIC-ISSUER-NOTICE-R2"
                }
              ],
              "referencePrice": {
                "value": 100,
                "currency": "USD",
                "anchorType": "previous-session-official-close",
                "anchorAt": "2026-03-13T20:00:00Z",
                "observedAt": "2026-03-13T20:00:00Z",
                "availableAt": "2026-03-13T20:00:05Z",
                "sourceId": "SYNTHETIC-OFFICIAL-CLOSE"
              },
              "precedingActions": [
                {
                  "actionId": "SYNTHETIC-2-FOR-1-SPLIT",
                  "actionOrder": 10,
                  "priceFactor": 0.5,
                  "perShareAmountFactor": 0.5,
                  "effectiveAt": "2026-03-16T13:30:00Z",
                  "observedAt": "2026-02-01T10:00:00Z",
                  "availableAt": "2026-02-01T10:05:00Z",
                  "sourceId": "SYNTHETIC-ACTION-SOURCE"
                }
              ],
              "fxRate": {
                "baseCurrency": "EUR",
                "quoteCurrency": "USD",
                "rate": 1.1,
                "observedAt": "2026-03-13T20:00:00Z",
                "availableAt": "2026-03-13T20:00:05Z",
                "sourceId": "SYNTHETIC-FX-CLOSE"
              },
              "taxProfile": {
                "withholdingRate": 0.25,
                "jurisdiction": "SYNTHETIC-JURISDICTION",
                "investorCategory": "SYNTHETIC-NONRESIDENT",
                "observedAt": "2026-01-05T09:00:00Z",
                "availableAt": "2026-01-05T09:05:00Z",
                "sourceId": "SYNTHETIC-TAX-RULE"
              },
              "exPriceObservation": {
                "value": 43.75,
                "currency": "USD",
                "observedAt": "2026-03-16T20:00:00Z",
                "availableAt": "2026-03-16T20:00:05Z",
                "sourceId": "SYNTHETIC-EX-CLOSE"
              }
            },
            "elided": null
          }
        ],
        "output": {
          "eventState": "effective",
          "selectedRevisionId": "R2",
          "classificationDecision": "special",
          "classificationReason": "source designation: special",
          "adjustmentApplied": true,
          "referencePriceOnEventBasis": 50,
          "grossDividendOnEventBasis": 8.8,
          "netDividendOnEventBasis": 6.6,
          "adjustmentCashAmount": 6.6,
          "theoreticalExPrice": 43.4,
          "adjustmentFactor": 0.868,
          "grossDistributionYield": 0.176,
          "methodologyId": "SYNTHETIC-NET-RETURN-POLICY",
          "methodologyVersion": "1.0"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 16
        },
        "outputShape": "object with 16 fields: eventState, selectedRevisionId, classificationDecision, classificationReason, adjustmentApplied, referencePriceOnEventBasis, grossDividendOnEventBasis, netDividendOnEventBasis, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a04/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a04/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Evidence-to-adjustment calculation flow",
            "source": "flowchart LR\n    A[\"Versioned event evidence\"] --> B[\"Select latest available revision\"]\n    B --> C{\"Cancelled?\"}\n    C -->|Yes| X[\"Stop with diagnostic\"]\n    C -->|No| D[\"Validate ex-date and official-close anchor\"]\n    D --> E[\"Apply preceding same-day action bases\"]\n    E --> F[\"Convert FX and gross or net cash\"]\n    F --> G{\"Named policy says special?\"}\n    G -->|No| H[\"Factor 1; ordinary treatment\"]\n    G -->|Yes| I[\"Subtract cash and reject nonpositive result\"]\n    I --> J[\"Factor, returns, and lineage\"]\n    H --> J"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Point-in-time revision lifecycle",
            "source": "stateDiagram-v2\n    [*] --> Announced\n    Announced --> Revised: later version becomes available\n    Announced --> Cancelled: cancellation becomes latest\n    Revised --> Revised: another version becomes available\n    Revised --> Cancelled: cancellation becomes latest\n    Announced --> Effective: asOf reaches exAt\n    Revised --> Effective: asOf reaches exAt\n    Effective --> Corrected: post-event revision is processed by policy\n    Cancelled --> [*]\n    Corrected --> [*]"
          }
        ]
      },
      "references": [
        {
          "key": "R1 - S&P Dow Jones Indices Equity Indices Policies & Practices",
          "title": "R1 - S&P Dow Jones Indices Equity Indices Policies & Practices",
          "author": null,
          "url": null
        },
        {
          "key": "R2 - FTSE Russell Corporate Actions and Events Guide for Market Capitalisation Weighted Indices",
          "title": "R2 - FTSE Russell Corporate Actions and Events Guide for Market Capitalisation Weighted Indices",
          "author": null,
          "url": null
        },
        {
          "key": "R3 - FINRA Rule 11140, Transactions in Securities \"Ex-Dividend,\" \"Ex-Rights\" or \"Ex-Warrants\"",
          "title": "R3 - FINRA Rule 11140, Transactions in Securities \"Ex-Dividend,\" \"Ex-Rights\" or \"Ex-Warrants\"",
          "author": null,
          "url": null
        },
        {
          "key": "R4 - Costco Wholesale Corporation declares special cash dividend of $10 per share",
          "title": "R4 - Costco Wholesale Corporation declares special cash dividend of $10 per share",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/complex-distributions/special-dividend-adjustment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/complex-distributions/special-dividend-adjustment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F02-A05",
      "name": "Return-of-Capital Adjustment",
      "headline": "Keep Price, Return, and Tax Views Separate",
      "slug": "return-of-capital-adjustment",
      "path": "corporate-actions-and-security-master-data/complex-distributions/return-of-capital-adjustment",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F02",
        "family": "Complex Distributions",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/complex-distributions/return-of-capital-adjustment",
        "entry": "calculate",
        "params": [
          "payload"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(payload)"
      },
      "api": {
        "summary": "Applies a return of capital, which reduces the investor's cost basis rather than paying income. It affects price continuity and tax reporting differently from a dividend, and conflating the two misstates both.",
        "params": [
          {
            "name": "payload",
            "type": "{ asOf: string; revisions: EventRevision[]; referenceObservation: object; fxObservation?: object; exObservation?: object; taxIllustration?: object }",
            "required": true,
            "description": "`taxIllustration` is optional and, when supplied, drives an illustrative US federal treatment kept strictly separate from the market-data adjustment. Point-in-time by construction: `asOf` is the knowledge time, and only revisions available at or before it are eligible. Passing the event date instead of the knowledge date is what lets a backtest use information it could not have had.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, applied, marketDataAdjustment, investorReturnDiagnostics, usFederalTaxIllustration }",
          "description": "The market-data adjustment and the tax illustration as separate blocks, deliberately — one is a price-series fact and the other is jurisdiction-specific and illustrative only."
        },
        "warmup": null,
        "errors": [
          {
            "when": "no revision is available at asOf",
            "behaviour": "reported as a state rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(revisions)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F02-A05.json",
        "call": "calculate({\"asOf\":\"2025-02-03T21:05:00Z\",\"revisions\":[{\"eventId\":\"SYN-ROC-2025-001\",\"revisionId\":\"SYN-ANNOUNCEMENT-R1\",\"revisionSequence\":1,\"observedAt\":\"2025-01-20T14:00:00Z\",\"availableAt\":\"2025-01-20T14:02:00Z\",\"sourceId\":\"SYN-ISSUER-NOTICE\",\"status\":\"confirmed\",\"exAt\":\"2025-02-03T14:30:00Z\",\"sameDayOrdering\":{\"sequence\":1,\"priorEventIds\":[]},\"terms\":{\"eventCurrency\":\"USD\",\"grossCapitalReturnPerShare\":\"2.00000000\",\"withholdingPerShare\":\"0.10000000\",\"feesPerShare\":\"0.02000000\"}}],\"referenceObservation\":{\"price\":\"25.00000000\",\"currency\":\"USD\",\"observedAt\":\"2025-01-31T21:00:00Z\",\"availableAt\":\"2025-01-31T21:00:05Z\",\"sourceId\":\"SYN-OFFICIAL-CLOSE\"},\"fxObservation\":{\"priceCurrencyPerEventCurrency\":\"1.00000000\",\"pair\":\"USD/USD\",\"anchorPolicy\":\"ON_OR_BEFORE_REFERENCE_OBSERVATION\",\"observedAt\":\"2025-01-31T21:00:00Z\",\"availableAt\":\"2025-01-31T21:00:00Z\",\"sourceId\":\"IDENTITY-FX\"},\"exObservation\":{\"price\":\"23.15000000\",\"currency\":\"USD\",\"observedAt\":\"2025-02-03T21:00:00Z\",\"availableAt\":\"2025-02-03T21:00:04Z\",\"sourceId\":\"SYN-OFFICIAL-CLOSE\"},\"taxIllustration\":{\"jurisdiction\":\"US_FEDERAL_INDIVIDUAL_TAXABLE_2025\",\"currency\":\"USD\",\"basisPerShareBefore\":\"1.50000000\",\"confirmedReturnOfCapitalPerShare\":\"1.20000000\",\"sourceId\":\"SYN-FINAL-ISSUER-TAX-CLASSIFICATION\",\"observedAt\":\"2025-02-03T20:00:00Z\",\"availableAt\":\"2025-02-03T20:05:00Z\"}})",
        "args": [
          {
            "value": {
              "asOf": "2025-02-03T21:05:00Z",
              "revisions": [
                {
                  "eventId": "SYN-ROC-2025-001",
                  "revisionId": "SYN-ANNOUNCEMENT-R1",
                  "revisionSequence": 1,
                  "observedAt": "2025-01-20T14:00:00Z",
                  "availableAt": "2025-01-20T14:02:00Z",
                  "sourceId": "SYN-ISSUER-NOTICE",
                  "status": "confirmed",
                  "exAt": "2025-02-03T14:30:00Z",
                  "sameDayOrdering": {
                    "sequence": 1,
                    "priorEventIds": []
                  },
                  "terms": {
                    "eventCurrency": "USD",
                    "grossCapitalReturnPerShare": "2.00000000",
                    "withholdingPerShare": "0.10000000",
                    "feesPerShare": "0.02000000"
                  }
                }
              ],
              "referenceObservation": {
                "price": "25.00000000",
                "currency": "USD",
                "observedAt": "2025-01-31T21:00:00Z",
                "availableAt": "2025-01-31T21:00:05Z",
                "sourceId": "SYN-OFFICIAL-CLOSE"
              },
              "fxObservation": {
                "priceCurrencyPerEventCurrency": "1.00000000",
                "pair": "USD/USD",
                "anchorPolicy": "ON_OR_BEFORE_REFERENCE_OBSERVATION",
                "observedAt": "2025-01-31T21:00:00Z",
                "availableAt": "2025-01-31T21:00:00Z",
                "sourceId": "IDENTITY-FX"
              },
              "exObservation": {
                "price": "23.15000000",
                "currency": "USD",
                "observedAt": "2025-02-03T21:00:00Z",
                "availableAt": "2025-02-03T21:00:04Z",
                "sourceId": "SYN-OFFICIAL-CLOSE"
              },
              "taxIllustration": {
                "jurisdiction": "US_FEDERAL_INDIVIDUAL_TAXABLE_2025",
                "currency": "USD",
                "basisPerShareBefore": "1.50000000",
                "confirmedReturnOfCapitalPerShare": "1.20000000",
                "sourceId": "SYN-FINAL-ISSUER-TAX-CLASSIFICATION",
                "observedAt": "2025-02-03T20:00:00Z",
                "availableAt": "2025-02-03T20:05:00Z"
              }
            },
            "elided": null
          }
        ],
        "output": {
          "eventId": "SYN-ROC-2025-001",
          "revisionId": "SYN-ANNOUNCEMENT-R1",
          "state": "confirmed",
          "applied": true,
          "priceCurrency": "USD",
          "marketDataAdjustment": {
            "referencePrice": "25.00000000",
            "grossDistributionInPriceCurrency": "2.00000000",
            "theoreticalExPrice": "23.00000000",
            "backwardHistoryFactor": "0.92000000",
            "forwardPostEventFactor": "1.08695652",
            "factorDirection": "multiply_pre_ex_history_by_backwardHistoryFactor",
            "theoreticalPriceIsObservedTrade": false
          },
          "investorReturnDiagnostics": {
            "rawPriceReturn": "-0.07400000",
            "grossTotalReturn": "0.00600000",
            "netCashReturn": "0.00120000"
          },
          "usFederalTaxIllustration": {
            "basisPerShareAfter": "0.30000000",
            "basisReductionPerShare": "1.20000000",
            "excessOverBasisPerShare": "0.00000000"
          }
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: eventId, revisionId, state, applied, priceCurrency, marketDataAdjustment, investorReturnDiagnostics, usFederalTaxIllustration"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a05/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a05/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f02-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Point-in-time calculation flow",
            "source": "flowchart LR\n    A[\"Event revisions\"] --> B{\"availableAt <= asOf?\"}\n    P[\"Price and FX observations\"] --> C{\"observedAt <= availableAt <= asOf?\"}\n    B -- \"No\" --> X[\"Exclude future revision\"]\n    B -- \"Yes\" --> D[\"Latest knowable revision\"]\n    C -- \"No\" --> R[\"Reject\"]\n    C -- \"Yes\" --> V[\"Validate ex boundary and ordering\"]\n    D --> V\n    V --> M[\"Gross market-data factor\"]\n    V --> T[\"Observed price / gross / net returns\"]\n    V --> U[\"Optional scoped US basis illustration\"]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Revision lifecycle",
            "source": "stateDiagram-v2\n    [*] --> Announced\n    Announced --> Revised: corrected terms become available\n    Announced --> Confirmed: terms remain effective\n    Revised --> Confirmed: latest terms validated\n    Announced --> Cancelled: cancellation becomes available\n    Revised --> Cancelled: cancellation becomes available\n    Confirmed --> Corrected: later quantitative evidence\n    Corrected --> Confirmed: corrected revision selected\n    Cancelled --> [*]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "FTSE Russell Corporate Actions and Events Guide for Non-Market Capitalisation Weighted Indices",
          "author": null,
          "url": null
        },
        {
          "key": "R2",
          "title": "IRS Publication 550 (2025), Investment Income and Expenses",
          "author": null,
          "url": null
        },
        {
          "key": "R3",
          "title": "Instructions for Form 8937 (12/2017)",
          "author": null,
          "url": null
        },
        {
          "key": "R4",
          "title": "Logility Supply Chain Solutions announces tax treatment of 2024 distributions",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence classification",
          "title": "Evidence classification",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/complex-distributions/return-of-capital-adjustment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/complex-distributions/return-of-capital-adjustment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F03-A01",
      "name": "Permanent Security Identifier Mapping",
      "headline": "Scoped, Effective-Dated Crosswalks",
      "slug": "permanent-security-identifier-mapping",
      "path": "corporate-actions-and-security-master-data/identity-continuity/permanent-security-identifier-mapping",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F03",
        "family": "Identity Continuity",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/identity-continuity/permanent-security-identifier-mapping",
        "entry": "resolveIdentifier",
        "params": [
          "data"
        ],
        "exports": [
          "resolveIdentifier"
        ],
        "archetype": "row-classify",
        "signature": "resolveIdentifier(data)"
      },
      "api": {
        "summary": "Resolves a vendor or exchange identifier to a permanent internal key. Tickers are recycled and vendor ids are reassigned; anything keyed on them corrupts its own history without ever raising an error.",
        "params": [
          {
            "name": "data",
            "type": "{ query: { identifier: string; validAt: string; knowledgeAt: string }; assertions: Assertion[] }",
            "required": true,
            "description": "`validAt` is when the identifier was in use and `knowledgeAt` when you are asking — the two differ whenever a mapping is corrected after the fact. `assertions` is the evidence set the resolution draws on.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, canonicalId, candidateCanonicalIds, confidence, evidence, … }",
          "description": "The resolved key with its confidence and the evidence behind it — and, when the identifier is genuinely ambiguous, every candidate rather than an arbitrary pick."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the query is missing an identifier or a time",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(assertions)",
          "space": "O(candidates)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F03-A01.json",
        "call": "resolveIdentifier({\"query\":{\"source\":{\"scheme\":\"TICKER\",\"value\":\"alp\",\"entityLevel\":\"trading_line\",\"venueMic\":\"xnas\"},\"validAt\":\"2024-06-15T14:30:00Z\",\"knowledgeAt\":\"2024-06-20T12:00:00Z\"},\"assertions\":[{\"assertionId\":\"SYN-MAP-001\",\"revision\":1,\"source\":{\"scheme\":\"TICKER\",\"value\":\"ALP\",\"entityLevel\":\"trading_line\",\"venueMic\":\"XNAS\"},\"target\":{\"canonicalId\":\"SYN-LINE-ALPHA-XNAS-USD\",\"entityLevel\":\"trading_line\"},\"validFrom\":\"2024-01-02T14:30:00Z\",\"validTo\":\"2024-07-01T13:30:00Z\",\"observedAt\":\"2023-12-20T18:00:00Z\",\"availableAt\":\"2023-12-20T18:05:00Z\",\"status\":\"active\",\"confidence\":\"authoritative\",\"checkDigitStatus\":\"not_applicable\",\"assignmentAuthority\":\"SYNTHETIC EXCHANGE NOTICE SERVICE\",\"sourceDocumentId\":\"SYN-NOTICE-100-R1\"},{\"assertionId\":\"SYN-MAP-001\",\"revision\":2,\"source\":{\"scheme\":\"TICKER\",\"value\":\"ALP\",\"entityLevel\":\"trading_line\",\"venueMic\":\"XNAS\"},\"target\":{\"canonicalId\":\"SYN-LINE-BETA-XNAS-USD\",\"entityLevel\":\"trading_line\"},\"validFrom\":\"2024-01-02T14:30:00Z\",\"validTo\":\"2024-07-01T13:30:00Z\",\"observedAt\":\"2024-06-25T09:00:00Z\",\"availableAt\":\"2024-06-25T09:05:00Z\",\"status\":\"active\",\"confidence\":\"authoritative\",\"checkDigitStatus\":\"not_applicable\",\"assignmentAuthority\":\"SYNTHETIC EXCHANGE NOTICE SERVICE\",\"sourceDocumentId\":\"SYN-CORRECTION-100-R2\"},{\"assertionId\":\"SYN-MAP-002\",\"revision\":1,\"source\":{\"scheme\":\"TICKER\",\"value\":\"ALP\",\"entityLevel\":\"trading_line\",\"venueMic\":\"XNAS\"},\"target\":{\"canonicalId\":\"SYN-LINE-GAMMA-XNAS-USD\",\"entityLevel\":\"trading_line\"},\"validFrom\":\"2024-07-01T13:30:00Z\",\"validTo\":null,\"observedAt\":\"2024-06-10T16:00:00Z\",\"availableAt\":\"2024-06-10T16:03:00Z\",\"status\":\"active\",\"confidence\":\"authoritative\",\"checkDigitStatus\":\"not_applicable\",\"assignmentAuthority\":\"SYNTHETIC EXCHANGE NOTICE SERVICE\",\"sourceDocumentId\":\"SYN-NOTICE-101-R1\"}]})",
        "args": [
          {
            "value": {
              "query": {
                "source": {
                  "scheme": "TICKER",
                  "value": "alp",
                  "entityLevel": "trading_line",
                  "venueMic": "xnas"
                },
                "validAt": "2024-06-15T14:30:00Z",
                "knowledgeAt": "2024-06-20T12:00:00Z"
              },
              "assertions": [
                {
                  "assertionId": "SYN-MAP-001",
                  "revision": 1,
                  "source": {
                    "scheme": "TICKER",
                    "value": "ALP",
                    "entityLevel": "trading_line",
                    "venueMic": "XNAS"
                  },
                  "target": {
                    "canonicalId": "SYN-LINE-ALPHA-XNAS-USD",
                    "entityLevel": "trading_line"
                  },
                  "validFrom": "2024-01-02T14:30:00Z",
                  "validTo": "2024-07-01T13:30:00Z",
                  "observedAt": "2023-12-20T18:00:00Z",
                  "availableAt": "2023-12-20T18:05:00Z",
                  "status": "active",
                  "confidence": "authoritative",
                  "checkDigitStatus": "not_applicable",
                  "assignmentAuthority": "SYNTHETIC EXCHANGE NOTICE SERVICE",
                  "sourceDocumentId": "SYN-NOTICE-100-R1"
                },
                {
                  "assertionId": "SYN-MAP-001",
                  "revision": 2,
                  "source": {
                    "scheme": "TICKER",
                    "value": "ALP",
                    "entityLevel": "trading_line",
                    "venueMic": "XNAS"
                  },
                  "target": {
                    "canonicalId": "SYN-LINE-BETA-XNAS-USD",
                    "entityLevel": "trading_line"
                  },
                  "validFrom": "2024-01-02T14:30:00Z",
                  "validTo": "2024-07-01T13:30:00Z",
                  "observedAt": "2024-06-25T09:00:00Z",
                  "availableAt": "2024-06-25T09:05:00Z",
                  "status": "active",
                  "confidence": "authoritative",
                  "checkDigitStatus": "not_applicable",
                  "assignmentAuthority": "SYNTHETIC EXCHANGE NOTICE SERVICE",
                  "sourceDocumentId": "SYN-CORRECTION-100-R2"
                },
                {
                  "assertionId": "SYN-MAP-002",
                  "revision": 1,
                  "source": {
                    "scheme": "TICKER",
                    "value": "ALP",
                    "entityLevel": "trading_line",
                    "venueMic": "XNAS"
                  },
                  "target": {
                    "canonicalId": "SYN-LINE-GAMMA-XNAS-USD",
                    "entityLevel": "trading_line"
                  },
                  "validFrom": "2024-07-01T13:30:00Z",
                  "validTo": null,
                  "observedAt": "2024-06-10T16:00:00Z",
                  "availableAt": "2024-06-10T16:03:00Z",
                  "status": "active",
                  "confidence": "authoritative",
                  "checkDigitStatus": "not_applicable",
                  "assignmentAuthority": "SYNTHETIC EXCHANGE NOTICE SERVICE",
                  "sourceDocumentId": "SYN-NOTICE-101-R1"
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "source": {
            "scheme": "TICKER",
            "value": "ALP",
            "entityLevel": "trading_line",
            "venueMic": "XNAS"
          },
          "validAt": "2024-06-15T14:30:00Z",
          "knowledgeAt": "2024-06-20T12:00:00Z",
          "canonicalId": "SYN-LINE-ALPHA-XNAS-USD",
          "candidateCanonicalIds": [
            "SYN-LINE-ALPHA-XNAS-USD"
          ],
          "confidence": "authoritative",
          "evidence": [
            {
              "assertionId": "SYN-MAP-001",
              "revision": 1,
              "availableAt": "2023-12-20T18:05:00Z",
              "assignmentAuthority": "SYNTHETIC EXCHANGE NOTICE SERVICE",
              "sourceDocumentId": "SYN-NOTICE-100-R1",
              "confidence": "authoritative",
              "checkDigitStatus": "not_applicable"
            }
          ],
          "reason": "Exactly one canonical entity is supported at both requested clocks."
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: status, source, validAt, knowledgeAt, canonicalId, candidateCanonicalIds, confidence, evidence, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a01/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a01/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "identity-layers.md",
            "caption": "Identity layers",
            "source": "flowchart TB\n    LE[\"Legal entity\"] -->|acts as| ISS[\"Issuer\"]\n    ISS -->|issues| INS[\"Instrument or security\"]\n    INS -->|may define| CLS[\"Share class\"]\n    CLS -->|admitted as| LST[\"Listing\"]\n    LST -->|exposed through| LIN[\"Trading line\"]\n    VEN[\"Venue\"] -->|hosts| LIN\n    SYM[\"Quote-symbol assignment\"] -->|names in venue context| LIN"
          },
          {
            "file": "resolution-flow.md",
            "caption": "Two-clock resolution flow",
            "source": "flowchart LR\n    Q[\"Scoped source + validAt + knowledgeAt\"] --> V[\"Validate layer, venue, time, lineage\"]\n    V --> R[\"Group by assertion ID\"]\n    R --> K[\"Select latest revision available by knowledgeAt\"]\n    K --> B[\"Apply active status and validity at validAt\"]\n    B --> C[\"Count distinct same-layer targets\"]\n    C -->|0| U[\"Unmapped\"]\n    C -->|1| S[\"Resolved with evidence\"]\n    C -->|More than 1| A[\"Ambiguous with candidates\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "ISO 6166:2021, International securities identification number",
          "author": null,
          "url": null
        },
        {
          "key": "R2",
          "title": "ANNA ISIN Uniform Guidelines relating to ISO 6166",
          "author": null,
          "url": null
        },
        {
          "key": "R3",
          "title": "The Legal Entity Identifier: Questions and Answers",
          "author": null,
          "url": null
        },
        {
          "key": "R4",
          "title": "LEI Common Data File format 3.1",
          "author": null,
          "url": null
        },
        {
          "key": "R5",
          "title": "About CGS Identifiers",
          "author": null,
          "url": null
        },
        {
          "key": "R6",
          "title": "CGS identifier request terms",
          "author": null,
          "url": null
        },
        {
          "key": "R7",
          "title": "Financial Instrument Global Identifier Specification",
          "author": null,
          "url": null
        },
        {
          "key": "R8",
          "title": "ISO 10383:2012 and MIC Registration Authority",
          "author": null,
          "url": null
        },
        {
          "key": "R9",
          "title": "Corporate Actions by Public Companies",
          "author": null,
          "url": null
        },
        {
          "key": "R10",
          "title": "Nasdaq Symbol Directory Definitions",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/identity-continuity/permanent-security-identifier-mapping/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/identity-continuity/permanent-security-identifier-mapping/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F03-A02",
      "name": "Ticker-Change Chain Resolution",
      "headline": null,
      "slug": "ticker-change-chain-resolution",
      "path": "corporate-actions-and-security-master-data/identity-continuity/ticker-change-chain-resolution",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F03",
        "family": "Identity Continuity",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/identity-continuity/ticker-change-chain-resolution",
        "entry": "resolveTickerChain",
        "params": [
          "input"
        ],
        "exports": [
          "resolveTickerChain"
        ],
        "archetype": "row-classify",
        "signature": "resolveTickerChain(input)"
      },
      "api": {
        "summary": "Follows a symbol through renames in either direction. FB became META, and any store keyed on the symbol now holds two disconnected halves of one company's history.",
        "params": [
          {
            "name": "input",
            "type": "{ issuers: Issuer[]; instruments: Instrument[]; listings: Listing[]; assignments: Assignment[]; query: { symbol: string; asOf: string; queryAt: string } }",
            "required": true,
            "description": "The four reference tables separate the layers a symbol actually sits on — issuer, instrument, listing, and the symbol assignment itself. Collapsing them is what makes rename handling ad hoc.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, direction, symbol, listingId, instrumentId, issuerId, chain, … }",
          "description": "The resolved identifiers at every layer plus the chain traversed, so a surprising answer can be walked back."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the query symbol or time is missing",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(assignments)",
          "space": "O(chain)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F03-A02.json",
        "call": "resolveTickerChain({\"issuers\":[{\"issuerId\":\"SYN-ISS-001\"},{\"issuerId\":\"SYN-ISS-002\"}],\"instruments\":[{\"instrumentId\":\"SYN-INS-001\",\"issuerId\":\"SYN-ISS-001\",\"shareClassId\":\"SYN-CLS-A\"},{\"instrumentId\":\"SYN-INS-002\",\"issuerId\":\"SYN-ISS-002\",\"shareClassId\":\"SYN-CLS-COM\"}],\"listings\":[{\"listingId\":\"SYN-LST-001\",\"instrumentId\":\"SYN-INS-001\",\"venueMic\":\"XNAS\",\"currency\":\"USD\"},{\"listingId\":\"SYN-LST-002\",\"instrumentId\":\"SYN-INS-001\",\"venueMic\":\"XLON\",\"currency\":\"GBP\"},{\"listingId\":\"SYN-LST-099\",\"instrumentId\":\"SYN-INS-002\",\"venueMic\":\"XNAS\",\"currency\":\"USD\"}],\"assignments\":[{\"assignmentId\":\"SYN-ASG-100\",\"revision\":1,\"status\":\"active\",\"listingId\":\"SYN-LST-001\",\"symbol\":\"ALP\",\"effectiveAt\":\"2020-01-02T14:30:00Z\",\"validTo\":\"2024-06-10T13:30:00Z\",\"announcedAt\":\"2019-12-18T15:00:00Z\",\"availableAt\":\"2019-12-18T15:05:00Z\",\"changeKind\":\"initial_listing\",\"sourceId\":\"SYN-SRC-XNAS-100\"},{\"assignmentId\":\"SYN-ASG-200\",\"revision\":1,\"status\":\"active\",\"listingId\":\"SYN-LST-001\",\"symbol\":\"NXT\",\"effectiveAt\":\"2024-06-10T13:30:00Z\",\"validTo\":\"2025-01-10T14:30:00Z\",\"announcedAt\":\"2024-05-15T12:00:00Z\",\"availableAt\":\"2024-05-15T12:07:00Z\",\"changeKind\":\"administrative\",\"sourceId\":\"SYN-SRC-XNAS-200-R1\"},{\"assignmentId\":\"SYN-ASG-200\",\"revision\":2,\"status\":\"active\",\"listingId\":\"SYN-LST-001\",\"symbol\":\"NXT\",\"effectiveAt\":\"2024-06-10T13:30:00Z\",\"validTo\":\"2025-01-15T14:30:00Z\",\"announcedAt\":\"2024-05-15T12:00:00Z\",\"availableAt\":\"2024-12-20T16:10:00Z\",\"changeKind\":\"administrative\",\"sourceId\":\"SYN-SRC-XNAS-200-R2\"}],\"query\":{\"direction\":\"listing_to_symbol\",\"listingId\":\"SYN-LST-001\",\"queryAt\":\"2024-07-01T15:00:00Z\",\"asOf\":\"2024-08-01T12:00:00Z\"}})",
        "args": [
          {
            "value": {
              "issuers": [
                {
                  "issuerId": "SYN-ISS-001"
                },
                {
                  "issuerId": "SYN-ISS-002"
                }
              ],
              "instruments": [
                {
                  "instrumentId": "SYN-INS-001",
                  "issuerId": "SYN-ISS-001",
                  "shareClassId": "SYN-CLS-A"
                },
                {
                  "instrumentId": "SYN-INS-002",
                  "issuerId": "SYN-ISS-002",
                  "shareClassId": "SYN-CLS-COM"
                }
              ],
              "listings": [
                {
                  "listingId": "SYN-LST-001",
                  "instrumentId": "SYN-INS-001",
                  "venueMic": "XNAS",
                  "currency": "USD"
                },
                {
                  "listingId": "SYN-LST-002",
                  "instrumentId": "SYN-INS-001",
                  "venueMic": "XLON",
                  "currency": "GBP"
                },
                {
                  "listingId": "SYN-LST-099",
                  "instrumentId": "SYN-INS-002",
                  "venueMic": "XNAS",
                  "currency": "USD"
                }
              ],
              "assignments": [
                {
                  "assignmentId": "SYN-ASG-100",
                  "revision": 1,
                  "status": "active",
                  "listingId": "SYN-LST-001",
                  "symbol": "ALP",
                  "effectiveAt": "2020-01-02T14:30:00Z",
                  "validTo": "2024-06-10T13:30:00Z",
                  "announcedAt": "2019-12-18T15:00:00Z",
                  "availableAt": "2019-12-18T15:05:00Z",
                  "changeKind": "initial_listing",
                  "sourceId": "SYN-SRC-XNAS-100"
                },
                {
                  "assignmentId": "SYN-ASG-200",
                  "revision": 1,
                  "status": "active",
                  "listingId": "SYN-LST-001",
                  "symbol": "NXT",
                  "effectiveAt": "2024-06-10T13:30:00Z",
                  "validTo": "2025-01-10T14:30:00Z",
                  "announcedAt": "2024-05-15T12:00:00Z",
                  "availableAt": "2024-05-15T12:07:00Z",
                  "changeKind": "administrative",
                  "sourceId": "SYN-SRC-XNAS-200-R1"
                },
                {
                  "assignmentId": "SYN-ASG-200",
                  "revision": 2,
                  "status": "active",
                  "listingId": "SYN-LST-001",
                  "symbol": "NXT",
                  "effectiveAt": "2024-06-10T13:30:00Z",
                  "validTo": "2025-01-15T14:30:00Z",
                  "announcedAt": "2024-05-15T12:00:00Z",
                  "availableAt": "2024-12-20T16:10:00Z",
                  "changeKind": "administrative",
                  "sourceId": "SYN-SRC-XNAS-200-R2"
                }
              ],
              "query": {
                "direction": "listing_to_symbol",
                "listingId": "SYN-LST-001",
                "queryAt": "2024-07-01T15:00:00Z",
                "asOf": "2024-08-01T12:00:00Z"
              }
            },
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "direction": "listing_to_symbol",
          "queryAt": "2024-07-01T15:00:00Z",
          "asOf": "2024-08-01T12:00:00Z",
          "symbol": "NXT",
          "listingId": "SYN-LST-001",
          "instrumentId": "SYN-INS-001",
          "issuerId": "SYN-ISS-001",
          "shareClassId": "SYN-CLS-A",
          "venueMic": "XNAS",
          "currency": "USD",
          "assignmentId": "SYN-ASG-200",
          "revision": 1,
          "changeKind": "administrative"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 21
        },
        "outputShape": "object with 21 fields: status, direction, queryAt, asOf, symbol, listingId, instrumentId, issuerId, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a02/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a02/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Ticker-chain point-in-time resolution flow",
            "source": "flowchart TD\n    A[\"Issuer, instrument, listing, and assignment records\"] --> B[\"Validate keys, MIC and currency syntax, UTC instants, and foreign keys\"]\n    B --> C[\"Group versions by assignment ID\"]\n    C --> D[\"Select greatest revision available by asOf\"]\n    D --> E{\"Latest visible revision active?\"}\n    E -->|No| F[\"Remove cancelled assignment\"]\n    E -->|Yes| G[\"Keep visible assignment\"]\n    F --> H{\"Lookup direction\"}\n    G --> H\n    H -->|Listing to symbol| I[\"Filter listing ID and effective interval\"]\n    H -->|Symbol to listing| J[\"Filter exact symbol, venue MIC, and effective interval\"]\n    I --> K{\"Exactly one match?\"}\n    J --> K\n    K -->|Zero| L[\"Reject gap or unavailable evidence\"]\n    K -->|More than one| M[\"Reject ambiguous overlap\"]\n    K -->|One| N[\"Validate full listing chain for overlaps\"]\n    N --> O[\"Return symbol assignment plus listing, instrument, issuer ID, class ID, venue, currency, source, and diagnostics\"]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Symbol-assignment revision lifecycle",
            "source": "stateDiagram-v2\n    [*] --> Announced\n    Announced --> Available: source record ingested\n    Available --> Scheduled: effective time not reached\n    Available --> Effective: effective time reached\n    Scheduled --> Effective: effective time reached\n    Available --> Revised: later revision becomes available\n    Scheduled --> Revised: later revision becomes available\n    Effective --> Revised: correction becomes available\n    Revised --> Scheduled: corrected active revision is future-effective\n    Revised --> Effective: corrected active revision covers query time\n    Revised --> Cancelled: latest visible revision cancels plan\n    Cancelled --> [*]\n    Effective --> Expired: exclusive valid-to reached\n    Expired --> [*]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "ISO 10383 Market Identifier Codes",
          "author": "SWIFT as ISO 10383 Registration Authority, published through ISO 20022",
          "url": null
        },
        {
          "key": "R2",
          "title": "ANNA ISIN Uniform Guidelines",
          "author": "Association of National Numbering Agencies (ANNA), ISO 6166 Registration Authority",
          "url": null
        },
        {
          "key": "R3",
          "title": "ISO 6166:2021",
          "author": "International Organization for Standardization",
          "url": null
        },
        {
          "key": "R4",
          "title": "Financial Instrument Global Identifier Specification",
          "author": "Object Management Group",
          "url": null
        },
        {
          "key": "R5",
          "title": "Nasdaq Symbol Directory Data Fields and Definitions",
          "author": "Nasdaq Trader",
          "url": null
        },
        {
          "key": "R6",
          "title": "OTC Equity Daily List User Guide",
          "author": "Financial Industry Regulatory Authority (FINRA)",
          "url": null
        },
        {
          "key": "R7",
          "title": "SEC approval of the NMS symbol-selection and reservation plan",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/identity-continuity/ticker-change-chain-resolution/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/identity-continuity/ticker-change-chain-resolution/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F03-A03",
      "name": "Share-Class Relationship Mapping",
      "headline": "Same Issuer Does Not Mean Same Security",
      "slug": "share-class-relationship-mapping",
      "path": "corporate-actions-and-security-master-data/identity-continuity/share-class-relationship-mapping",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F03",
        "family": "Identity Continuity",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/identity-continuity/share-class-relationship-mapping",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Relates share classes of one issuer — GOOG and GOOGL, voting and non-voting lines. Index membership, float and liquidity screens all need to know these are one company, and naive de-duplication by name gets it wrong.",
        "params": [
          {
            "name": "data",
            "type": "{ query: object; entities: Entity[]; relationships: Relationship[] }",
            "required": true,
            "description": "`relationships` carries the declared links between classes rather than inferring them from name similarity, which fails on exactly the cases that matter.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ query, root, state, sameIssuerShareClassIds, comparison, resolvedRelationships, diagnostics }",
          "description": "Every class of the same issuer, with the comparison basis used and diagnostics for links that could not be resolved."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the query entity is unknown",
            "behaviour": "reported as a state rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(relationships)",
          "space": "O(classes)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F03-A03.json",
        "call": "calculate({\"query\":{\"rootEntityId\":\"SYN-CLASS-FOUNDER\",\"validAt\":\"2026-03-01T12:00:00Z\",\"knownAt\":\"2026-03-05T12:00:00Z\",\"compareShareClassIds\":[\"SYN-CLASS-FOUNDER\",\"SYN-CLASS-PUBLIC\"]},\"entities\":[{\"entityId\":\"SYN-ISSUER-ALPHA\",\"entityType\":\"ISSUER\",\"label\":\"Synthetic Alpha Holdings\"},{\"entityId\":\"SYN-INSTRUMENT-COMMON\",\"entityType\":\"LEGAL_INSTRUMENT\",\"label\":\"Synthetic Alpha Common Equity\"},{\"entityId\":\"SYN-INSTRUMENT-PREFERRED\",\"entityType\":\"LEGAL_INSTRUMENT\",\"label\":\"Synthetic Alpha Preferred Equity\"}],\"relationships\":[{\"assertionId\":\"R-ISSUE-COMMON\",\"revisionNumber\":1,\"status\":\"ACTIVE\",\"relationshipType\":\"ISSUED_BY\",\"sourceEntityId\":\"SYN-INSTRUMENT-COMMON\",\"targetEntityId\":\"SYN-ISSUER-ALPHA\",\"effectiveFrom\":\"2026-01-01T00:00:00Z\",\"effectiveTo\":null,\"observedAt\":\"2025-12-15T09:00:00Z\",\"availableAt\":\"2025-12-15T10:00:00Z\",\"source\":{\"sourceId\":\"SYN-CHARTER-1\",\"sourceType\":\"synthetic_charter\",\"documentDate\":\"2025-12-15\",\"locator\":\"Article IV\"},\"terms\":{\"basis\":\"legal-issuer\"},\"unsupportedTerms\":[]},{\"assertionId\":\"R-ISSUE-PREF\",\"revisionNumber\":1,\"status\":\"ACTIVE\",\"relationshipType\":\"ISSUED_BY\",\"sourceEntityId\":\"SYN-INSTRUMENT-PREFERRED\",\"targetEntityId\":\"SYN-ISSUER-ALPHA\",\"effectiveFrom\":\"2026-01-01T00:00:00Z\",\"effectiveTo\":null,\"observedAt\":\"2025-12-15T09:00:00Z\",\"availableAt\":\"2025-12-15T10:00:00Z\",\"source\":{\"sourceId\":\"SYN-CHARTER-1\",\"sourceType\":\"synthetic_charter\",\"documentDate\":\"2025-12-15\",\"locator\":\"Article IV\"},\"terms\":{\"basis\":\"legal-issuer\"},\"unsupportedTerms\":[]},{\"assertionId\":\"R-CLASS-FOUNDER\",\"revisionNumber\":1,\"status\":\"ACTIVE\",\"relationshipType\":\"CLASS_OF\",\"sourceEntityId\":\"SYN-CLASS-FOUNDER\",\"targetEntityId\":\"SYN-INSTRUMENT-COMMON\",\"effectiveFrom\":\"2026-01-01T00:00:00Z\",\"effectiveTo\":null,\"observedAt\":\"2025-12-15T09:00:00Z\",\"availableAt\":\"2025-12-15T10:00:00Z\",\"source\":{\"sourceId\":\"SYN-CHARTER-1\",\"sourceType\":\"synthetic_charter\",\"documentDate\":\"2025-12-15\",\"locator\":\"Article IV.1\"},\"terms\":{\"classCode\":\"F\"},\"unsupportedTerms\":[]}]})",
        "args": [
          {
            "value": {
              "query": {
                "rootEntityId": "SYN-CLASS-FOUNDER",
                "validAt": "2026-03-01T12:00:00Z",
                "knownAt": "2026-03-05T12:00:00Z",
                "compareShareClassIds": [
                  "SYN-CLASS-FOUNDER",
                  "SYN-CLASS-PUBLIC"
                ]
              },
              "entities": [
                {
                  "entityId": "SYN-ISSUER-ALPHA",
                  "entityType": "ISSUER",
                  "label": "Synthetic Alpha Holdings"
                },
                {
                  "entityId": "SYN-INSTRUMENT-COMMON",
                  "entityType": "LEGAL_INSTRUMENT",
                  "label": "Synthetic Alpha Common Equity"
                },
                {
                  "entityId": "SYN-INSTRUMENT-PREFERRED",
                  "entityType": "LEGAL_INSTRUMENT",
                  "label": "Synthetic Alpha Preferred Equity"
                }
              ],
              "relationships": [
                {
                  "assertionId": "R-ISSUE-COMMON",
                  "revisionNumber": 1,
                  "status": "ACTIVE",
                  "relationshipType": "ISSUED_BY",
                  "sourceEntityId": "SYN-INSTRUMENT-COMMON",
                  "targetEntityId": "SYN-ISSUER-ALPHA",
                  "effectiveFrom": "2026-01-01T00:00:00Z",
                  "effectiveTo": null,
                  "observedAt": "2025-12-15T09:00:00Z",
                  "availableAt": "2025-12-15T10:00:00Z",
                  "source": {
                    "sourceId": "SYN-CHARTER-1",
                    "sourceType": "synthetic_charter",
                    "documentDate": "2025-12-15",
                    "locator": "Article IV"
                  },
                  "terms": {
                    "basis": "legal-issuer"
                  },
                  "unsupportedTerms": []
                },
                {
                  "assertionId": "R-ISSUE-PREF",
                  "revisionNumber": 1,
                  "status": "ACTIVE",
                  "relationshipType": "ISSUED_BY",
                  "sourceEntityId": "SYN-INSTRUMENT-PREFERRED",
                  "targetEntityId": "SYN-ISSUER-ALPHA",
                  "effectiveFrom": "2026-01-01T00:00:00Z",
                  "effectiveTo": null,
                  "observedAt": "2025-12-15T09:00:00Z",
                  "availableAt": "2025-12-15T10:00:00Z",
                  "source": {
                    "sourceId": "SYN-CHARTER-1",
                    "sourceType": "synthetic_charter",
                    "documentDate": "2025-12-15",
                    "locator": "Article IV"
                  },
                  "terms": {
                    "basis": "legal-issuer"
                  },
                  "unsupportedTerms": []
                },
                {
                  "assertionId": "R-CLASS-FOUNDER",
                  "revisionNumber": 1,
                  "status": "ACTIVE",
                  "relationshipType": "CLASS_OF",
                  "sourceEntityId": "SYN-CLASS-FOUNDER",
                  "targetEntityId": "SYN-INSTRUMENT-COMMON",
                  "effectiveFrom": "2026-01-01T00:00:00Z",
                  "effectiveTo": null,
                  "observedAt": "2025-12-15T09:00:00Z",
                  "availableAt": "2025-12-15T10:00:00Z",
                  "source": {
                    "sourceId": "SYN-CHARTER-1",
                    "sourceType": "synthetic_charter",
                    "documentDate": "2025-12-15",
                    "locator": "Article IV.1"
                  },
                  "terms": {
                    "classCode": "F"
                  },
                  "unsupportedTerms": []
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "RESOLVED",
          "sameIssuerShareClassIds": [
            "SYN-CLASS-FOUNDER",
            "SYN-CLASS-PREFERRED",
            "SYN-CLASS-PUBLIC"
          ],
          "comparison": {
            "votingRightsRatioLeftToRight": {
              "status": "ESTABLISHED",
              "numerator": 10,
              "denominator": 1,
              "unit": "votes_per_share"
            },
            "economicRightsRatioLeftToRight": {
              "status": "ESTABLISHED",
              "numerator": 1,
              "denominator": 1,
              "unit": "distribution_units_per_share"
            },
            "equalEconomics": true,
            "conversion": {
              "status": "ESTABLISHED",
              "direction": "SYN-CLASS-FOUNDER->SYN-CLASS-PUBLIC",
              "relationshipType": "CONVERTS_TO",
              "ratio": {
                "numerator": 1,
                "denominator": 1
              },
              "unit": "target_shares_per_source_share",
              "conditions": [
                "qualifying_transfer"
              ]
            },
            "fungibility": {
              "status": "NOT_ESTABLISHED"
            },
            "priceConvertibility": "NOT_ESTABLISHED"
          },
          "diagnostics": {
            "excludedFutureRevisionCount": 1,
            "cancelledAssertionIds": [
              "R-LIST-OLD"
            ]
          }
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: state, sameIssuerShareClassIds, comparison, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a03/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a03/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Bitemporal relationship resolution",
            "source": "flowchart TD\n    A[Typed entities and relationship revisions] --> B{Contract valid?}\n    B -->|No| X[Reject input]\n    B -->|Yes| C[Group by stable assertion ID]\n    C --> D[Keep revisions available by knownAt]\n    D --> E[Select highest available revision]\n    E --> F{Cancelled?}\n    F -->|Yes| G[Record cancellation]\n    F -->|No| H{Interval contains validAt?}\n    H -->|No| I[Exclude from resolved graph]\n    H -->|Yes| J[Add typed edge with source and terms]\n    J --> K{Conflicts or unsupported terms?}\n    K -->|Conflict| L[Resolver result is CONFLICT]\n    K -->|Unsupported| M[Resolver result is INCOMPLETE]\n    K -->|No| N[Resolver result is RESOLVED]\n    N --> O[Compare explicit unit-compatible rights]\n    O --> P[Return graph and diagnostics]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Assertion and resolution lifecycle",
            "source": "stateDiagram-v2\n    [*] --> Observed\n    Observed --> Available: source enters system\n    Available --> Effective: valid interval contains validAt\n    Available --> Future: effectiveFrom after validAt\n    Available --> Expired: effectiveTo at or before validAt\n    Available --> Cancelled: latest available revision cancels assertion\n    Effective --> Resolved: terms supported and consistent\n    Effective --> Incomplete: unsupported contract term\n    Effective --> Conflict: incompatible active assertions\n    Future --> [*]\n    Expired --> [*]\n    Cancelled --> [*]\n    Resolved --> [*]\n    Incomplete --> [*]\n    Conflict --> [*]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "Alphabet Inc. 2025 Annual Report on Form 10-K",
          "author": "Alphabet Inc.; filed with the U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "R2",
          "title": "Financial Instrument Global Identifier Specification, version 1.2",
          "author": "Object Management Group",
          "url": null
        },
        {
          "key": "R3",
          "title": "ISO 6166:2021, Financial services — International securities identification number",
          "author": "International Organization for Standardization",
          "url": null
        },
        {
          "key": "R4",
          "title": "Alphabet Inc. Amended and Restated Certificate of Incorporation",
          "author": "Alphabet Inc.",
          "url": null
        },
        {
          "key": "Evidence classification",
          "title": "Evidence classification",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/identity-continuity/share-class-relationship-mapping/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/identity-continuity/share-class-relationship-mapping/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F03-A04",
      "name": "Merger Predecessor/Successor Mapping",
      "headline": "Preserve Identity and Entitlements Without Inventing Continuity",
      "slug": "merger-predecessor-successor-mapping",
      "path": "corporate-actions-and-security-master-data/identity-continuity/merger-predecessor-successor-mapping",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F03",
        "family": "Identity Continuity",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/identity-continuity/merger-predecessor-successor-mapping",
        "entry": "resolveMerger",
        "params": [
          "payload"
        ],
        "exports": [
          "resolveMerger"
        ],
        "archetype": "row-classify",
        "signature": "resolveMerger(payload)"
      },
      "api": {
        "summary": "Maps a position in a predecessor company onto what it became: successor shares, cash, or a mix. Getting the entitlement wrong is not a rounding error — it changes the return of the position outright.",
        "params": [
          {
            "name": "payload",
            "type": "{ asOf: string; position: Position; eventVersions: EventVersion[] }",
            "required": true,
            "description": "`eventVersions` is a revision history because merger terms are frequently amended before completion. Point-in-time by construction: `asOf` is the knowledge time, and only revisions available at or before it are eligible. Passing the event date instead of the knowledge date is what lets a backtest use information it could not have had.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, eventId, selectedRevision, effectiveAt, predecessor, allocations, successorPositions, cashByCurrency, … }",
          "description": "The resulting positions and cash by currency, with the allocation that produced them and which revision was in force — so a disputed entitlement can be reconstructed."
        },
        "warmup": null,
        "errors": [
          {
            "when": "no event version is effective at asOf",
            "behaviour": "reported as a state rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(versions)",
          "space": "O(successors)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F03-A04.json",
        "call": "resolveMerger({\"asOf\":\"2026-07-02T12:00:00Z\",\"position\":{\"predecessorQuantity\":\"101\",\"electedOptionId\":\"stock-election\",\"appraisalQuantity\":\"0\"},\"eventVersions\":[{\"eventId\":\"SYNTH-MERGER-001\",\"revision\":1,\"status\":\"confirmed\",\"availableAt\":\"2026-05-01T12:00:00Z\",\"announcedAt\":\"2026-04-15T12:00:00Z\",\"closingAt\":\"2026-06-30T20:00:00Z\",\"effectiveAt\":\"2026-06-30T20:00:00Z\",\"delistingAt\":\"2026-07-01T13:30:00Z\",\"sourceIds\":[\"SYNTH-DEFINITIVE-AGREEMENT-R1\",\"SYNTH-CLOSING-NOTICE\"],\"predecessor\":{\"issuerId\":\"ISSUER-TARGET\",\"instrumentId\":\"INSTR-TARGET-COMMON\",\"shareClassId\":\"CLASS-TARGET-A\",\"listingId\":\"LIST-TARGET-XNAS\",\"identifiers\":[{\"scheme\":\"PACKAGE_SECURITY_KEY\",\"value\":\"SYNTH-TARGET-A\",\"sourceId\":\"SYNTH-SECURITY-MASTER\"}]},\"options\":[{\"optionId\":\"stock-election\",\"stockLegs\":[{\"legId\":\"STOCK-LEG-1\",\"ratioPerAllocatedPredecessorShare\":\"0.6\",\"sourceId\":\"SYNTH-DEFINITIVE-AGREEMENT-R1\",\"successor\":{\"issuerId\":\"ISSUER-SUCCESSOR\",\"instrumentId\":\"INSTR-SUCCESSOR-COMMON\",\"shareClassId\":\"CLASS-SUCCESSOR-A\",\"listingId\":\"LIST-SUCCESSOR-XNYS\",\"identifiers\":[{\"scheme\":\"PACKAGE_SECURITY_KEY\",\"value\":\"SYNTH-SUCCESSOR-A\",\"sourceId\":\"SYNTH-SECURITY-MASTER\"}]},\"fractionalPolicy\":{\"mode\":\"cash_in_lieu\",\"lotSize\":\"1\",\"pricePerShare\":\"40\",\"currency\":\"USD\",\"observedAt\":\"2026-06-30T20:00:00Z\",\"availableAt\":\"2026-06-30T20:01:00Z\",\"sourceId\":\"SYNTH-CIL-PRICE\"}}],\"cashLegs\":[{\"legId\":\"CASH-1\",\"kind\":\"consideration\",\"amountPerAllocatedPredecessorShare\":\"5\",\"currency\":\"USD\",\"sourceId\":\"SYNTH-DEFINITIVE-AGREEMENT-R1\"},{\"legId\":\"TAX-1\",\"kind\":\"withholding\",\"amountPerAllocatedPredecessorShare\":\"0.2\",\"currency\":\"USD\",\"sourceId\":\"SYNTH-TAX-INSTRUCTION\"},{\"legId\":\"FEE-1\",\"kind\":\"fee\",\"amountPerAllocatedPredecessorShare\":\"0.05\",\"currency\":\"USD\",\"sourceId\":\"SYNTH-AGENT-INSTRUCTION\"}]},{\"optionId\":\"cash-election\",\"stockLegs\":[],\"cashLegs\":[{\"legId\":\"CASH-2\",\"kind\":\"consideration\",\"amountPerAllocatedPredecessorShare\":\"35\",\"currency\":\"USD\",\"sourceId\":\"SYNTH-DEFINITIVE-AGREEMENT-R1\"},{\"legId\":\"FEE-2\",\"kind\":\"fee\",\"amountPerAllocatedPredecessorShare\":\"0.05\",\"currency\":\"USD\",\"sourceId\":\"SYNTH-AGENT-INSTRUCTION\"}]}],\"electionRules\":{\"fallbackOptionId\":\"cash-election\",\"fulfilledFractions\":{\"stock-election\":\"0.75\",\"cash-election\":\"1\"}},\"termsSupported\":true}]})",
        "args": [
          {
            "value": {
              "asOf": "2026-07-02T12:00:00Z",
              "position": {
                "predecessorQuantity": "101",
                "electedOptionId": "stock-election",
                "appraisalQuantity": "0"
              },
              "eventVersions": [
                {
                  "eventId": "SYNTH-MERGER-001",
                  "revision": 1,
                  "status": "confirmed",
                  "availableAt": "2026-05-01T12:00:00Z",
                  "announcedAt": "2026-04-15T12:00:00Z",
                  "closingAt": "2026-06-30T20:00:00Z",
                  "effectiveAt": "2026-06-30T20:00:00Z",
                  "delistingAt": "2026-07-01T13:30:00Z",
                  "sourceIds": [
                    "SYNTH-DEFINITIVE-AGREEMENT-R1",
                    "SYNTH-CLOSING-NOTICE"
                  ],
                  "predecessor": {
                    "issuerId": "ISSUER-TARGET",
                    "instrumentId": "INSTR-TARGET-COMMON",
                    "shareClassId": "CLASS-TARGET-A",
                    "listingId": "LIST-TARGET-XNAS",
                    "identifiers": [
                      {
                        "scheme": "PACKAGE_SECURITY_KEY",
                        "value": "SYNTH-TARGET-A",
                        "sourceId": "SYNTH-SECURITY-MASTER"
                      }
                    ]
                  },
                  "options": [
                    {
                      "optionId": "stock-election",
                      "stockLegs": [
                        {
                          "legId": "STOCK-LEG-1",
                          "ratioPerAllocatedPredecessorShare": "0.6",
                          "sourceId": "SYNTH-DEFINITIVE-AGREEMENT-R1",
                          "successor": {
                            "issuerId": "ISSUER-SUCCESSOR",
                            "instrumentId": "INSTR-SUCCESSOR-COMMON",
                            "shareClassId": "CLASS-SUCCESSOR-A",
                            "listingId": "LIST-SUCCESSOR-XNYS",
                            "identifiers": [
                              {
                                "scheme": "PACKAGE_SECURITY_KEY",
                                "value": "SYNTH-SUCCESSOR-A",
                                "sourceId": "SYNTH-SECURITY-MASTER"
                              }
                            ]
                          },
                          "fractionalPolicy": {
                            "mode": "cash_in_lieu",
                            "lotSize": "1",
                            "pricePerShare": "40",
                            "currency": "USD",
                            "observedAt": "2026-06-30T20:00:00Z",
                            "availableAt": "2026-06-30T20:01:00Z",
                            "sourceId": "SYNTH-CIL-PRICE"
                          }
                        }
                      ],
                      "cashLegs": [
                        {
                          "legId": "CASH-1",
                          "kind": "consideration",
                          "amountPerAllocatedPredecessorShare": "5",
                          "currency": "USD",
                          "sourceId": "SYNTH-DEFINITIVE-AGREEMENT-R1"
                        },
                        {
                          "legId": "TAX-1",
                          "kind": "withholding",
                          "amountPerAllocatedPredecessorShare": "0.2",
                          "currency": "USD",
                          "sourceId": "SYNTH-TAX-INSTRUCTION"
                        },
                        {
                          "legId": "FEE-1",
                          "kind": "fee",
                          "amountPerAllocatedPredecessorShare": "0.05",
                          "currency": "USD",
                          "sourceId": "SYNTH-AGENT-INSTRUCTION"
                        }
                      ]
                    },
                    {
                      "optionId": "cash-election",
                      "stockLegs": [],
                      "cashLegs": [
                        {
                          "legId": "CASH-2",
                          "kind": "consideration",
                          "amountPerAllocatedPredecessorShare": "35",
                          "currency": "USD",
                          "sourceId": "SYNTH-DEFINITIVE-AGREEMENT-R1"
                        },
                        {
                          "legId": "FEE-2",
                          "kind": "fee",
                          "amountPerAllocatedPredecessorShare": "0.05",
                          "currency": "USD",
                          "sourceId": "SYNTH-AGENT-INSTRUCTION"
                        }
                      ]
                    }
                  ],
                  "electionRules": {
                    "fallbackOptionId": "cash-election",
                    "fulfilledFractions": {
                      "stock-election": "0.75",
                      "cash-election": "1"
                    }
                  },
                  "termsSupported": true
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "mapped",
          "eventId": "SYNTH-MERGER-001",
          "selectedRevision": 1,
          "effectiveAt": "2026-06-30T20:00:00Z",
          "predecessor": {
            "issuerId": "ISSUER-TARGET",
            "instrumentId": "INSTR-TARGET-COMMON",
            "shareClassId": "CLASS-TARGET-A",
            "listingId": "LIST-TARGET-XNAS",
            "identifiers": [
              {
                "scheme": "PACKAGE_SECURITY_KEY",
                "value": "SYNTH-TARGET-A",
                "sourceId": "SYNTH-SECURITY-MASTER"
              }
            ]
          },
          "allocations": [
            {
              "optionId": "stock-election",
              "role": "elected",
              "fulfilledFraction": "0.750000",
              "allocatedPredecessorQuantity": "75.750000"
            },
            {
              "optionId": "cash-election",
              "role": "fallback",
              "fulfilledFraction": "0.250000",
              "allocatedPredecessorQuantity": "25.250000"
            }
          ],
          "successorPositions": [
            {
              "issuerId": "ISSUER-SUCCESSOR",
              "instrumentId": "INSTR-SUCCESSOR-COMMON",
              "shareClassId": "CLASS-SUCCESSOR-A",
              "listingId": "LIST-SUCCESSOR-XNYS",
              "quantity": "45.000000"
            }
          ],
          "cashByCurrency": [
            {
              "currency": "USD",
              "consideration": "1262.500000",
              "appraisal": "0.000000",
              "withholding": "15.150000",
              "fees": "5.050000",
              "cashInLieu": "18.000000",
              "net": "1260.300000"
            }
          ],
          "fractionalSettlements": [
            {
              "stockLegId": "STOCK-LEG-1",
              "grossQuantity": "45.450000",
              "deliverableQuantity": "45.000000",
              "fractionalQuantity": "0.450000",
              "cashInLieu": "18.000000",
              "currency": "USD",
              "sourceId": "SYNTH-CIL-PRICE"
            }
          ],
          "identityEdges": [
            {
              "relation": "predecessor_instrument_to_successor_instrument",
              "fromInstrumentId": "INSTR-TARGET-COMMON",
              "toInstrumentId": "INSTR-SUCCESSOR-COMMON",
              "effectiveAt": "2026-06-30T20:00:00Z",
              "sourceId": "SYNTH-DEFINITIVE-AGREEMENT-R1"
            }
          ],
          "listingState": {
            "predecessor": "inactive",
            "successors": "not_established"
          },
          "priceAdjustment": {
            "state": "not_computed",
            "reason": "Identity and entitlement mapping does not create a historical price-adjustment series."
          },
          "diagnostics": {
            "asOf": "2026-07-02T12:00:00Z",
            "selectedVersionAvailableAt": "2026-05-01T12:00:00Z",
            "sourceIds": [
              "SYNTH-AGENT-INSTRUCTION",
              "SYNTH-CIL-PRICE",
              "SYNTH-CLOSING-NOTICE",
              "SYNTH-DEFINITIVE-AGREEMENT-R1",
              "SYNTH-SECURITY-MASTER",
              "SYNTH-TAX-INSTRUCTION"
            ]
          }
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: state, eventId, selectedRevision, effectiveAt, predecessor, allocations, successorPositions, cashByCurrency, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a04/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a04/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Point-in-time merger resolution",
            "source": "flowchart TD\n    A[\"Validate one event ID and immutable predecessor\"] --> B[\"Keep versions available by asOf\"]\n    B --> C{\"Unique highest revision?\"}\n    C -->|No version| P[\"Pending\"]\n    C -->|Conflict| M[\"Malformed input\"]\n    C -->|Yes| D{\"Latest status\"}\n    D -->|Cancelled| X[\"Cancelled\"]\n    D -->|Pending or pre-effective| P\n    D -->|Unsupported terms| U[\"Unsupported\"]\n    D -->|Confirmed and effective| E{\"Election and proration known?\"}\n    E -->|No| A1[\"Ambiguous\"]\n    E -->|Yes| F[\"Allocate stock and cash legs\"]\n    F --> G{\"Fractional policy evidenced?\"}\n    G -->|Waiting for CIL price| P\n    G -->|Reject conflicts with fraction| U\n    G -->|Yes| H[\"Mapped positions, cash, and identity edges\"]\n    H --> I[\"Successor listing not established\"]\n    H --> J[\"Historical price adjustment not computed\"]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Merger mapping lifecycle",
            "source": "stateDiagram-v2\n    [*] --> Pending\n    Pending --> Pending: version known but not effective\n    Pending --> Cancelled: latest available revision cancels\n    Pending --> Ambiguous: effective but election unresolved\n    Pending --> Unsupported: terms or fractional policy out of scope\n    Pending --> Mapped: effective and fully evidenced\n    Ambiguous --> Mapped: sourced election or fallback arrives\n    Unsupported --> Mapped: supported revised terms arrive\n    Mapped --> Cancelled: later cancellation known before effective use\n    Cancelled --> [*]\n    Mapped --> [*]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "Disney closing Form 8-K for the 21CF acquisition",
          "author": null,
          "url": null
        },
        {
          "key": "R2",
          "title": "Disney and 21CF filed issuer release announcing per-share value",
          "author": null,
          "url": null
        },
        {
          "key": "R3",
          "title": "Disney and 21CF definitive joint proxy statement/prospectus",
          "author": null,
          "url": null
        },
        {
          "key": "R4",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": null,
          "url": null
        },
        {
          "key": "R5",
          "title": "ISO 6166:2021, International Securities Identification Number",
          "author": null,
          "url": null
        },
        {
          "key": "R6",
          "title": "NYSE Group Security Master Client Specification",
          "author": null,
          "url": null
        },
        {
          "key": "R7",
          "title": "SEC rule release on removal from listing and successor securities",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/identity-continuity/merger-predecessor-successor-mapping/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/identity-continuity/merger-predecessor-successor-mapping/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F03-A05",
      "name": "Delisting Return Reconstruction",
      "headline": "Separate Observed Proceeds from Estimates",
      "slug": "delisting-return-reconstruction",
      "path": "corporate-actions-and-security-master-data/identity-continuity/delisting-return-reconstruction",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F03",
        "family": "Identity Continuity",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/identity-continuity/delisting-return-reconstruction",
        "entry": "calculate",
        "params": [
          "input"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(input)"
      },
      "api": {
        "summary": "Reconstructs the final return of a security that stopped trading. Omitting it is one of the largest sources of survivorship bias in equity research: the companies that failed are exactly the ones with no last price.",
        "params": [
          {
            "name": "input",
            "type": "{ asOf: string; baseCurrency: string; previousRegularObservation: object; lastRegularObservation: object; event: object; proceedsStatus: string; proceeds?: object; deductions?: object; researchImputation?: object }",
            "required": true,
            "description": "`proceedsStatus` distinguishes proceeds that are known, pending or never paid. `researchImputation` supplies the convention to use when nothing was recovered — CRSP-style imputed delisting returns exist precisely because the honest answer is not zero.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ observed, researchEstimate, diagnostics }",
          "description": "The observed return and the imputed research estimate as **separate** fields. Merging them would hide the difference between what happened and what a convention assumes happened."
        },
        "warmup": null,
        "errors": [
          {
            "when": "proceedsStatus is unrecognised",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F03-A05.json",
        "call": "calculate({\"asOf\":\"2026-04-17T12:00:00Z\",\"baseCurrency\":\"USD\",\"previousRegularObservation\":{\"securityId\":\"SYNTH-OLD-A\",\"price\":\"48\",\"currency\":\"USD\",\"tradingAt\":\"2026-04-10T20:00:00Z\",\"observedAt\":\"2026-04-10T20:00:00Z\",\"sourceAt\":\"2026-04-10T20:01:00Z\",\"availableAt\":\"2026-04-10T20:05:00Z\",\"sourceId\":\"SYNTH-PRICES\"},\"lastRegularObservation\":{\"securityId\":\"SYNTH-OLD-A\",\"price\":\"50\",\"currency\":\"USD\",\"tradingAt\":\"2026-04-14T20:00:00Z\",\"observedAt\":\"2026-04-14T20:00:00Z\",\"sourceAt\":\"2026-04-14T20:01:00Z\",\"availableAt\":\"2026-04-14T20:05:00Z\",\"sourceId\":\"SYNTH-PRICES\"},\"event\":{\"eventId\":\"SYNTH-EVENT-001\",\"reason\":\"merger\",\"effectiveAt\":\"2026-04-15T13:30:00Z\",\"observedAt\":\"2026-04-01T14:00:00Z\",\"sourceAt\":\"2026-04-01T14:01:00Z\",\"availableAt\":\"2026-04-01T14:05:00Z\",\"sourceId\":\"SYNTH-EVENTS\"},\"proceedsStatus\":\"complete\",\"proceeds\":[{\"kind\":\"cash\",\"amountPerOldShare\":\"10\",\"currency\":\"EUR\",\"effectiveAt\":\"2026-04-15T13:30:00Z\",\"observedAt\":\"2026-04-15T15:00:00Z\",\"sourceAt\":\"2026-04-15T15:01:00Z\",\"availableAt\":\"2026-04-16T00:00:00Z\",\"sourceId\":\"SYNTH-PAYMENTS\",\"fxToBase\":{\"fromCurrency\":\"EUR\",\"toCurrency\":\"USD\",\"rate\":\"1.1\",\"rateAt\":\"2026-04-15T20:00:00Z\",\"observedAt\":\"2026-04-15T20:00:00Z\",\"sourceAt\":\"2026-04-15T20:01:00Z\",\"availableAt\":\"2026-04-16T00:00:00Z\",\"sourceId\":\"SYNTH-FX\"}},{\"kind\":\"stock\",\"quantityPerOldShare\":\"0.8\",\"successorSecurityId\":\"SYNTH-NEW-B\",\"valuationPrice\":\"52.5\",\"priceCurrency\":\"USD\",\"valuationAt\":\"2026-04-15T20:00:00Z\",\"observedAt\":\"2026-04-15T20:00:00Z\",\"sourceAt\":\"2026-04-15T20:01:00Z\",\"availableAt\":\"2026-04-16T00:00:00Z\",\"sourceId\":\"SYNTH-SUCCESSOR-PRICE\",\"fxToBase\":{\"fromCurrency\":\"USD\",\"toCurrency\":\"USD\",\"rate\":\"1\",\"rateAt\":\"2026-04-15T20:00:00Z\",\"observedAt\":\"2026-04-15T20:00:00Z\",\"sourceAt\":\"2026-04-15T20:01:00Z\",\"availableAt\":\"2026-04-16T00:00:00Z\",\"sourceId\":\"SYNTH-FX-IDENTITY\"}}],\"deductions\":[{\"kind\":\"fee\",\"amountPerOldShare\":\"0.2\",\"currency\":\"USD\",\"effectiveAt\":\"2026-04-15T13:30:00Z\",\"observedAt\":\"2026-04-15T21:00:00Z\",\"sourceAt\":\"2026-04-15T21:01:00Z\",\"availableAt\":\"2026-04-16T00:00:00Z\",\"sourceId\":\"SYNTH-FEES\",\"fxToBase\":{\"fromCurrency\":\"USD\",\"toCurrency\":\"USD\",\"rate\":\"1\",\"rateAt\":\"2026-04-15T20:00:00Z\",\"observedAt\":\"2026-04-15T20:00:00Z\",\"sourceAt\":\"2026-04-15T20:01:00Z\",\"availableAt\":\"2026-04-16T00:00:00Z\",\"sourceId\":\"SYNTH-FX-IDENTITY\"}},{\"kind\":\"withholding\",\"amountPerOldShare\":\"0.3\",\"currency\":\"USD\",\"effectiveAt\":\"2026-04-15T13:30:00Z\",\"observedAt\":\"2026-04-15T21:00:00Z\",\"sourceAt\":\"2026-04-15T21:01:00Z\",\"availableAt\":\"2026-04-16T00:00:00Z\",\"sourceId\":\"SYNTH-WITHHOLDING\",\"fxToBase\":{\"fromCurrency\":\"USD\",\"toCurrency\":\"USD\",\"rate\":\"1\",\"rateAt\":\"2026-04-15T20:00:00Z\",\"observedAt\":\"2026-04-15T20:00:00Z\",\"sourceAt\":\"2026-04-15T20:01:00Z\",\"availableAt\":\"2026-04-16T00:00:00Z\",\"sourceId\":\"SYNTH-FX-IDENTITY\"}}],\"researchImputation\":null})",
        "args": [
          {
            "value": {
              "asOf": "2026-04-17T12:00:00Z",
              "baseCurrency": "USD",
              "previousRegularObservation": {
                "securityId": "SYNTH-OLD-A",
                "price": "48",
                "currency": "USD",
                "tradingAt": "2026-04-10T20:00:00Z",
                "observedAt": "2026-04-10T20:00:00Z",
                "sourceAt": "2026-04-10T20:01:00Z",
                "availableAt": "2026-04-10T20:05:00Z",
                "sourceId": "SYNTH-PRICES"
              },
              "lastRegularObservation": {
                "securityId": "SYNTH-OLD-A",
                "price": "50",
                "currency": "USD",
                "tradingAt": "2026-04-14T20:00:00Z",
                "observedAt": "2026-04-14T20:00:00Z",
                "sourceAt": "2026-04-14T20:01:00Z",
                "availableAt": "2026-04-14T20:05:00Z",
                "sourceId": "SYNTH-PRICES"
              },
              "event": {
                "eventId": "SYNTH-EVENT-001",
                "reason": "merger",
                "effectiveAt": "2026-04-15T13:30:00Z",
                "observedAt": "2026-04-01T14:00:00Z",
                "sourceAt": "2026-04-01T14:01:00Z",
                "availableAt": "2026-04-01T14:05:00Z",
                "sourceId": "SYNTH-EVENTS"
              },
              "proceedsStatus": "complete",
              "proceeds": [
                {
                  "kind": "cash",
                  "amountPerOldShare": "10",
                  "currency": "EUR",
                  "effectiveAt": "2026-04-15T13:30:00Z",
                  "observedAt": "2026-04-15T15:00:00Z",
                  "sourceAt": "2026-04-15T15:01:00Z",
                  "availableAt": "2026-04-16T00:00:00Z",
                  "sourceId": "SYNTH-PAYMENTS",
                  "fxToBase": {
                    "fromCurrency": "EUR",
                    "toCurrency": "USD",
                    "rate": "1.1",
                    "rateAt": "2026-04-15T20:00:00Z",
                    "observedAt": "2026-04-15T20:00:00Z",
                    "sourceAt": "2026-04-15T20:01:00Z",
                    "availableAt": "2026-04-16T00:00:00Z",
                    "sourceId": "SYNTH-FX"
                  }
                },
                {
                  "kind": "stock",
                  "quantityPerOldShare": "0.8",
                  "successorSecurityId": "SYNTH-NEW-B",
                  "valuationPrice": "52.5",
                  "priceCurrency": "USD",
                  "valuationAt": "2026-04-15T20:00:00Z",
                  "observedAt": "2026-04-15T20:00:00Z",
                  "sourceAt": "2026-04-15T20:01:00Z",
                  "availableAt": "2026-04-16T00:00:00Z",
                  "sourceId": "SYNTH-SUCCESSOR-PRICE",
                  "fxToBase": {
                    "fromCurrency": "USD",
                    "toCurrency": "USD",
                    "rate": "1",
                    "rateAt": "2026-04-15T20:00:00Z",
                    "observedAt": "2026-04-15T20:00:00Z",
                    "sourceAt": "2026-04-15T20:01:00Z",
                    "availableAt": "2026-04-16T00:00:00Z",
                    "sourceId": "SYNTH-FX-IDENTITY"
                  }
                }
              ],
              "deductions": [
                {
                  "kind": "fee",
                  "amountPerOldShare": "0.2",
                  "currency": "USD",
                  "effectiveAt": "2026-04-15T13:30:00Z",
                  "observedAt": "2026-04-15T21:00:00Z",
                  "sourceAt": "2026-04-15T21:01:00Z",
                  "availableAt": "2026-04-16T00:00:00Z",
                  "sourceId": "SYNTH-FEES",
                  "fxToBase": {
                    "fromCurrency": "USD",
                    "toCurrency": "USD",
                    "rate": "1",
                    "rateAt": "2026-04-15T20:00:00Z",
                    "observedAt": "2026-04-15T20:00:00Z",
                    "sourceAt": "2026-04-15T20:01:00Z",
                    "availableAt": "2026-04-16T00:00:00Z",
                    "sourceId": "SYNTH-FX-IDENTITY"
                  }
                },
                {
                  "kind": "withholding",
                  "amountPerOldShare": "0.3",
                  "currency": "USD",
                  "effectiveAt": "2026-04-15T13:30:00Z",
                  "observedAt": "2026-04-15T21:00:00Z",
                  "sourceAt": "2026-04-15T21:01:00Z",
                  "availableAt": "2026-04-16T00:00:00Z",
                  "sourceId": "SYNTH-WITHHOLDING",
                  "fxToBase": {
                    "fromCurrency": "USD",
                    "toCurrency": "USD",
                    "rate": "1",
                    "rateAt": "2026-04-15T20:00:00Z",
                    "observedAt": "2026-04-15T20:00:00Z",
                    "sourceAt": "2026-04-15T20:01:00Z",
                    "availableAt": "2026-04-16T00:00:00Z",
                    "sourceId": "SYNTH-FX-IDENTITY"
                  }
                }
              ],
              "researchImputation": null
            },
            "elided": null
          }
        ],
        "output": {
          "observed": {
            "status": "complete",
            "lastRegularReturn": "0.041666666667",
            "terminalGrossValuePerOldShare": "53.000000000000",
            "deductionsPerOldShare": "0.500000000000",
            "terminalNetValuePerOldShare": "52.500000000000",
            "terminalReturn": "0.050000000000",
            "linkedReturn": "0.093750000000",
            "proceedsBasis": "complete_observed",
            "knownObservedGrossValuePerOldShare": null,
            "knownObservedDeductionsPerOldShare": null,
            "knownObservedNetValuePerOldShare": null
          },
          "researchEstimate": null,
          "diagnostics": {
            "eventId": "SYNTH-EVENT-001",
            "eventReason": "merger",
            "asOf": "2026-04-17T12:00:00Z",
            "effectiveAt": "2026-04-15T13:30:00Z",
            "lastRegularTradingAt": "2026-04-14T20:00:00Z",
            "observedEvidenceAvailable": true,
            "missingEvidence": [],
            "withheldEvidence": [],
            "knownProceedsEvidence": [
              "deductions[0]",
              "deductions[0].fxToBase",
              "deductions[1]",
              "deductions[1].fxToBase",
              "proceeds[0]",
              "proceeds[0].fxToBase"
            ],
            "baseCurrency": "USD"
          }
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: observed, researchEstimate, diagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a05/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a05/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f03-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Evidence-gated calculation flow",
            "source": "flowchart TD\n    A[\"Price and event records\"] --> B[\"Validate decimals, identity, currency, and clocks\"]\n    B --> C{\"Available at as-of time?\"}\n    C -->|No| D[\"Not yet available; returns null\"]\n    C -->|Yes| E{\"Event effective?\"}\n    E -->|No| F[\"Event not effective; terminal return null\"]\n    E -->|Yes| G[\"Value known cash, stock, FX, fees, and withholding\"]\n    G --> H{\"Proceeds evidence state\"}\n    H -->|Complete| I[\"Observed terminal and linked returns\"]\n    H -->|Explicit zero| I\n    H -->|Partial| J[\"Known subtotal; returns null\"]\n    H -->|Unknown| K[\"Missing proceeds; returns null\"]\n    L[\"Documented research policy\"] --> M[\"Research estimate branch\"]\n    M -. \"Never fills observed fields\" .-> I"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Point-in-time evidence lifecycle",
            "source": "stateDiagram-v2\n    [*] --> EventUnavailable\n    EventUnavailable --> EventKnown: event available\n    EventKnown --> EventEffective: effective time reached\n    EventEffective --> ProceedsUnknown: no terminal evidence\n    EventEffective --> ProceedsPartial: some observed legs\n    EventEffective --> ProceedsComplete: complete observed legs\n    EventEffective --> ZeroConfirmed: explicit zero evidence\n    ProceedsUnknown --> ProceedsPartial: first observed leg\n    ProceedsPartial --> ProceedsComplete: completeness established\n    ProceedsUnknown --> ResearchEstimate: documented policy\n    ProceedsPartial --> ResearchEstimate: documented policy\n    ResearchEstimate --> ResearchEstimate: later estimates remain labeled\n    ResearchEstimate --> ProceedsComplete: observed branch completes separately\n    ProceedsComplete --> [*]\n    ZeroConfirmed --> [*]"
          }
        ]
      },
      "references": [
        {
          "key": "R1 - CRSPAccess US Stock and Index Databases Data Descriptions Guide",
          "title": "R1 - CRSPAccess US Stock and Index Databases Data Descriptions Guide",
          "author": null,
          "url": null
        },
        {
          "key": "R2 - CRSP US Stock and Indexes Databases Data Descriptions Guide",
          "title": "R2 - CRSP US Stock and Indexes Databases Data Descriptions Guide",
          "author": null,
          "url": null
        },
        {
          "key": "R3 - Nasdaq Daily List Product Description",
          "title": "R3 - Nasdaq Daily List Product Description",
          "author": null,
          "url": null
        },
        {
          "key": "R4 - SEC Exchange Delistings",
          "title": "R4 - SEC Exchange Delistings",
          "author": null,
          "url": null
        },
        {
          "key": "R5 - SEC Exchange Act Forms, Section 111.01",
          "title": "R5 - SEC Exchange Act Forms, Section 111.01",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary for historical examples",
          "title": "Evidence boundary for historical examples",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/identity-continuity/delisting-return-reconstruction/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/identity-continuity/delisting-return-reconstruction/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F04-A01",
      "name": "Historical Constituent Reconstruction",
      "headline": "Rebuild the Roster Without Looking Ahead",
      "slug": "historical-constituent-reconstruction",
      "path": "corporate-actions-and-security-master-data/point-in-time-universe/historical-constituent-reconstruction",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F04",
        "family": "Point-in-Time Universe",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/point-in-time-universe/historical-constituent-reconstruction",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Rebuilds an index's membership as it stood on a past date, from a base snapshot plus the change events since. Testing a strategy on today's members instead guarantees flattering results, because today's members are the survivors.",
        "params": [
          {
            "name": "data",
            "type": "{ indexId: string; effectiveAt: string; knownAt: string; snapshots: Snapshot[]; events: Event[] }",
            "required": true,
            "description": "`effectiveAt` is the date whose roster you want; `knownAt` is when you are asking. They differ whenever a membership change is announced before it takes effect, or corrected afterwards — and conflating them is the bias this exists to prevent.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, indexId, effectiveAt, knownAt, baseSnapshotId, securityIds, membershipIntervals, … }",
          "description": "The roster with the interval each member was in the index, and which snapshot it was rolled forward from."
        },
        "warmup": null,
        "errors": [
          {
            "when": "no snapshot precedes effectiveAt",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(events)",
          "space": "O(members)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F04-A01.json",
        "call": "calculate({\"indexId\":\"IDX:SYNTH:ALPHA\",\"effectiveAt\":\"2024-08-15T00:00:00Z\",\"knownAt\":\"2024-08-15T12:00:00Z\",\"snapshots\":[{\"snapshotId\":\"BASE-2024\",\"indexId\":\"IDX:SYNTH:ALPHA\",\"revision\":1,\"effectiveAt\":\"2024-01-01T00:00:00Z\",\"availableAt\":\"2024-01-02T09:00:00Z\",\"lastSequence\":0,\"status\":\"active\",\"securityIds\":[\"SEC:A\",\"SEC:B\",\"SEC:C\",\"SEC:D\"],\"sourceId\":\"SYNTH-BASE\"}],\"events\":[{\"eventId\":\"EV-001\",\"indexId\":\"IDX:SYNTH:ALPHA\",\"revision\":1,\"sequence\":1,\"eventType\":\"add\",\"effectiveOrder\":0,\"effectiveAt\":\"2024-02-01T00:00:00Z\",\"announcedAt\":\"2024-01-15T12:00:00Z\",\"availableAt\":\"2024-01-15T12:05:00Z\",\"status\":\"active\",\"changes\":[{\"action\":\"add\",\"securityId\":\"SEC:E\"}],\"sourceId\":\"SYNTH-NOTICE-001\"},{\"eventId\":\"EV-002\",\"indexId\":\"IDX:SYNTH:ALPHA\",\"revision\":1,\"sequence\":2,\"eventType\":\"replace\",\"effectiveOrder\":0,\"effectiveAt\":\"2024-03-01T00:00:00Z\",\"announcedAt\":\"2024-02-20T16:00:00Z\",\"availableAt\":\"2024-02-20T16:03:00Z\",\"status\":\"active\",\"changes\":[{\"action\":\"delete\",\"securityId\":\"SEC:B\"},{\"action\":\"add\",\"securityId\":\"SEC:F\"}],\"sourceId\":\"SYNTH-NOTICE-002\"},{\"eventId\":\"EV-003\",\"indexId\":\"IDX:SYNTH:ALPHA\",\"revision\":1,\"sequence\":3,\"eventType\":\"rebalance\",\"effectiveOrder\":0,\"effectiveAt\":\"2024-04-01T00:00:00Z\",\"announcedAt\":\"2024-03-20T15:00:00Z\",\"availableAt\":\"2024-03-20T15:04:00Z\",\"status\":\"active\",\"changes\":[],\"sourceId\":\"SYNTH-NOTICE-003\"}]})",
        "args": [
          {
            "value": {
              "indexId": "IDX:SYNTH:ALPHA",
              "effectiveAt": "2024-08-15T00:00:00Z",
              "knownAt": "2024-08-15T12:00:00Z",
              "snapshots": [
                {
                  "snapshotId": "BASE-2024",
                  "indexId": "IDX:SYNTH:ALPHA",
                  "revision": 1,
                  "effectiveAt": "2024-01-01T00:00:00Z",
                  "availableAt": "2024-01-02T09:00:00Z",
                  "lastSequence": 0,
                  "status": "active",
                  "securityIds": [
                    "SEC:A",
                    "SEC:B",
                    "SEC:C",
                    "SEC:D"
                  ],
                  "sourceId": "SYNTH-BASE"
                }
              ],
              "events": [
                {
                  "eventId": "EV-001",
                  "indexId": "IDX:SYNTH:ALPHA",
                  "revision": 1,
                  "sequence": 1,
                  "eventType": "add",
                  "effectiveOrder": 0,
                  "effectiveAt": "2024-02-01T00:00:00Z",
                  "announcedAt": "2024-01-15T12:00:00Z",
                  "availableAt": "2024-01-15T12:05:00Z",
                  "status": "active",
                  "changes": [
                    {
                      "action": "add",
                      "securityId": "SEC:E"
                    }
                  ],
                  "sourceId": "SYNTH-NOTICE-001"
                },
                {
                  "eventId": "EV-002",
                  "indexId": "IDX:SYNTH:ALPHA",
                  "revision": 1,
                  "sequence": 2,
                  "eventType": "replace",
                  "effectiveOrder": 0,
                  "effectiveAt": "2024-03-01T00:00:00Z",
                  "announcedAt": "2024-02-20T16:00:00Z",
                  "availableAt": "2024-02-20T16:03:00Z",
                  "status": "active",
                  "changes": [
                    {
                      "action": "delete",
                      "securityId": "SEC:B"
                    },
                    {
                      "action": "add",
                      "securityId": "SEC:F"
                    }
                  ],
                  "sourceId": "SYNTH-NOTICE-002"
                },
                {
                  "eventId": "EV-003",
                  "indexId": "IDX:SYNTH:ALPHA",
                  "revision": 1,
                  "sequence": 3,
                  "eventType": "rebalance",
                  "effectiveOrder": 0,
                  "effectiveAt": "2024-04-01T00:00:00Z",
                  "announcedAt": "2024-03-20T15:00:00Z",
                  "availableAt": "2024-03-20T15:04:00Z",
                  "status": "active",
                  "changes": [],
                  "sourceId": "SYNTH-NOTICE-003"
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "securityIds": [
            "SEC:E",
            "SEC:F",
            "SEC:G",
            "SEC:H",
            "SEC:I",
            "SEC:J"
          ],
          "appliedEventVersions": [
            "EV-001@1",
            "EV-002@1",
            "EV-003@1",
            "EV-004@1",
            "EV-005@1",
            "EV-006@1"
          ],
          "cancelledEventIds": []
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: status, securityIds, appliedEventVersions, cancelledEventIds"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f04-a01/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f04-a01/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f04-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Bitemporal reconstruction flow",
            "source": "flowchart LR\n    Q[\"Index ID, effectiveAt, knownAt\"] --> B[\"Latest eligible base revision\"]\n    Q --> E[\"Latest eligible revision per event\"]\n    B --> G{\"Complete ledger?\"}\n    E --> G\n    G -->|\"No base or gap\"| I[\"incomplete\"]\n    G -->|\"Overlap or conflict\"| A[\"ambiguous\"]\n    G -->|\"Unknown event semantics\"| U[\"unsupported\"]\n    G -->|\"Yes\"| P[\"Replay ordered changes\"]\n    P --> R[\"resolved roster and audit trace\"]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Resolution state lifecycle",
            "source": "stateDiagram-v2\n    [*] --> Validating\n    Validating --> Selecting: contract valid\n    Selecting --> Incomplete: no base or sequence gap\n    Selecting --> Ambiguous: competing evidence\n    Selecting --> Unsupported: unknown event type\n    Selecting --> Replaying: one complete ledger\n    Replaying --> Ambiguous: impossible add or delete\n    Replaying --> Resolved: ordered replay succeeds\n    Incomplete --> [*]\n    Ambiguous --> [*]\n    Unsupported --> [*]\n    Resolved --> [*]"
          }
        ]
      },
      "references": [
        {
          "key": "S01",
          "title": "Tesla Set to Join S&P 500",
          "author": null,
          "url": null
        },
        {
          "key": "S02",
          "title": "S&P DJI Announces Implementation of Tesla’s Addition to S&P 500",
          "author": null,
          "url": null
        },
        {
          "key": "S03",
          "title": "Tesla Set to Join S&P 500 & 100; Apartment Income REIT to Join S&P MidCap 400",
          "author": null,
          "url": null
        },
        {
          "key": "S04",
          "title": "FTSE Russell Corporate Actions and Events Guide",
          "author": null,
          "url": null
        },
        {
          "key": "S05",
          "title": "Subscribe to FTSE Russell index data",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/point-in-time-universe/historical-constituent-reconstruction/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/point-in-time-universe/historical-constituent-reconstruction/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F04-A02",
      "name": "Survivorship-Bias Guard",
      "headline": "Keep Historical Failures in the Test",
      "slug": "survivorship-bias-guard",
      "path": "corporate-actions-and-security-master-data/point-in-time-universe/survivorship-bias-guard",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F04",
        "family": "Point-in-Time Universe",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/point-in-time-universe/survivorship-bias-guard",
        "entry": "guardSurvivorship",
        "params": [
          "input"
        ],
        "exports": [
          "guardSurvivorship",
          "compareEqualWeightedReturns"
        ],
        "archetype": "row-classify",
        "signature": "guardSurvivorship(input)"
      },
      "api": {
        "summary": "Compares a universe you intend to test against the point-in-time roster and reports what is missing. It is a gate rather than a transform: the failure is the product.",
        "params": [
          {
            "name": "input",
            "type": "{ universeId: string; definitionId: string; effectiveAt: string; knownAt: string; candidateUniverse: object; universeDefinitions: object[]; membershipRecords: object[]; comparisonRoster: object }",
            "required": true,
            "description": "`candidateUniverse` is the roster under test — typically whatever a data pull returned — and `comparisonRoster` is the point-in-time truth to check it against.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, definitionVersion, candidateUniverseAsOf, missingSecurities, extraSecurities, … }",
          "description": "Which securities are missing from the candidate and which should not be there, with the definition version the comparison used."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the universe definition is unknown at knownAt",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(members)",
          "space": "O(members)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F04-A02.json",
        "call": "guardSurvivorship({\"universeId\":\"UNIVERSE:SYNTH:CORE\",\"definitionId\":\"DEF:SYNTH:CORE\",\"effectiveAt\":\"2023-12-31T23:59:59Z\",\"knownAt\":\"2024-01-02T12:00:00Z\",\"candidateUniverse\":{\"construction\":\"historical_membership_ledger\",\"asOf\":\"2023-12-31T23:59:59Z\",\"availableAt\":\"2024-01-02T10:00:00Z\",\"securityIds\":[\"SEC:A\",\"SEC:B\",\"SEC:C\",\"SEC:D\"],\"sourceId\":\"SYNTH-CANDIDATE-LEDGER\"},\"universeDefinitions\":[{\"definitionId\":\"DEF:SYNTH:CORE\",\"universeId\":\"UNIVERSE:SYNTH:CORE\",\"revision\":1,\"effectiveFrom\":\"2020-01-01T00:00:00Z\",\"effectiveTo\":null,\"announcedAt\":\"2019-12-15T12:00:00Z\",\"availableAt\":\"2019-12-15T12:05:00Z\",\"status\":\"active\",\"baseType\":\"named_research_universe\",\"baseId\":\"BASE:SYNTH:001\",\"ruleSummary\":\"Synthetic members documented by effective-dated membership evidence.\",\"sourceId\":\"SYNTH-DEFINITION-R1\"},{\"definitionId\":\"DEF:SYNTH:CORE\",\"universeId\":\"UNIVERSE:SYNTH:CORE\",\"revision\":2,\"effectiveFrom\":\"2020-01-01T00:00:00Z\",\"effectiveTo\":null,\"announcedAt\":\"2024-02-01T09:00:00Z\",\"availableAt\":\"2024-02-01T09:05:00Z\",\"status\":\"active\",\"baseType\":\"named_research_universe\",\"baseId\":\"BASE:SYNTH:001\",\"ruleSummary\":\"Later documentation revision; unavailable to the canonical query.\",\"sourceId\":\"SYNTH-DEFINITION-R2\"}],\"membershipRecords\":[{\"membershipId\":\"MEM-A\",\"revision\":1,\"universeId\":\"UNIVERSE:SYNTH:CORE\",\"securityId\":\"SEC:A\",\"validFrom\":\"2020-01-01T00:00:00Z\",\"validTo\":null,\"announcedAt\":\"2019-12-15T12:00:00Z\",\"availableAt\":\"2019-12-15T12:05:00Z\",\"status\":\"active\",\"changeType\":\"entry\",\"eventId\":\"EVENT-A-ENTRY\",\"sourceId\":\"SYNTH-MEM-A\"},{\"membershipId\":\"MEM-B\",\"revision\":1,\"universeId\":\"UNIVERSE:SYNTH:CORE\",\"securityId\":\"SEC:B\",\"validFrom\":\"2020-01-01T00:00:00Z\",\"validTo\":\"2024-06-01T00:00:00Z\",\"announcedAt\":\"2023-12-20T10:00:00Z\",\"availableAt\":\"2023-12-20T10:05:00Z\",\"status\":\"active\",\"changeType\":\"exit\",\"eventId\":\"EVENT-B-EXIT\",\"sourceId\":\"SYNTH-MEM-B-R1\"},{\"membershipId\":\"MEM-B\",\"revision\":2,\"universeId\":\"UNIVERSE:SYNTH:CORE\",\"securityId\":\"SEC:B\",\"validFrom\":\"2020-01-01T00:00:00Z\",\"validTo\":\"2023-12-15T00:00:00Z\",\"announcedAt\":\"2024-01-10T08:00:00Z\",\"availableAt\":\"2024-01-10T08:05:00Z\",\"status\":\"active\",\"changeType\":\"revision\",\"eventId\":\"EVENT-B-CORRECTION\",\"sourceId\":\"SYNTH-MEM-B-R2\"}],\"comparisonRoster\":{\"observedAt\":\"2025-01-02T00:00:00Z\",\"availableAt\":\"2025-01-02T12:00:00Z\",\"securityIds\":[\"SEC:A\",\"SEC:C\",\"SEC:D\"],\"sourceId\":\"SYNTH-CURRENT-ROSTER\"}})",
        "args": [
          {
            "value": {
              "universeId": "UNIVERSE:SYNTH:CORE",
              "definitionId": "DEF:SYNTH:CORE",
              "effectiveAt": "2023-12-31T23:59:59Z",
              "knownAt": "2024-01-02T12:00:00Z",
              "candidateUniverse": {
                "construction": "historical_membership_ledger",
                "asOf": "2023-12-31T23:59:59Z",
                "availableAt": "2024-01-02T10:00:00Z",
                "securityIds": [
                  "SEC:A",
                  "SEC:B",
                  "SEC:C",
                  "SEC:D"
                ],
                "sourceId": "SYNTH-CANDIDATE-LEDGER"
              },
              "universeDefinitions": [
                {
                  "definitionId": "DEF:SYNTH:CORE",
                  "universeId": "UNIVERSE:SYNTH:CORE",
                  "revision": 1,
                  "effectiveFrom": "2020-01-01T00:00:00Z",
                  "effectiveTo": null,
                  "announcedAt": "2019-12-15T12:00:00Z",
                  "availableAt": "2019-12-15T12:05:00Z",
                  "status": "active",
                  "baseType": "named_research_universe",
                  "baseId": "BASE:SYNTH:001",
                  "ruleSummary": "Synthetic members documented by effective-dated membership evidence.",
                  "sourceId": "SYNTH-DEFINITION-R1"
                },
                {
                  "definitionId": "DEF:SYNTH:CORE",
                  "universeId": "UNIVERSE:SYNTH:CORE",
                  "revision": 2,
                  "effectiveFrom": "2020-01-01T00:00:00Z",
                  "effectiveTo": null,
                  "announcedAt": "2024-02-01T09:00:00Z",
                  "availableAt": "2024-02-01T09:05:00Z",
                  "status": "active",
                  "baseType": "named_research_universe",
                  "baseId": "BASE:SYNTH:001",
                  "ruleSummary": "Later documentation revision; unavailable to the canonical query.",
                  "sourceId": "SYNTH-DEFINITION-R2"
                }
              ],
              "membershipRecords": [
                {
                  "membershipId": "MEM-A",
                  "revision": 1,
                  "universeId": "UNIVERSE:SYNTH:CORE",
                  "securityId": "SEC:A",
                  "validFrom": "2020-01-01T00:00:00Z",
                  "validTo": null,
                  "announcedAt": "2019-12-15T12:00:00Z",
                  "availableAt": "2019-12-15T12:05:00Z",
                  "status": "active",
                  "changeType": "entry",
                  "eventId": "EVENT-A-ENTRY",
                  "sourceId": "SYNTH-MEM-A"
                },
                {
                  "membershipId": "MEM-B",
                  "revision": 1,
                  "universeId": "UNIVERSE:SYNTH:CORE",
                  "securityId": "SEC:B",
                  "validFrom": "2020-01-01T00:00:00Z",
                  "validTo": "2024-06-01T00:00:00Z",
                  "announcedAt": "2023-12-20T10:00:00Z",
                  "availableAt": "2023-12-20T10:05:00Z",
                  "status": "active",
                  "changeType": "exit",
                  "eventId": "EVENT-B-EXIT",
                  "sourceId": "SYNTH-MEM-B-R1"
                },
                {
                  "membershipId": "MEM-B",
                  "revision": 2,
                  "universeId": "UNIVERSE:SYNTH:CORE",
                  "securityId": "SEC:B",
                  "validFrom": "2020-01-01T00:00:00Z",
                  "validTo": "2023-12-15T00:00:00Z",
                  "announcedAt": "2024-01-10T08:00:00Z",
                  "availableAt": "2024-01-10T08:05:00Z",
                  "status": "active",
                  "changeType": "revision",
                  "eventId": "EVENT-B-CORRECTION",
                  "sourceId": "SYNTH-MEM-B-R2"
                }
              ],
              "comparisonRoster": {
                "observedAt": "2025-01-02T00:00:00Z",
                "availableAt": "2025-01-02T12:00:00Z",
                "securityIds": [
                  "SEC:A",
                  "SEC:C",
                  "SEC:D"
                ],
                "sourceId": "SYNTH-CURRENT-ROSTER"
              }
            },
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "definitionVersion": "DEF:SYNTH:CORE@1",
          "eligibleSecurityIds": [
            "SEC:A",
            "SEC:B",
            "SEC:C"
          ],
          "ineligibleSecurityIds": [
            "SEC:D"
          ],
          "unknownSecurityIds": [],
          "ambiguousSecurityIds": [],
          "hindsightDiagnostics": {
            "historicallyEligibleMissingFromCurrent": [
              "SEC:B"
            ],
            "currentRosterNotHistoricallyEligible": [
              "SEC:D"
            ],
            "retentionRatio": 0.666667
          }
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: status, definitionVersion, eligibleSecurityIds, ineligibleSecurityIds, unknownSecurityIds, ambiguousSecurityIds, hindsightDiagnostics"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f04-a02/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f04-a02/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f04-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Causal membership and hindsight diagnostics",
            "source": "flowchart LR\n    Q[\"effectiveAt and knownAt\"] --> A[\"Rows available by knownAt\"]\n    A --> V[\"Validate revision prefixes\"]\n    V --> D[\"Resolve supported definition\"]\n    D --> C{\"Historical candidate ledger complete?\"}\n    C -->|No| I[\"Incomplete\"]\n    C -->|Yes| M[\"Classify membership intervals\"]\n    M --> R[\"Causal result\"]\n    R -.-> H[\"Non-causal later-roster diagnostic\"]\n    R -.-> P[\"Synthetic-only return illustration\"]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Membership classification states",
            "source": "stateDiagram-v2\n    [*] --> SelectKnownVersions\n    SelectKnownVersions --> Eligible: exactly one interval covers effectiveAt\n    SelectKnownVersions --> Ineligible: active evidence excludes effectiveAt\n    SelectKnownVersions --> Unknown: no active evidence available\n    SelectKnownVersions --> Ambiguous: multiple intervals cover effectiveAt\n    Eligible --> Resolved\n    Ineligible --> Resolved\n    Unknown --> NeedsEvidence\n    Ambiguous --> NeedsReconciliation"
          }
        ]
      },
      "references": [
        {
          "key": "R1 - S&P Dow Jones Indices Equity Indices Policies & Practices",
          "title": "R1 - S&P Dow Jones Indices Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": null
        },
        {
          "key": "R2 - Lehman Brothers Form 8-K: Chapter 11 filing",
          "title": "R2 - Lehman Brothers Form 8-K: Chapter 11 filing",
          "author": "Lehman Brothers Holdings Inc., filed with the U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "R3 - Lehman Brothers Form 8-K: NYSE suspension",
          "title": "R3 - Lehman Brothers Form 8-K: NYSE suspension",
          "author": "Lehman Brothers Holdings Inc., filed with the U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "R4 - S&P 150 comparison",
          "title": "R4 - S&P 150 comparison",
          "author": "S&P Dow Jones Indices",
          "url": null
        },
        {
          "key": "R5 - CRSP Research Data Products",
          "title": "R5 - CRSP Research Data Products",
          "author": "Center for Research in Security Prices",
          "url": null
        },
        {
          "key": "R6 - CRSP PERMNO and PERMCO",
          "title": "R6 - CRSP PERMNO and PERMCO",
          "author": "Center for Research in Security Prices",
          "url": null
        },
        {
          "key": "R7 - CRSP10 US Stock Database Guide",
          "title": "R7 - CRSP10 US Stock Database Guide",
          "author": "Center for Research in Security Prices",
          "url": null
        },
        {
          "key": "R8 - SEC EDGAR access guidance",
          "title": "R8 - SEC EDGAR access guidance",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/point-in-time-universe/survivorship-bias-guard/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/point-in-time-universe/survivorship-bias-guard/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F04-A03",
      "name": "IPO Availability Timestamping",
      "headline": "Separate Listing Events from Research Knowledge",
      "slug": "ipo-availability-timestamping",
      "path": "corporate-actions-and-security-master-data/point-in-time-universe/ipo-availability-timestamping",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F04",
        "family": "Point-in-Time Universe",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/point-in-time-universe/ipo-availability-timestamping",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Decides when a newly listed security first became usable — not when it was listed, but when enough history existed to satisfy the policy a strategy actually applies.",
        "params": [
          {
            "name": "data",
            "type": "{ query: object; policies: Policy[]; records: Record[] }",
            "required": true,
            "description": "`policies` states the seasoning rules — minimum trading days, minimum float, minimum liquidity — so the availability date follows from a declared rule rather than a hard-coded constant.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ effectiveAt, knownAt, identity, policyId, status, policySatisfied, effectiveGateAt, … }",
          "description": "The date the security became eligible under the named policy, plus which gate was the binding one."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the referenced policy does not exist",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(records)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F04-A03.json",
        "call": "calculate({\"query\":{\"issuerId\":\"ISSUER-SYN-001\",\"instrumentId\":\"INSTRUMENT-SYN-001\",\"listingId\":\"LISTING-SYN-XNAS\",\"effectiveAt\":\"2025-05-13T13:36:10Z\",\"knownAt\":\"2025-05-13T13:36:10Z\",\"policyId\":\"POLICY-SYN-IPO-RESEARCH\"},\"policies\":[{\"policyId\":\"POLICY-SYN-IPO-RESEARCH\",\"revision\":1,\"state\":\"active\",\"effectiveAt\":\"2025-05-01T00:00:00Z\",\"availableAt\":\"2025-05-01T00:05:00Z\",\"sourceId\":\"SYN-RESEARCH-GOVERNANCE\",\"context\":\"traditional_ipo\",\"marketPhase\":\"regular\",\"requiredEventTypes\":[\"registration_effective\",\"listing_notice\",\"first_eligible_session\",\"first_observed_trade\",\"vendor_release\",\"local_ingestion\"]},{\"policyId\":\"POLICY-SYN-IPO-RESEARCH\",\"revision\":2,\"state\":\"active\",\"effectiveAt\":\"2025-05-01T00:00:00Z\",\"availableAt\":\"2025-05-14T09:00:00Z\",\"sourceId\":\"SYN-RESEARCH-GOVERNANCE\",\"context\":\"traditional_ipo\",\"marketPhase\":\"regular\",\"requiredEventTypes\":[\"registration_effective\",\"listing_notice\",\"first_eligible_session\",\"first_observed_quote\",\"first_observed_trade\",\"vendor_release\"]}],\"records\":[{\"eventId\":\"EV-FILING\",\"revision\":1,\"state\":\"active\",\"eventType\":\"issuer_filing\",\"issuerId\":\"ISSUER-SYN-001\",\"instrumentId\":\"INSTRUMENT-SYN-001\",\"listingId\":\"LISTING-SYN-XNAS\",\"marketPhase\":\"all\",\"effectiveAt\":\"2025-05-05T14:00:00Z\",\"availableAt\":\"2025-05-05T14:03:00Z\",\"clockOwner\":\"regulator\",\"sourceId\":\"SYN-REGULATOR-FILING\"},{\"eventId\":\"EV-EFFECT\",\"revision\":1,\"state\":\"active\",\"eventType\":\"registration_effective\",\"issuerId\":\"ISSUER-SYN-001\",\"instrumentId\":\"INSTRUMENT-SYN-001\",\"listingId\":\"LISTING-SYN-XNAS\",\"marketPhase\":\"all\",\"effectiveAt\":\"2025-05-08T12:00:00Z\",\"availableAt\":\"2025-05-08T12:02:00Z\",\"clockOwner\":\"regulator\",\"sourceId\":\"SYN-REGULATOR-EFFECT\"},{\"eventId\":\"EV-LIST\",\"revision\":1,\"state\":\"active\",\"eventType\":\"listing_notice\",\"issuerId\":\"ISSUER-SYN-001\",\"instrumentId\":\"INSTRUMENT-SYN-001\",\"listingId\":\"LISTING-SYN-XNAS\",\"marketPhase\":\"all\",\"effectiveAt\":\"2025-05-13T13:30:00Z\",\"availableAt\":\"2025-05-08T15:10:00Z\",\"clockOwner\":\"exchange\",\"sourceId\":\"SYN-EXCHANGE-NOTICE\"}]})",
        "args": [
          {
            "value": {
              "query": {
                "issuerId": "ISSUER-SYN-001",
                "instrumentId": "INSTRUMENT-SYN-001",
                "listingId": "LISTING-SYN-XNAS",
                "effectiveAt": "2025-05-13T13:36:10Z",
                "knownAt": "2025-05-13T13:36:10Z",
                "policyId": "POLICY-SYN-IPO-RESEARCH"
              },
              "policies": [
                {
                  "policyId": "POLICY-SYN-IPO-RESEARCH",
                  "revision": 1,
                  "state": "active",
                  "effectiveAt": "2025-05-01T00:00:00Z",
                  "availableAt": "2025-05-01T00:05:00Z",
                  "sourceId": "SYN-RESEARCH-GOVERNANCE",
                  "context": "traditional_ipo",
                  "marketPhase": "regular",
                  "requiredEventTypes": [
                    "registration_effective",
                    "listing_notice",
                    "first_eligible_session",
                    "first_observed_trade",
                    "vendor_release",
                    "local_ingestion"
                  ]
                },
                {
                  "policyId": "POLICY-SYN-IPO-RESEARCH",
                  "revision": 2,
                  "state": "active",
                  "effectiveAt": "2025-05-01T00:00:00Z",
                  "availableAt": "2025-05-14T09:00:00Z",
                  "sourceId": "SYN-RESEARCH-GOVERNANCE",
                  "context": "traditional_ipo",
                  "marketPhase": "regular",
                  "requiredEventTypes": [
                    "registration_effective",
                    "listing_notice",
                    "first_eligible_session",
                    "first_observed_quote",
                    "first_observed_trade",
                    "vendor_release"
                  ]
                }
              ],
              "records": [
                {
                  "eventId": "EV-FILING",
                  "revision": 1,
                  "state": "active",
                  "eventType": "issuer_filing",
                  "issuerId": "ISSUER-SYN-001",
                  "instrumentId": "INSTRUMENT-SYN-001",
                  "listingId": "LISTING-SYN-XNAS",
                  "marketPhase": "all",
                  "effectiveAt": "2025-05-05T14:00:00Z",
                  "availableAt": "2025-05-05T14:03:00Z",
                  "clockOwner": "regulator",
                  "sourceId": "SYN-REGULATOR-FILING"
                },
                {
                  "eventId": "EV-EFFECT",
                  "revision": 1,
                  "state": "active",
                  "eventType": "registration_effective",
                  "issuerId": "ISSUER-SYN-001",
                  "instrumentId": "INSTRUMENT-SYN-001",
                  "listingId": "LISTING-SYN-XNAS",
                  "marketPhase": "all",
                  "effectiveAt": "2025-05-08T12:00:00Z",
                  "availableAt": "2025-05-08T12:02:00Z",
                  "clockOwner": "regulator",
                  "sourceId": "SYN-REGULATOR-EFFECT"
                },
                {
                  "eventId": "EV-LIST",
                  "revision": 1,
                  "state": "active",
                  "eventType": "listing_notice",
                  "issuerId": "ISSUER-SYN-001",
                  "instrumentId": "INSTRUMENT-SYN-001",
                  "listingId": "LISTING-SYN-XNAS",
                  "marketPhase": "all",
                  "effectiveAt": "2025-05-13T13:30:00Z",
                  "availableAt": "2025-05-08T15:10:00Z",
                  "clockOwner": "exchange",
                  "sourceId": "SYN-EXCHANGE-NOTICE"
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "effectiveGateAt": "2025-05-13T13:36:00Z",
          "knowledgeGateAt": "2025-05-13T13:36:05Z",
          "missingEventTypes": []
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: status, effectiveGateAt, knowledgeGateAt, missingEventTypes"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f04-a03/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f04-a03/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f04-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Causal IPO evidence flow",
            "source": "flowchart TD\n    Q[\"Query: identity, effectiveAt, knownAt, policyId\"] --> P[\"Keep policy revisions available by knownAt\"]\n    P --> PA{\"Applicable active policy?\"}\n    PA -->|No| MI[\"Incomplete: missing policy\"]\n    PA -->|Yes| E[\"Keep event revisions available by knownAt\"]\n    E --> V[\"Validate known immutable revision chains\"]\n    V --> I[\"Match issuer, instrument, listing, and market phase\"]\n    I --> R{\"Required clocks resolved and effective?\"}\n    R -->|Missing or cancelled| INC[\"Incomplete\"]\n    R -->|Conflicting timestamps| AMB[\"Ambiguous\"]\n    R -->|Unsupported policy semantic| UNS[\"Unsupported\"]\n    R -->|Yes| G[\"Resolved: effective gate plus knowledge gate\"]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "IPO evidence query state lifecycle",
            "source": "stateDiagram-v2\n    [*] --> SelectPolicy\n    SelectPolicy --> Incomplete: policy missing or cancelled\n    SelectPolicy --> SelectEvidence: policy active and applicable\n    SelectEvidence --> Incomplete: required evidence missing, cancelled, or future-effective\n    SelectEvidence --> Ambiguous: required timestamps or identity links conflict\n    SelectEvidence --> Unsupported: policy semantic does not fit listing context\n    SelectEvidence --> Resolved: every required clock effective and known\n    Resolved --> LaterKnownQuery: correction becomes available\n    LaterKnownQuery --> SelectPolicy\n    Incomplete --> [*]\n    Ambiguous --> [*]\n    Unsupported --> [*]\n    Resolved --> [*]"
          }
        ]
      },
      "references": [
        {
          "key": "R1 - SEC: Determine the Status of My Filing",
          "title": "R1 - SEC: Determine the Status of My Filing",
          "author": null,
          "url": null
        },
        {
          "key": "R2 - SEC: Webmaster Frequently Asked Questions",
          "title": "R2 - SEC: Webmaster Frequently Asked Questions",
          "author": null,
          "url": null
        },
        {
          "key": "R3 - Airbnb 2020 Form 10-K",
          "title": "R3 - Airbnb 2020 Form 10-K",
          "author": null,
          "url": null
        },
        {
          "key": "R4 - Airbnb final prospectus filing index",
          "title": "R4 - Airbnb final prospectus filing index",
          "author": null,
          "url": null
        },
        {
          "key": "R5 - Airbnb pricing announcement hosted by Nasdaq",
          "title": "R5 - Airbnb pricing announcement hosted by Nasdaq",
          "author": null,
          "url": null
        },
        {
          "key": "R6 - Nasdaq Listing Rule IM-5315-1",
          "title": "R6 - Nasdaq Listing Rule IM-5315-1",
          "author": null,
          "url": null
        },
        {
          "key": "R7 - Nasdaq Daily List product description",
          "title": "R7 - Nasdaq Daily List product description",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/point-in-time-universe/ipo-availability-timestamping/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/point-in-time-universe/ipo-availability-timestamping/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F04-A04",
      "name": "Filing-Revision Versioning",
      "headline": null,
      "slug": "filing-revision-versioning",
      "path": "corporate-actions-and-security-master-data/point-in-time-universe/filing-revision-versioning",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F04",
        "family": "Point-in-Time Universe",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/point-in-time-universe/filing-revision-versioning",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Selects the version of a financial filing that was current at a knowledge time. Companies restate; using the final restated figure in a backtest means trading on numbers nobody had.",
        "params": [
          {
            "name": "data",
            "type": "{ entityId: string; reportPeriod: string; formFamily: string; asOf: string; records: FilingRecord[] }",
            "required": true,
            "description": "`records` is the full filing and amendment history for the period. `asOf` is the knowledge time — the amendment that superseded a figure last week was not available a month ago.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ entityId, reportPeriod, asOf, selectionBasis, accessionNo, form, amendmentNumber, acceptedAt, … }",
          "description": "The selected filing with its accession number and acceptance time, and the basis on which it was chosen."
        },
        "warmup": null,
        "errors": [
          {
            "when": "no filing exists for the period at asOf",
            "behaviour": "reported on the result rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(records)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D02-F04-A04.json",
        "call": "calculate({\"entityId\":\"CIK0000033619\",\"reportPeriod\":\"2017-09-29\",\"formFamily\":\"10-K\",\"asOf\":\"2018-02-01T00:00:00Z\",\"records\":[{\"entityId\":\"CIK0000033619\",\"reportPeriod\":\"2017-09-29\",\"form\":\"10-K\",\"accessionNo\":\"0001564590-17-024189\",\"amendmentNumber\":0,\"acceptedAt\":\"2017-11-21T16:32:41Z\",\"ingestedAt\":\"2017-11-21T16:40:00Z\",\"amendmentScope\":[\"Original annual filing\"],\"facts\":{\"basicEpsUsdPerShare\":3.94,\"netEarningsUsdMillions\":117.387}},{\"entityId\":\"CIK0000033619\",\"reportPeriod\":\"2017-09-29\",\"form\":\"10-K/A\",\"accessionNo\":\"0001564590-18-007244\",\"amendmentNumber\":1,\"acceptedAt\":\"2018-03-30T14:43:54Z\",\"ingestedAt\":\"2018-03-30T15:00:00Z\",\"amendmentScope\":[\"Item 6\",\"Item 7\",\"Item 8\",\"Item 9A\",\"Item 15\"],\"facts\":{\"basicEpsUsdPerShare\":3.75,\"netEarningsUsdMillions\":111.554}}]})",
        "args": [
          {
            "value": {
              "entityId": "CIK0000033619",
              "reportPeriod": "2017-09-29",
              "formFamily": "10-K",
              "asOf": "2018-02-01T00:00:00Z",
              "records": [
                {
                  "entityId": "CIK0000033619",
                  "reportPeriod": "2017-09-29",
                  "form": "10-K",
                  "accessionNo": "0001564590-17-024189",
                  "amendmentNumber": 0,
                  "acceptedAt": "2017-11-21T16:32:41Z",
                  "ingestedAt": "2017-11-21T16:40:00Z",
                  "amendmentScope": [
                    "Original annual filing"
                  ],
                  "facts": {
                    "basicEpsUsdPerShare": 3.94,
                    "netEarningsUsdMillions": 117.387
                  }
                },
                {
                  "entityId": "CIK0000033619",
                  "reportPeriod": "2017-09-29",
                  "form": "10-K/A",
                  "accessionNo": "0001564590-18-007244",
                  "amendmentNumber": 1,
                  "acceptedAt": "2018-03-30T14:43:54Z",
                  "ingestedAt": "2018-03-30T15:00:00Z",
                  "amendmentScope": [
                    "Item 6",
                    "Item 7",
                    "Item 8",
                    "Item 9A",
                    "Item 15"
                  ],
                  "facts": {
                    "basicEpsUsdPerShare": 3.75,
                    "netEarningsUsdMillions": 111.554
                  }
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "entityId": "CIK0000033619",
          "reportPeriod": "2017-09-29",
          "asOf": "2018-02-01T00:00:00Z",
          "selectionBasis": "latest accepted filing among locally ingested versions",
          "accessionNo": "0001564590-17-024189",
          "form": "10-K",
          "amendmentNumber": 0,
          "acceptedAt": "2017-11-21T16:32:41Z",
          "ingestedAt": "2017-11-21T16:40:00Z",
          "amendmentScope": [
            "Original annual filing"
          ],
          "facts": {
            "basicEpsUsdPerShare": 3.94,
            "netEarningsUsdMillions": 117.387
          },
          "eligibleAccessions": [
            "0001564590-17-024189"
          ],
          "excludedNotYetIngested": [
            "0001564590-18-007244"
          ]
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: entityId, reportPeriod, asOf, selectionBasis, accessionNo, form, amendmentNumber, acceptedAt, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d02-f04-a04/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d02-f04-a04/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d02-f04-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Causal filing-version query",
            "source": "flowchart LR\n    A[\"Immutable filing versions\"] --> B[\"Validate identity and timestamps\"]\n    B --> C{\"ingestedAt <= asOf?\"}\n    C -->|No| D[\"Exclude and report\"]\n    C -->|Yes| E[\"Order by acceptedAt, amendment, accession\"]\n    E --> F[\"Return selected version and audit trace\"]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "Filing-version lifecycle",
            "source": "stateDiagram-v2\n    [*] --> Submitted\n    Submitted --> Accepted: EDGAR accepts\n    Accepted --> Ingested: local system acquires\n    Ingested --> Validated: parser and checks complete\n    Validated --> Eligible: cutoff reaches policy timestamp\n    Accepted --> Excluded: cutoff before local ingestion\n    Eligible --> Superseded: later eligible amendment\n    Superseded --> [*]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "Esterline fiscal-2017 original Form 10-K filing index",
          "author": null,
          "url": null
        },
        {
          "key": "R2",
          "title": "Esterline fiscal-2017 Form 10-K/A filing index",
          "author": null,
          "url": null
        },
        {
          "key": "R3",
          "title": "Esterline fiscal-2017 Form 10-K/A",
          "author": null,
          "url": null
        },
        {
          "key": "R4",
          "title": "SEC Webmaster Frequently Asked Questions",
          "author": null,
          "url": null
        },
        {
          "key": "R5",
          "title": "Accessing EDGAR Data",
          "author": null,
          "url": null
        },
        {
          "key": "R6",
          "title": "EDGAR glossary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/point-in-time-universe/filing-revision-versioning/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/point-in-time-universe/filing-revision-versioning/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D02-F04-A05",
      "name": "Corporate-Action Status and Effective-Date Reconciliation",
      "headline": null,
      "slug": "corporate-action-status-and-effective-date-reconciliation",
      "path": "corporate-actions-and-security-master-data/point-in-time-universe/corporate-action-status-and-effective-date-reconciliation",
      "taxonomy": {
        "domainId": "D02",
        "domain": "Corporate Actions and Security Master Data",
        "familyId": "D02-F04",
        "family": "Point-in-Time Universe",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/corporate-actions-and-security-master-data/point-in-time-universe/corporate-action-status-and-effective-date-reconciliation",
        "entry": "reconcileCorporateAction",
        "params": [
          "input"
        ],
        "exports": [
          "reconcileCorporateAction"
        ],
        "archetype": "record-transform",
        "signature": "reconcileCorporateAction(input)"
      },
      "api": {
        "summary": "Reconstructs the highest-authority corporate-action state knowable at an as-of time while preserving conflicts and terminal messages.",
        "params": [
          {
            "name": "input",
            "type": "object",
            "required": true,
            "description": "Topic-specific point-in-time audit contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "object",
          "description": "Structured state, audit rows, diagnostics, and provenance."
        },
        "warmup": null,
        "errors": [],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "reconcileCorporateAction({\"event_reference\":\"CA-77\",\"security_id\":\"SYNTH-XYZ\",\"event_type\":\"stock-split\",\"as_of\":\"2026-07-05T12:00:00Z\",\"records\":[{\"message_id\":\"P-1\",\"event_reference\":\"CA-77\",\"security_id\":\"SYNTH-XYZ\",\"event_type\":\"stock-split\",\"source\":\"provider-feed\",\"source_rank\":1,\"version\":1,\"available_at\":\"2026-07-01T09:00:00Z\",\"announcement_date\":\"2026-07-01\",\"effective_date\":\"2026-07-15\",\"status\":\"preliminary\",\"function\":\"new\",\"supersedes\":null},{\"message_id\":\"E-1\",\"event_reference\":\"CA-77\",\"security_id\":\"SYNTH-XYZ\",\"event_type\":\"stock-split\",\"source\":\"exchange-notice\",\"source_rank\":2,\"version\":1,\"available_at\":\"2026-07-03T11:00:00Z\",\"announcement_date\":\"2026-07-01\",\"effective_date\":\"2026-07-16\",\"status\":\"confirmed\",\"function\":\"new\",\"supersedes\":null},{\"message_id\":\"I-2\",\"event_reference\":\"CA-77\",\"security_id\":\"SYNTH-XYZ\",\"event_type\":\"stock-split\",\"source\":\"issuer-notice\",\"source_rank\":3,\"version\":2,\"available_at\":\"2026-07-04T09:00:00Z\",\"announcement_date\":\"2026-07-01\",\"effective_date\":\"2026-07-16\",\"status\":\"confirmed\",\"function\":\"replacement\",\"supersedes\":\"I-1\"}]})",
        "args": [
          {
            "value": {
              "event_reference": "CA-77",
              "security_id": "SYNTH-XYZ",
              "event_type": "stock-split",
              "as_of": "2026-07-05T12:00:00Z",
              "records": [
                {
                  "message_id": "P-1",
                  "event_reference": "CA-77",
                  "security_id": "SYNTH-XYZ",
                  "event_type": "stock-split",
                  "source": "provider-feed",
                  "source_rank": 1,
                  "version": 1,
                  "available_at": "2026-07-01T09:00:00Z",
                  "announcement_date": "2026-07-01",
                  "effective_date": "2026-07-15",
                  "status": "preliminary",
                  "function": "new",
                  "supersedes": null
                },
                {
                  "message_id": "E-1",
                  "event_reference": "CA-77",
                  "security_id": "SYNTH-XYZ",
                  "event_type": "stock-split",
                  "source": "exchange-notice",
                  "source_rank": 2,
                  "version": 1,
                  "available_at": "2026-07-03T11:00:00Z",
                  "announcement_date": "2026-07-01",
                  "effective_date": "2026-07-16",
                  "status": "confirmed",
                  "function": "new",
                  "supersedes": null
                },
                {
                  "message_id": "I-2",
                  "event_reference": "CA-77",
                  "security_id": "SYNTH-XYZ",
                  "event_type": "stock-split",
                  "source": "issuer-notice",
                  "source_rank": 3,
                  "version": 2,
                  "available_at": "2026-07-04T09:00:00Z",
                  "announcement_date": "2026-07-01",
                  "effective_date": "2026-07-16",
                  "status": "confirmed",
                  "function": "replacement",
                  "supersedes": "I-1"
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "event_reference": "CA-77",
          "security_id": "SYNTH-XYZ",
          "event_type": "stock-split",
          "as_of": "2026-07-05T12:00:00Z",
          "state": "reconciled-with-conflicts",
          "selected": {
            "message_id": "I-2",
            "source": "issuer-notice",
            "source_rank": 3,
            "version": 2,
            "available_at": "2026-07-04T09:00:00Z",
            "announcement_date": "2026-07-01",
            "effective_date": "2026-07-16",
            "status": "confirmed",
            "function": "replacement",
            "supersedes": "I-1"
          },
          "applicable": false,
          "conflicts": [
            {
              "type": "status-conflict",
              "selected": "confirmed",
              "other": "preliminary",
              "other_source": "provider-feed"
            },
            {
              "type": "effective-date-conflict",
              "selected": "2026-07-16",
              "other": "2026-07-15",
              "other_source": "provider-feed"
            }
          ],
          "eligible_message_ids": [
            "E-1",
            "I-2",
            "P-1"
          ],
          "future_message_ids": []
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: event_reference, security_id, event_type, as_of, state, selected, applicable, conflicts, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d02-f04-a05/static/system-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "system-flow.md",
            "caption": "Corporate-action reconciliation flow",
            "source": "flowchart LR\n    A[\"Versioned source messages\"] --> B[\"Filter available_at ≤ as_of\"]\n    B --> C[\"Select latest message per source\"]\n    C --> D[\"Rank governed source heads\"]\n    D --> E{\"Equal-rank disagreement?\"}\n    E -->|Yes| F[\"Unresolved authority tie\"]\n    E -->|No| G[\"Select highest authority\"]\n    G --> H[\"Retain status and effective-date conflicts\"]\n    H --> I{\"Terminal, incomplete, or future?\"}\n    I -->|Yes| J[\"Block application\"]\n    I -->|No| K[\"Applicable event state\"]\n    K --> L[\"Audit invariant: no future message enters the selected state\"]"
          }
        ]
      },
      "references": [
        {
          "key": "S1",
          "title": "ISO 15022 MT 564 scope",
          "author": null,
          "url": null
        },
        {
          "key": "S2",
          "title": "ISO 15022 MT 564 field 23G",
          "author": null,
          "url": null
        },
        {
          "key": "S3",
          "title": "ISO 15022 MT 564 field 20C",
          "author": null,
          "url": null
        },
        {
          "key": "S4",
          "title": "ISO 15022 MT 564 field 98a",
          "author": null,
          "url": null
        },
        {
          "key": "S5",
          "title": "FINRA Rule 11140",
          "author": null,
          "url": null
        },
        {
          "key": "Publication decision",
          "title": "Publication decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/corporate-actions-and-security-master-data/point-in-time-universe/corporate-action-status-and-effective-date-reconciliation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/corporate-actions-and-security-master-data/point-in-time-universe/corporate-action-status-and-effective-date-reconciliation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F01-A01",
      "name": "Base-Date/Base-Value Initialization",
      "headline": null,
      "slug": "base-date-base-value-initialization",
      "path": "index-and-benchmark-engineering/index-initialization-and-continuity/base-date-base-value-initialization",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F01",
        "family": "Index Initialization and Continuity",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/index-initialization-and-continuity/base-date-base-value-initialization",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Sets an index running: pick a base date and a base level, and the divisor follows from the market value on that date. Everything else in index construction is maintenance of this one relationship.",
        "params": [
          {
            "name": "data",
            "type": "{ constituents: Constituent[]; baseLevel: number; baseDate: string }",
            "required": true,
            "description": "`constituents` supply the market value at the base date. `baseLevel` is an arbitrary convention — 100 and 1000 are both common — and only fixes the scale.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ marketValue, divisor, indexLevel }",
          "description": "The base market value, the divisor derived from it, and the level — which by construction equals `baseLevel` on day one."
        },
        "warmup": null,
        "errors": [
          {
            "when": "baseLevel is not positive or the market value is zero",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F01-A01.json",
        "call": "calculate({\"constituents\":[{\"id\":\"ALFA\",\"price\":50,\"shares\":1000,\"floatFactor\":0.8,\"fx\":1},{\"id\":\"BETA\",\"price\":80,\"shares\":600,\"floatFactor\":0.75,\"fx\":1},{\"id\":\"GAMMA\",\"price\":40,\"shares\":1200,\"floatFactor\":0.9,\"fx\":1}],\"baseLevel\":1000,\"baseDate\":\"2026-01-02\"})",
        "args": [
          {
            "value": {
              "constituents": [
                {
                  "id": "ALFA",
                  "price": 50,
                  "shares": 1000,
                  "floatFactor": 0.8,
                  "fx": 1
                },
                {
                  "id": "BETA",
                  "price": 80,
                  "shares": 600,
                  "floatFactor": 0.75,
                  "fx": 1
                },
                {
                  "id": "GAMMA",
                  "price": 40,
                  "shares": 1200,
                  "floatFactor": 0.9,
                  "fx": 1
                }
              ],
              "baseLevel": 1000,
              "baseDate": "2026-01-02"
            },
            "elided": null
          }
        ],
        "output": {
          "marketValue": 119200,
          "divisor": 119.2,
          "indexLevel": 1000
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: marketValue, divisor, indexLevel"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a01/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a01/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Base-Date/Base-Value Initialization calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Base-Date/Base-Value Initialization\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Base-Date/Base-Value Initialization methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/index-initialization-and-continuity/base-date-base-value-initialization/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/index-initialization-and-continuity/base-date-base-value-initialization/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F01-A02",
      "name": "Index Divisor Initialization",
      "headline": null,
      "slug": "index-divisor-initialization",
      "path": "index-and-benchmark-engineering/index-initialization-and-continuity/index-divisor-initialization",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F01",
        "family": "Index Initialization and Continuity",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/index-initialization-and-continuity/index-divisor-initialization",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "The divisor itself: market value divided by the target level. Small, and the number every other calculation in this domain is defined against.",
        "params": [
          {
            "name": "data",
            "type": "{ marketValue: number; baseLevel: number }",
            "required": true,
            "description": "Total market value and the level it should represent.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ marketValue, divisor, indexLevel }",
          "description": "The divisor and the level it produces, echoed back for checking."
        },
        "warmup": null,
        "errors": [
          {
            "when": "baseLevel is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F01-A02.json",
        "call": "calculate({\"marketValue\":125000000,\"baseLevel\":1000})",
        "args": [
          {
            "value": {
              "marketValue": 125000000,
              "baseLevel": 1000
            },
            "elided": null
          }
        ],
        "output": {
          "marketValue": 125000000,
          "divisor": 125000,
          "indexLevel": 1000
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: marketValue, divisor, indexLevel"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a02/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a02/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Index Divisor Initialization calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Index Divisor Initialization\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Index Divisor Initialization methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/index-initialization-and-continuity/index-divisor-initialization/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/index-initialization-and-continuity/index-divisor-initialization/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F01-A03",
      "name": "Divisor Continuity Adjustment",
      "headline": null,
      "slug": "divisor-continuity-adjustment",
      "path": "index-and-benchmark-engineering/index-initialization-and-continuity/divisor-continuity-adjustment",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F01",
        "family": "Index Initialization and Continuity",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/index-initialization-and-continuity/divisor-continuity-adjustment",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Rescales the divisor when market value changes for a non-market reason — a share issue, a member swap — so the level does not jump. This is the mechanism that makes an index a continuous series rather than a sum of unrelated numbers.",
        "params": [
          {
            "name": "data",
            "type": "{ oldMarketValue: number; newMarketValue: number; oldDivisor: number }",
            "required": true,
            "description": "The market value immediately before and after the change, and the divisor in force before it. Both values must be measured at the same prices — a divisor adjustment that also absorbs a price move is the classic error.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ oldLevel, newDivisor, bridgedLevel, continuityError }",
          "description": "The new divisor plus `continuityError` — the residual difference between the level before and after. It should be zero or floating-point dust; anything larger means the inputs were not measured at the same instant."
        },
        "warmup": null,
        "errors": [
          {
            "when": "any market value or divisor is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F01-A03.json",
        "call": "calculate({\"oldMarketValue\":100000000,\"newMarketValue\":112000000,\"oldDivisor\":100000})",
        "args": [
          {
            "value": {
              "oldMarketValue": 100000000,
              "newMarketValue": 112000000,
              "oldDivisor": 100000
            },
            "elided": null
          }
        ],
        "output": {
          "oldLevel": 1000,
          "newDivisor": 112000,
          "bridgedLevel": 1000,
          "continuityError": 0
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: oldLevel, newDivisor, bridgedLevel, continuityError"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a03/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a03/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Divisor Continuity Adjustment calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Divisor Continuity Adjustment\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Divisor Continuity Adjustment methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/index-initialization-and-continuity/divisor-continuity-adjustment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/index-initialization-and-continuity/divisor-continuity-adjustment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F01-A04",
      "name": "Corporate-Action Divisor Bridge",
      "headline": null,
      "slug": "corporate-action-divisor-bridge",
      "path": "index-and-benchmark-engineering/index-initialization-and-continuity/corporate-action-divisor-bridge",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F01",
        "family": "Index Initialization and Continuity",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/index-initialization-and-continuity/corporate-action-divisor-bridge",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Applies a corporate action to an index by routing its non-market value change through the divisor. Connects D02's event handling to the index level: the constituent's price changes for real, the index level must not.",
        "params": [
          {
            "name": "data",
            "type": "{ preEventMarketValue: number; nonMarketValueChange: number; preEventDivisor: number; action: string }",
            "required": true,
            "description": "`nonMarketValueChange` is the part of the value change that is *not* economic — the part the divisor must absorb. Splitting a change into its market and non-market components correctly is the whole difficulty.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ action, preEventLevel, postEventMarketValue, newDivisor, bridgedLevel }",
          "description": "The rebased divisor and the level either side, which should match."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the pre-event divisor is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F01-A04.json",
        "call": "calculate({\"preEventMarketValue\":100000000,\"nonMarketValueChange\":-4000000,\"preEventDivisor\":100000,\"action\":\"special dividend\"})",
        "args": [
          {
            "value": {
              "preEventMarketValue": 100000000,
              "nonMarketValueChange": -4000000,
              "preEventDivisor": 100000,
              "action": "special dividend"
            },
            "elided": null
          }
        ],
        "output": {
          "action": "special dividend",
          "preEventLevel": 1000,
          "postEventMarketValue": 96000000,
          "newDivisor": 96000,
          "bridgedLevel": 1000
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: action, preEventLevel, postEventMarketValue, newDivisor, bridgedLevel"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a04/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a04/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Corporate-Action Divisor Bridge calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Corporate-Action Divisor Bridge\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Corporate-Action Divisor Bridge methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/index-initialization-and-continuity/corporate-action-divisor-bridge/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/index-initialization-and-continuity/corporate-action-divisor-bridge/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F01-A05",
      "name": "Intraday Index-Level Calculation",
      "headline": null,
      "slug": "intraday-index-level-calculation",
      "path": "index-and-benchmark-engineering/index-initialization-and-continuity/intraday-index-level-calculation",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F01",
        "family": "Index Initialization and Continuity",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/index-initialization-and-continuity/intraday-index-level-calculation",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Recomputes the level from a live price snapshot using fixed index shares and float factors. Shares and float are held constant through the session — only prices move — which is why an intraday level is cheap to compute.",
        "params": [
          {
            "name": "data",
            "type": "{ indexShares: Record<string, number>; floatFactors: Record<string, number>; divisor: number; snapshots: Snapshot[] }",
            "required": true,
            "description": "`indexShares` and `floatFactors` are set at the last rebalance, not recalculated per tick. `snapshots` are the price updates to evaluate.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ levels, divisor }",
          "description": "A level per snapshot, and the divisor used."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a snapshot references a constituent with no index shares",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(snapshots × constituents)",
          "space": "O(snapshots)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F01-A05.json",
        "call": "calculate({\"indexShares\":[800,450,1080],\"floatFactors\":[1,1,1],\"divisor\":120,\"snapshots\":[{\"timestamp\":\"09:30\",\"prices\":[50,80,40],\"fxRates\":[1,1,1]},{\"timestamp\":\"10:00\",\"prices\":[50.5,79,40.2],\"fxRates\":[1,1,1]},{\"timestamp\":\"10:30\",\"prices\":[51,79.5,40.6],\"fxRates\":[1,1,1]}]})",
        "args": [
          {
            "value": {
              "indexShares": [
                800,
                450,
                1080
              ],
              "floatFactors": [
                1,
                1,
                1
              ],
              "divisor": 120,
              "snapshots": [
                {
                  "timestamp": "09:30",
                  "prices": [
                    50,
                    80,
                    40
                  ],
                  "fxRates": [
                    1,
                    1,
                    1
                  ]
                },
                {
                  "timestamp": "10:00",
                  "prices": [
                    50.5,
                    79,
                    40.2
                  ],
                  "fxRates": [
                    1,
                    1,
                    1
                  ]
                },
                {
                  "timestamp": "10:30",
                  "prices": [
                    51,
                    79.5,
                    40.6
                  ],
                  "fxRates": [
                    1,
                    1,
                    1
                  ]
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "levels": [
            {
              "timestamp": "09:30",
              "numerator": 119200,
              "level": 993.333333
            },
            {
              "timestamp": "10:00",
              "numerator": 119366,
              "level": 994.716667
            },
            {
              "timestamp": "10:30",
              "numerator": 120423,
              "level": 1003.525
            }
          ],
          "divisor": 120
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: levels, divisor"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a05/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a05/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f01-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Intraday Index-Level Calculation calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Intraday Index-Level Calculation\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Intraday Index-Level Calculation methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/index-initialization-and-continuity/intraday-index-level-calculation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/index-initialization-and-continuity/intraday-index-level-calculation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F02-A01",
      "name": "Price-Weighted Index",
      "headline": null,
      "slug": "price-weighted-index",
      "path": "index-and-benchmark-engineering/weighting-and-capping/price-weighted-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F02",
        "family": "Weighting and Capping",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/weighting-and-capping/price-weighted-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "The Dow construction: sum the prices, divide by a divisor. Weight follows share *price*, not company size — a $500 stock moves it more than a $50 one ten times the size, which is why it tells a different story from the S&P.",
        "params": [
          {
            "name": "data",
            "type": "{ prices: number[]; divisor: number }",
            "required": true,
            "description": "Constituent prices and the current divisor.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ priceSum, divisor, indexLevel, weights }",
          "description": "The level plus the implied weights, which make the price-not-size effect visible."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the divisor is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F02-A01.json",
        "call": "calculate({\"prices\":[50,75,25,100],\"divisor\":0.25})",
        "args": [
          {
            "value": {
              "prices": [
                50,
                75,
                25,
                100
              ],
              "divisor": 0.25
            },
            "elided": null
          }
        ],
        "output": {
          "priceSum": 250,
          "divisor": 0.25,
          "indexLevel": 1000,
          "weights": [
            0.2,
            0.3,
            0.1,
            0.4
          ]
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: priceSum, divisor, indexLevel, weights"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a01/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a01/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Price-Weighted Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Price-Weighted Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Price-Weighted Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/weighting-and-capping/price-weighted-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/weighting-and-capping/price-weighted-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F02-A02",
      "name": "Total-Market-Cap Index",
      "headline": null,
      "slug": "total-market-cap-index",
      "path": "index-and-benchmark-engineering/weighting-and-capping/total-market-cap-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F02",
        "family": "Weighting and Capping",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/weighting-and-capping/total-market-cap-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Weight by full market capitalisation. The textbook construction, and the starting point every float and capping rule modifies.",
        "params": [
          {
            "name": "data",
            "type": "{ constituents: Constituent[]; divisor: number }",
            "required": true,
            "description": "Constituents carrying price and total shares outstanding, and the current divisor.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ marketValues, weights, indexLevel }",
          "description": "Per-constituent market values and weights alongside the level."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the divisor is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F02-A02.json",
        "call": "calculate({\"constituents\":[{\"id\":\"A\",\"price\":20,\"shares\":1000000,\"fx\":1},{\"id\":\"B\",\"price\":40,\"shares\":500000,\"fx\":1},{\"id\":\"C\",\"price\":30,\"shares\":800000,\"fx\":1.1}],\"divisor\":50000})",
        "args": [
          {
            "value": {
              "constituents": [
                {
                  "id": "A",
                  "price": 20,
                  "shares": 1000000,
                  "fx": 1
                },
                {
                  "id": "B",
                  "price": 40,
                  "shares": 500000,
                  "fx": 1
                },
                {
                  "id": "C",
                  "price": 30,
                  "shares": 800000,
                  "fx": 1.1
                }
              ],
              "divisor": 50000
            },
            "elided": null
          }
        ],
        "output": {
          "marketValues": [
            20000000,
            20000000,
            26400000
          ],
          "weights": [
            0.301205,
            0.301205,
            0.39759
          ],
          "indexLevel": 1328
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: marketValues, weights, indexLevel"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a02/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a02/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Total-Market-Cap Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Total-Market-Cap Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Total-Market-Cap Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/weighting-and-capping/total-market-cap-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/weighting-and-capping/total-market-cap-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F02-A03",
      "name": "Free-Float Market-Cap Index",
      "headline": null,
      "slug": "free-float-market-cap-index",
      "path": "index-and-benchmark-engineering/weighting-and-capping/free-float-market-cap-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F02",
        "family": "Weighting and Capping",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/weighting-and-capping/free-float-market-cap-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Weight by the shares that can actually be bought. Excluding strategic, government and insider holdings is what makes an index replicable — a fund cannot buy shares that are not for sale.",
        "params": [
          {
            "name": "data",
            "type": "{ constituents: Constituent[] }",
            "required": true,
            "description": "Constituents carrying price, shares outstanding and a free-float factor.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ids, floatMarketValues, weights }",
          "description": "Float-adjusted market values and the weights they imply."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a float factor falls outside 0…1",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F02-A03.json",
        "call": "calculate({\"constituents\":[{\"id\":\"A\",\"price\":20,\"shares\":1000000,\"floatFactor\":0.65,\"fx\":1},{\"id\":\"B\",\"price\":40,\"shares\":500000,\"floatFactor\":0.9,\"fx\":1},{\"id\":\"C\",\"price\":30,\"shares\":800000,\"floatFactor\":0.5,\"fx\":1.1}]})",
        "args": [
          {
            "value": {
              "constituents": [
                {
                  "id": "A",
                  "price": 20,
                  "shares": 1000000,
                  "floatFactor": 0.65,
                  "fx": 1
                },
                {
                  "id": "B",
                  "price": 40,
                  "shares": 500000,
                  "floatFactor": 0.9,
                  "fx": 1
                },
                {
                  "id": "C",
                  "price": 30,
                  "shares": 800000,
                  "floatFactor": 0.5,
                  "fx": 1.1
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "ids": [
            "A",
            "B",
            "C",
            "D"
          ],
          "floatMarketValues": [
            13000000,
            18000000,
            13200000,
            12960000
          ],
          "weights": [
            0.227432,
            0.314906,
            0.230931,
            0.226732
          ]
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: ids, floatMarketValues, weights"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a03/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a03/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Free-Float Market-Cap Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Free-Float Market-Cap Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Free-Float Market-Cap Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/weighting-and-capping/free-float-market-cap-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/weighting-and-capping/free-float-market-cap-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F02-A04",
      "name": "Capped Free-Float Market-Cap Index",
      "headline": null,
      "slug": "capped-free-float-market-cap-index",
      "path": "index-and-benchmark-engineering/weighting-and-capping/capped-free-float-market-cap-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F02",
        "family": "Weighting and Capping",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/weighting-and-capping/capped-free-float-market-cap-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Float weighting with a ceiling on any single constituent. Regulation and mandate limits require it, and the redistribution is subtler than it looks: capping one name lifts the others, which can push a second name over the cap.",
        "params": [
          {
            "name": "data",
            "type": "{ ids: string[]; marketValues: number[]; cap: number }",
            "required": true,
            "description": "`cap` is the maximum weight any one constituent may hold, as a fraction. The routine iterates until every weight is compliant.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ids, weights, cap, iterations, maxWeight, weightSum }",
          "description": "Compliant weights plus `iterations` and `maxWeight`, so the redistribution can be checked rather than assumed to have converged."
        },
        "warmup": null,
        "errors": [
          {
            "when": "cap is not between 0 and 1",
            "behaviour": "throws"
          },
          {
            "when": "the cap is mathematically unsatisfiable — cap × count < 1",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × iterations)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F02-A04.json",
        "call": "calculate({\"ids\":[\"A\",\"B\",\"C\",\"D\",\"E\"],\"marketValues\":[48,24,14,9,5],\"cap\":0.3})",
        "args": [
          {
            "value": {
              "ids": [
                "A",
                "B",
                "C",
                "D",
                "E"
              ],
              "marketValues": [
                48,
                24,
                14,
                9,
                5
              ],
              "cap": 0.3
            },
            "elided": null
          }
        ],
        "output": {
          "ids": [
            "A",
            "B",
            "C",
            "D",
            "E"
          ],
          "weights": [
            0.3,
            0.3,
            0.2,
            0.128571,
            0.071429
          ],
          "cap": 0.3,
          "iterations": 3,
          "maxWeight": 0.3,
          "weightSum": 1
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: ids, weights, cap, iterations, maxWeight, weightSum"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a04/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a04/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Capped Free-Float Market-Cap Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Capped Free-Float Market-Cap Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Capped Free-Float Market-Cap Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/weighting-and-capping/capped-free-float-market-cap-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/weighting-and-capping/capped-free-float-market-cap-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F02-A05",
      "name": "Modified Market-Cap Index",
      "headline": null,
      "slug": "modified-market-cap-index",
      "path": "index-and-benchmark-engineering/weighting-and-capping/modified-market-cap-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F02",
        "family": "Weighting and Capping",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/weighting-and-capping/modified-market-cap-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Applies an exponent to market value before weighting, compressing the gap between the largest and smallest members. An exponent of 1 is plain cap weighting and 0 is equal weighting; between them is a continuous dial.",
        "params": [
          {
            "name": "data",
            "type": "{ ids: string[]; marketValues: number[]; exponent: number }",
            "required": true,
            "description": "`exponent` below 1 compresses the distribution; above 1 concentrates it further.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ids, transformedValues, weights, exponent }",
          "description": "The transformed values and resulting weights."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a market value is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F02-A05.json",
        "call": "calculate({\"ids\":[\"A\",\"B\",\"C\",\"D\"],\"marketValues\":[64,25,9,4],\"exponent\":0.5})",
        "args": [
          {
            "value": {
              "ids": [
                "A",
                "B",
                "C",
                "D"
              ],
              "marketValues": [
                64,
                25,
                9,
                4
              ],
              "exponent": 0.5
            },
            "elided": null
          }
        ],
        "output": {
          "ids": [
            "A",
            "B",
            "C",
            "D"
          ],
          "transformedValues": [
            8,
            5,
            3,
            2
          ],
          "weights": [
            0.444444,
            0.277778,
            0.166667,
            0.111111
          ],
          "exponent": 0.5
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: ids, transformedValues, weights, exponent"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a05/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a05/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Modified Market-Cap Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Modified Market-Cap Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Modified Market-Cap Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/weighting-and-capping/modified-market-cap-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/weighting-and-capping/modified-market-cap-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F02-A06",
      "name": "Equal-Weight Index",
      "headline": null,
      "slug": "equal-weight-index",
      "path": "index-and-benchmark-engineering/weighting-and-capping/equal-weight-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F02",
        "family": "Weighting and Capping",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/weighting-and-capping/equal-weight-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Every constituent counts the same. Simple to state and expensive to run: weights drift with prices immediately, so the construction implies continuous rebalancing and materially higher turnover.",
        "params": [
          {
            "name": "data",
            "type": "{ ids: string[]; returns: number[] }",
            "required": true,
            "description": "Constituent ids and their period returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ids, weights, portfolioReturn }",
          "description": "Equal weights and the resulting portfolio return."
        },
        "warmup": null,
        "errors": [
          {
            "when": "ids and returns differ in length",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F02-A06.json",
        "call": "calculate({\"ids\":[\"A\",\"B\",\"C\",\"D\",\"E\"],\"returns\":[0.02,-0.01,0.015,0.005,-0.004]})",
        "args": [
          {
            "value": {
              "ids": [
                "A",
                "B",
                "C",
                "D",
                "E"
              ],
              "returns": [
                0.02,
                -0.01,
                0.015,
                0.005,
                -0.004
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "ids": [
            "A",
            "B",
            "C",
            "D",
            "E"
          ],
          "weights": [
            0.2,
            0.2,
            0.2,
            0.2,
            0.2
          ],
          "portfolioReturn": 0.0052
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: ids, weights, portfolioReturn"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a06/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a06/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a06/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Equal-Weight Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Equal-Weight Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Equal-Weight Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/weighting-and-capping/equal-weight-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/weighting-and-capping/equal-weight-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F02-A07",
      "name": "Iterative Cap Redistribution",
      "headline": null,
      "slug": "iterative-cap-redistribution",
      "path": "index-and-benchmark-engineering/weighting-and-capping/iterative-cap-redistribution",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F02",
        "family": "Weighting and Capping",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/weighting-and-capping/iterative-cap-redistribution",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "The redistribution engine behind every capped index. Cap the offenders, spread the excess across the rest in proportion, repeat until nothing breaches — the loop is necessary because each pass can create new breaches.",
        "params": [
          {
            "name": "data",
            "type": "{ ids: string[]; rawWeights: number[]; cap: number; tolerance: number; maxIterations: number }",
            "required": true,
            "description": "`tolerance` is the convergence threshold and `maxIterations` the bound that keeps a pathological input from looping forever.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ids, weights, cap, iterations, maxWeight, weightSum }",
          "description": "Converged weights with the iteration count. `weightSum` should be 1 to within tolerance — if it is not, the loop hit its bound."
        },
        "warmup": null,
        "errors": [
          {
            "when": "cap × count < 1, which makes compliance impossible",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × iterations)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F02-A07.json",
        "call": "calculate({\"ids\":[\"A\",\"B\",\"C\",\"D\",\"E\",\"F\"],\"rawWeights\":[0.42,0.22,0.14,0.1,0.07,0.05],\"cap\":0.25,\"tolerance\":1e-10,\"maxIterations\":100})",
        "args": [
          {
            "value": {
              "ids": [
                "A",
                "B",
                "C",
                "D",
                "E",
                "F"
              ],
              "rawWeights": [
                0.42,
                0.22,
                0.14,
                0.1,
                0.07,
                0.05
              ],
              "cap": 0.25,
              "tolerance": 1e-10,
              "maxIterations": 100
            },
            "elided": null
          }
        ],
        "output": {
          "ids": [
            "A",
            "B",
            "C",
            "D",
            "E",
            "F"
          ],
          "weights": [
            0.25,
            0.25,
            0.194444,
            0.138889,
            0.097222,
            0.069444
          ],
          "cap": 0.25,
          "iterations": 3,
          "maxWeight": 0.25,
          "weightSum": 1
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: ids, weights, cap, iterations, maxWeight, weightSum"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a07/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a07/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a07/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Iterative Cap Redistribution calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Iterative Cap Redistribution\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Iterative Cap Redistribution methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/weighting-and-capping/iterative-cap-redistribution/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/weighting-and-capping/iterative-cap-redistribution/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F02-A08",
      "name": "Group-Level Capping",
      "headline": null,
      "slug": "group-level-capping",
      "path": "index-and-benchmark-engineering/weighting-and-capping/group-level-capping",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F02",
        "family": "Weighting and Capping",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/weighting-and-capping/group-level-capping",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Caps at two levels at once: each constituent, and each group it belongs to. This is the UCITS 5/10/40 shape, and the two constraints interact — satisfying one can break the other, so both are enforced together.",
        "params": [
          {
            "name": "data",
            "type": "{ items: Item[]; constituentCap: number; groupCaps: Record<string, number>; tolerance: number; maxIterations: number }",
            "required": true,
            "description": "`items` carry each constituent's group membership. `groupCaps` may differ per group — sector limits are rarely uniform.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ids, weights, groupWeights, iterations, weightSum }",
          "description": "Weights satisfying both constraint levels, with the realised group weights so compliance is visible rather than implied."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the combination of caps is unsatisfiable",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × iterations)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F02-A08.json",
        "call": "calculate({\"items\":[{\"id\":\"A\",\"group\":\"Tech\",\"weight\":0.35},{\"id\":\"B\",\"group\":\"Tech\",\"weight\":0.25},{\"id\":\"C\",\"group\":\"Finance\",\"weight\":0.18}],\"constituentCap\":0.3,\"groupCaps\":{\"Tech\":0.5,\"Finance\":0.6,\"Health\":0.6},\"tolerance\":1e-9,\"maxIterations\":200})",
        "args": [
          {
            "value": {
              "items": [
                {
                  "id": "A",
                  "group": "Tech",
                  "weight": 0.35
                },
                {
                  "id": "B",
                  "group": "Tech",
                  "weight": 0.25
                },
                {
                  "id": "C",
                  "group": "Finance",
                  "weight": 0.18
                }
              ],
              "constituentCap": 0.3,
              "groupCaps": {
                "Tech": 0.5,
                "Finance": 0.6,
                "Health": 0.6
              },
              "tolerance": 1e-9,
              "maxIterations": 200
            },
            "elided": null
          }
        ],
        "output": {
          "ids": [
            "A",
            "B",
            "C",
            "D",
            "E"
          ],
          "weights": [
            0.263514,
            0.236486,
            0.209508,
            0.154426,
            0.136066
          ],
          "groupWeights": {
            "Tech": 0.5,
            "Finance": 0.363934,
            "Health": 0.136066
          },
          "iterations": 4,
          "weightSum": 1
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: ids, weights, groupWeights, iterations, weightSum"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a08/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a08/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f02-a08/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Group-Level Capping calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Group-Level Capping\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Group-Level Capping methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/weighting-and-capping/group-level-capping/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/weighting-and-capping/group-level-capping/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F03-A01",
      "name": "Fundamental-Weighted Index",
      "headline": null,
      "slug": "fundamental-weighted-index",
      "path": "index-and-benchmark-engineering/alternative-weighting/fundamental-weighted-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F03",
        "family": "Alternative Weighting",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/alternative-weighting/fundamental-weighted-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Weight by accounting size — sales, book value, cash flow, dividends — instead of market price. The argument is that price-based weighting mechanically overweights whatever is currently expensive.",
        "params": [
          {
            "name": "data",
            "type": "{ records: Record[]; multipliers: Record<string, number> }",
            "required": true,
            "description": "`records` carry the fundamental metrics per constituent; `multipliers` set how each metric contributes to the composite score.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ids, scores, weights }",
          "description": "The composite score per constituent and the weights derived from it."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a multiplier references a metric absent from the records",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × metrics)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F03-A01.json",
        "call": "calculate({\"records\":[{\"id\":\"A\",\"sales\":120,\"cashFlow\":18,\"bookValue\":70,\"dividends\":4},{\"id\":\"B\",\"sales\":90,\"cashFlow\":15,\"bookValue\":55,\"dividends\":3},{\"id\":\"C\",\"sales\":60,\"cashFlow\":8,\"bookValue\":45,\"dividends\":2}],\"multipliers\":{\"sales\":1,\"cashFlow\":4,\"bookValue\":2,\"dividends\":10}})",
        "args": [
          {
            "value": {
              "records": [
                {
                  "id": "A",
                  "sales": 120,
                  "cashFlow": 18,
                  "bookValue": 70,
                  "dividends": 4
                },
                {
                  "id": "B",
                  "sales": 90,
                  "cashFlow": 15,
                  "bookValue": 55,
                  "dividends": 3
                },
                {
                  "id": "C",
                  "sales": 60,
                  "cashFlow": 8,
                  "bookValue": 45,
                  "dividends": 2
                }
              ],
              "multipliers": {
                "sales": 1,
                "cashFlow": 4,
                "bookValue": 2,
                "dividends": 10
              }
            },
            "elided": null
          }
        ],
        "output": {
          "ids": [
            "A",
            "B",
            "C",
            "D"
          ],
          "scores": [
            372,
            290,
            202,
            128
          ],
          "weights": [
            0.375,
            0.292339,
            0.203629,
            0.129032
          ]
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: ids, scores, weights"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a01/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a01/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Fundamental-Weighted Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Fundamental-Weighted Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Fundamental-Weighted Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/alternative-weighting/fundamental-weighted-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/alternative-weighting/fundamental-weighted-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F03-A02",
      "name": "Dividend-Yield-Weighted Index",
      "headline": null,
      "slug": "dividend-yield-weighted-index",
      "path": "index-and-benchmark-engineering/alternative-weighting/dividend-yield-weighted-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F03",
        "family": "Alternative Weighting",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/alternative-weighting/dividend-yield-weighted-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Weight by dividend yield. Straightforward arithmetic with a well-known failure mode: yield rises as price falls, so the construction naturally overweights companies in distress.",
        "params": [
          {
            "name": "data",
            "type": "{ ids: string[]; dividendYields: number[] }",
            "required": true,
            "description": "Constituent ids and their yields, expressed consistently as fractions or percentages.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ids, weights, weightedYield }",
          "description": "Weights and the resulting portfolio yield."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a yield is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F03-A02.json",
        "call": "calculate({\"ids\":[\"A\",\"B\",\"C\",\"D\",\"E\"],\"dividendYields\":[0.035,0.02,0.05,0.015,0.03]})",
        "args": [
          {
            "value": {
              "ids": [
                "A",
                "B",
                "C",
                "D",
                "E"
              ],
              "dividendYields": [
                0.035,
                0.02,
                0.05,
                0.015,
                0.03
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "ids": [
            "A",
            "B",
            "C",
            "D",
            "E"
          ],
          "weights": [
            0.233333,
            0.133333,
            0.333333,
            0.1,
            0.2
          ],
          "weightedYield": 0.035
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: ids, weights, weightedYield"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a02/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a02/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Dividend-Yield-Weighted Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Dividend-Yield-Weighted Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Dividend-Yield-Weighted Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/alternative-weighting/dividend-yield-weighted-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/alternative-weighting/dividend-yield-weighted-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F03-A03",
      "name": "Factor-Score-Weighted Index",
      "headline": null,
      "slug": "factor-score-weighted-index",
      "path": "index-and-benchmark-engineering/alternative-weighting/factor-score-weighted-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F03",
        "family": "Alternative Weighting",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/alternative-weighting/factor-score-weighted-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Weight by a composite of factor scores — value, quality, momentum — with a floor so negative scores cannot produce negative weights.",
        "params": [
          {
            "name": "data",
            "type": "{ records: Record[]; factorWeights: Record<string, number>; scoreFloor: number }",
            "required": true,
            "description": "`factorWeights` blends the factors; `scoreFloor` clips the composite from below, which is what keeps a short position from appearing in a long-only index.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ids, compositeScores, weights }",
          "description": "The blended score per constituent and the weights it produces."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the factor weights do not reference any available score",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × factors)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F03-A03.json",
        "call": "calculate({\"records\":[{\"id\":\"A\",\"value\":12,\"quality\":18,\"momentum\":8},{\"id\":\"B\",\"value\":8,\"quality\":15,\"momentum\":12},{\"id\":\"C\",\"value\":15,\"quality\":9,\"momentum\":5}],\"factorWeights\":{\"value\":0.4,\"quality\":0.35,\"momentum\":0.25},\"scoreFloor\":0.1})",
        "args": [
          {
            "value": {
              "records": [
                {
                  "id": "A",
                  "value": 12,
                  "quality": 18,
                  "momentum": 8
                },
                {
                  "id": "B",
                  "value": 8,
                  "quality": 15,
                  "momentum": 12
                },
                {
                  "id": "C",
                  "value": 15,
                  "quality": 9,
                  "momentum": 5
                }
              ],
              "factorWeights": {
                "value": 0.4,
                "quality": 0.35,
                "momentum": 0.25
              },
              "scoreFloor": 0.1
            },
            "elided": null
          }
        ],
        "output": {
          "ids": [
            "A",
            "B",
            "C",
            "D",
            "E"
          ],
          "compositeScores": [
            0.639323,
            0.066682,
            -0.176343,
            -0.273927,
            -0.255736
          ],
          "weights": [
            0.541951,
            0.235666,
            0.10568,
            0.053486,
            0.063216
          ]
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: ids, compositeScores, weights"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a03/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a03/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Factor-Score-Weighted Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Factor-Score-Weighted Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Factor-Score-Weighted Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/alternative-weighting/factor-score-weighted-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/alternative-weighting/factor-score-weighted-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F03-A04",
      "name": "Minimum-Volatility Index",
      "headline": null,
      "slug": "minimum-volatility-index",
      "path": "index-and-benchmark-engineering/alternative-weighting/minimum-volatility-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F03",
        "family": "Alternative Weighting",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/alternative-weighting/minimum-volatility-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Solves for the weights that minimise portfolio variance for a given covariance matrix. The result is only as good as the covariance estimate, which is the part that is hard — not the optimisation.",
        "params": [
          {
            "name": "data",
            "type": "{ ids: string[]; covariance: number[][] }",
            "required": true,
            "description": "`covariance` must be square, symmetric and positive semi-definite. A matrix estimated from fewer observations than assets will not be, and no optimiser can rescue it.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ids, weights, variance, volatility }",
          "description": "The minimising weights and the portfolio variance and volatility they achieve."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the covariance matrix is not square or not symmetric",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n³)",
          "space": "O(n²)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F03-A04.json",
        "call": "calculate({\"ids\":[\"A\",\"B\",\"C\"],\"covariance\":[[0.04,0.006,0.004],[0.006,0.0225,0.003],[0.004,0.003,0.01]]})",
        "args": [
          {
            "value": {
              "ids": [
                "A",
                "B",
                "C"
              ],
              "covariance": [
                [
                  0.04,
                  0.006,
                  0.004
                ],
                [
                  0.006,
                  0.0225,
                  0.003
                ],
                [
                  0.004,
                  0.003,
                  0.01
                ]
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "ids": [
            "A",
            "B",
            "C"
          ],
          "weights": [
            0.093023,
            0.232558,
            0.674419
          ],
          "variance": 0.007814,
          "volatility": 0.088397
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: ids, weights, variance, volatility"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a04/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a04/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Minimum-Volatility Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Minimum-Volatility Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Minimum-Volatility Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/alternative-weighting/minimum-volatility-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/alternative-weighting/minimum-volatility-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F03-A05",
      "name": "Equal-Risk-Contribution Index",
      "headline": null,
      "slug": "equal-risk-contribution-index",
      "path": "index-and-benchmark-engineering/alternative-weighting/equal-risk-contribution-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F03",
        "family": "Alternative Weighting",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/alternative-weighting/equal-risk-contribution-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Risk parity: weights chosen so every constituent contributes the same share of total portfolio risk. Equal *risk*, not equal money — a volatile asset gets a smaller position.",
        "params": [
          {
            "name": "data",
            "type": "{ ids: string[]; covariance: number[][]; tolerance: number; maxIterations: number }",
            "required": true,
            "description": "Solved iteratively; `tolerance` is the convergence threshold on risk-contribution dispersion and `maxIterations` the bound.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ids, weights, riskContributionShares, volatility, iterations }",
          "description": "The weights plus each constituent's realised risk share — which should be equal, and is reported so that can be verified rather than assumed."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the covariance matrix is not square or not symmetric",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n² × iterations)",
          "space": "O(n²)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F03-A05.json",
        "call": "calculate({\"ids\":[\"A\",\"B\",\"C\"],\"covariance\":[[0.04,0.006,0.004],[0.006,0.0225,0.003],[0.004,0.003,0.01]],\"tolerance\":1e-8,\"maxIterations\":1000})",
        "args": [
          {
            "value": {
              "ids": [
                "A",
                "B",
                "C"
              ],
              "covariance": [
                [
                  0.04,
                  0.006,
                  0.004
                ],
                [
                  0.006,
                  0.0225,
                  0.003
                ],
                [
                  0.004,
                  0.003,
                  0.01
                ]
              ],
              "tolerance": 1e-8,
              "maxIterations": 1000
            },
            "elided": null
          }
        ],
        "output": {
          "ids": [
            "A",
            "B",
            "C"
          ],
          "weights": [
            0.230769,
            0.307692,
            0.461538
          ],
          "riskContributionShares": [
            0.333333,
            0.333333,
            0.333333
          ],
          "volatility": 0.094587,
          "iterations": 12
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: ids, weights, riskContributionShares, volatility, iterations"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a05/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a05/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Equal-Risk-Contribution Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Equal-Risk-Contribution Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Equal-Risk-Contribution Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/alternative-weighting/equal-risk-contribution-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/alternative-weighting/equal-risk-contribution-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F03-A06",
      "name": "Thematic-Tilt Index",
      "headline": null,
      "slug": "thematic-tilt-index",
      "path": "index-and-benchmark-engineering/alternative-weighting/thematic-tilt-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F03",
        "family": "Alternative Weighting",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/alternative-weighting/thematic-tilt-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Tilts a parent index toward a theme by scaling weights with a theme score, bounded so no single name runs away. Keeps the parent's diversification while expressing a view.",
        "params": [
          {
            "name": "data",
            "type": "{ ids: string[]; parentWeights: number[]; themeScores: number[]; tilt: number; maxMultiplier: number }",
            "required": true,
            "description": "`tilt` sets the strength of the tilt and `maxMultiplier` caps how far any weight may be multiplied — without it a high score plus a small parent weight produces an untradeable position.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ids, multipliers, weights, activeWeights }",
          "description": "Tilted weights and the active weights against the parent, which is what a tracking-error budget is measured on."
        },
        "warmup": null,
        "errors": [
          {
            "when": "maxMultiplier is less than 1",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F03-A06.json",
        "call": "calculate({\"ids\":[\"A\",\"B\",\"C\",\"D\",\"E\"],\"parentWeights\":[0.3,0.25,0.2,0.15,0.1],\"themeScores\":[1,0.6,0.1,-0.4,-0.8],\"tilt\":0.5,\"maxMultiplier\":1.6})",
        "args": [
          {
            "value": {
              "ids": [
                "A",
                "B",
                "C",
                "D",
                "E"
              ],
              "parentWeights": [
                0.3,
                0.25,
                0.2,
                0.15,
                0.1
              ],
              "themeScores": [
                1,
                0.6,
                0.1,
                -0.4,
                -0.8
              ],
              "tilt": 0.5,
              "maxMultiplier": 1.6
            },
            "elided": null
          }
        ],
        "output": {
          "ids": [
            "A",
            "B",
            "C",
            "D",
            "E"
          ],
          "multipliers": [
            1.5,
            1.3,
            1.05,
            0.8,
            0.6
          ],
          "weights": [
            0.386266,
            0.27897,
            0.180258,
            0.103004,
            0.051502
          ],
          "activeWeights": [
            0.086266,
            0.02897,
            -0.019742,
            -0.046996,
            -0.048498
          ]
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: ids, multipliers, weights, activeWeights"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a06/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a06/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f03-a06/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Thematic-Tilt Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Thematic-Tilt Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Thematic-Tilt Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/alternative-weighting/thematic-tilt-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/alternative-weighting/thematic-tilt-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F04-A01",
      "name": "Price-Return Index",
      "headline": null,
      "slug": "price-return-index",
      "path": "index-and-benchmark-engineering/return-variants/price-return-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F04",
        "family": "Return Variants",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/return-variants/price-return-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Level series from price returns alone, ignoring dividends. The number most often quoted, and the one that understates long-horizon performance.",
        "params": [
          {
            "name": "data",
            "type": "{ prices: number[]; baseLevel: number }",
            "required": true,
            "description": "Constituent or index prices in chronological order. `baseLevel` is the index value at the start of the series; it scales the level but never the returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ returns, levels, endingLevel }",
          "description": "Period returns, the level series, and the final level."
        },
        "warmup": null,
        "errors": [
          {
            "when": "fewer than two prices are supplied",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F04-A01.json",
        "call": "calculate({\"prices\":[100,102,101,104,103.5,106],\"baseLevel\":1000})",
        "args": [
          {
            "value": {
              "prices": [
                100,
                102,
                101,
                104,
                103.5,
                106
              ],
              "baseLevel": 1000
            },
            "elided": null
          }
        ],
        "output": {
          "returns": [
            0.02,
            -0.009804,
            0.029703,
            -0.004808,
            0.024155
          ],
          "levels": [
            1000,
            1020,
            1010,
            1040,
            1035,
            1060
          ],
          "endingLevel": 1060
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: returns, levels, endingLevel"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a01/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a01/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Price-Return Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Price-Return Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Price-Return Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/return-variants/price-return-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/return-variants/price-return-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F04-A02",
      "name": "Gross Total-Return Index",
      "headline": null,
      "slug": "gross-total-return-index",
      "path": "index-and-benchmark-engineering/return-variants/gross-total-return-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F04",
        "family": "Return Variants",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/return-variants/gross-total-return-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Reinvests dividends in full, with no tax deducted. The variant that assumes a holder who suffers no withholding — a domestic pension fund, typically.",
        "params": [
          {
            "name": "data",
            "type": "{ prices: number[]; dividends: number[]; baseLevel: number }",
            "required": true,
            "description": "`dividends` aligns index-for-index with `prices` and is expressed on the ex-date. `baseLevel` is the index value at the start of the series; it scales the level but never the returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ returns, levels, endingLevel }",
          "description": "Total returns with dividends reinvested gross."
        },
        "warmup": null,
        "errors": [
          {
            "when": "prices and dividends differ in length",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F04-A02.json",
        "call": "calculate({\"prices\":[100,102,99,101,103,104],\"dividends\":[0,0,3,0,0,1],\"baseLevel\":1000})",
        "args": [
          {
            "value": {
              "prices": [
                100,
                102,
                99,
                101,
                103,
                104
              ],
              "dividends": [
                0,
                0,
                3,
                0,
                0,
                1
              ],
              "baseLevel": 1000
            },
            "elided": null
          }
        ],
        "output": {
          "returns": [
            0.02,
            0,
            0.020202,
            0.019802,
            0.019417
          ],
          "levels": [
            1000,
            1020,
            1020,
            1040.606061,
            1061.212121,
            1081.818182
          ],
          "endingLevel": 1081.818182
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: returns, levels, endingLevel"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a02/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a02/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Gross Total-Return Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Gross Total-Return Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Gross Total-Return Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/return-variants/gross-total-return-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/return-variants/gross-total-return-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F04-A03",
      "name": "Net Total-Return Index",
      "headline": null,
      "slug": "net-total-return-index",
      "path": "index-and-benchmark-engineering/return-variants/net-total-return-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F04",
        "family": "Return Variants",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/return-variants/net-total-return-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Reinvests dividends after withholding tax. Over a decade the gap from the gross variant is large enough that quoting the wrong one materially misstates performance — and both are published under nearly the same name.",
        "params": [
          {
            "name": "data",
            "type": "{ prices: number[]; dividends: number[]; withholdingRates: number[]; baseLevel: number }",
            "required": true,
            "description": "`withholdingRates` is per observation because the rate depends on the domicile pairing and changes with treaty. `baseLevel` is the index value at the start of the series; it scales the level but never the returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ returns, levels, endingLevel }",
          "description": "Total returns with dividends reinvested net of withholding."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a withholding rate falls outside 0…1",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F04-A03.json",
        "call": "calculate({\"prices\":[100,102,99,101,103,104],\"dividends\":[0,0,3,0,0,1],\"withholdingRates\":[0,0,0.25,0,0,0.25],\"baseLevel\":1000})",
        "args": [
          {
            "value": {
              "prices": [
                100,
                102,
                99,
                101,
                103,
                104
              ],
              "dividends": [
                0,
                0,
                3,
                0,
                0,
                1
              ],
              "withholdingRates": [
                0,
                0,
                0.25,
                0,
                0,
                0.25
              ],
              "baseLevel": 1000
            },
            "elided": null
          }
        ],
        "output": {
          "returns": [
            0.02,
            -0.007353,
            0.020202,
            0.019802,
            0.01699
          ],
          "levels": [
            1000,
            1020,
            1012.5,
            1032.954545,
            1053.409091,
            1071.306818
          ],
          "endingLevel": 1071.306818
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: returns, levels, endingLevel"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a03/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a03/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Net Total-Return Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Net Total-Return Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Net Total-Return Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/return-variants/net-total-return-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/return-variants/net-total-return-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F04-A04",
      "name": "Excess-Return Index",
      "headline": null,
      "slug": "excess-return-index",
      "path": "index-and-benchmark-engineering/return-variants/excess-return-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F04",
        "family": "Return Variants",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/return-variants/excess-return-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Total return less a cash return, giving the return over funding. This is what a futures or swap position on the index actually earns, which is why structured products quote it.",
        "params": [
          {
            "name": "data",
            "type": "{ totalReturns: number[]; cashReturns: number[]; baseLevel: number }",
            "required": true,
            "description": "Both series must cover identical periods; mismatched compounding frequencies are a silent error. `baseLevel` is the index value at the start of the series; it scales the level but never the returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ excessReturns, levels, endingLevel }",
          "description": "Excess returns and the level series they generate."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the two return series differ in length",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F04-A04.json",
        "call": "calculate({\"totalReturns\":[0.005,-0.002,0.008,0.001,-0.004,0.006],\"cashReturns\":[0.00015,0.00015,0.00016,0.00016,0.00016,0.00017],\"baseLevel\":1000})",
        "args": [
          {
            "value": {
              "totalReturns": [
                0.005,
                -0.002,
                0.008,
                0.001,
                -0.004,
                0.006
              ],
              "cashReturns": [
                0.00015,
                0.00015,
                0.00016,
                0.00016,
                0.00016,
                0.00017
              ],
              "baseLevel": 1000
            },
            "elided": null
          }
        ],
        "output": {
          "excessReturns": [
            0.004849,
            -0.00215,
            0.007839,
            0.00084,
            -0.004159,
            0.005829
          ],
          "levels": [
            1000,
            1004.849273,
            1002.689171,
            1010.548996,
            1011.397722,
            1007.19098
          ],
          "endingLevel": 1013.061905
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: excessReturns, levels, endingLevel"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a04/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a04/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Excess-Return Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Excess-Return Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Excess-Return Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/return-variants/excess-return-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/return-variants/excess-return-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F04-A05",
      "name": "Dividend-Point Index",
      "headline": null,
      "slug": "dividend-point-index",
      "path": "index-and-benchmark-engineering/return-variants/dividend-point-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F04",
        "family": "Return Variants",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/return-variants/dividend-point-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Expresses dividends in index points rather than currency, which is how dividend futures and swaps are quoted. Converting through the divisor is what makes a per-share payment comparable to an index level.",
        "params": [
          {
            "name": "data",
            "type": "{ events: DividendEvent[]; divisor: number }",
            "required": true,
            "description": "`events` carry per-share dividends and index shares; `divisor` converts the aggregate into points.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ids, pointContributions, dividendPoints }",
          "description": "Each constituent's contribution in points and the total."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the divisor is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F04-A05.json",
        "call": "calculate({\"events\":[{\"id\":\"A\",\"dividend\":1.2,\"indexShares\":2000000,\"floatFactor\":0.8,\"fx\":1},{\"id\":\"B\",\"dividend\":0.5,\"indexShares\":3500000,\"floatFactor\":0.7,\"fx\":1},{\"id\":\"C\",\"dividend\":2,\"indexShares\":500000,\"floatFactor\":1,\"fx\":1.1}],\"divisor\":1000000})",
        "args": [
          {
            "value": {
              "events": [
                {
                  "id": "A",
                  "dividend": 1.2,
                  "indexShares": 2000000,
                  "floatFactor": 0.8,
                  "fx": 1
                },
                {
                  "id": "B",
                  "dividend": 0.5,
                  "indexShares": 3500000,
                  "floatFactor": 0.7,
                  "fx": 1
                },
                {
                  "id": "C",
                  "dividend": 2,
                  "indexShares": 500000,
                  "floatFactor": 1,
                  "fx": 1.1
                }
              ],
              "divisor": 1000000
            },
            "elided": null
          }
        ],
        "output": {
          "ids": [
            "A",
            "B",
            "C"
          ],
          "pointContributions": [
            1.92,
            1.225,
            1.1
          ],
          "dividendPoints": 4.245
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: ids, pointContributions, dividendPoints"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a05/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a05/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Dividend-Point Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Dividend-Point Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Dividend-Point Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/return-variants/dividend-point-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/return-variants/dividend-point-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F04-A06",
      "name": "Currency-Converted Index",
      "headline": null,
      "slug": "currency-converted-index",
      "path": "index-and-benchmark-engineering/return-variants/currency-converted-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F04",
        "family": "Return Variants",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/return-variants/currency-converted-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Restates an index in another currency by compounding local returns with FX returns. Unhedged: the holder takes the currency exposure, and this is the variant that shows it.",
        "params": [
          {
            "name": "data",
            "type": "{ localReturns: number[]; fxReturns: number[]; baseLevel: number; quote: string }",
            "required": true,
            "description": "`quote` names the direction of the FX quotation. Getting that direction backwards inverts the currency effect, and the result still looks plausible. `baseLevel` is the index value at the start of the series; it scales the level but never the returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ baseCurrencyReturns, levels, endingLevel, quote }",
          "description": "Converted returns and levels, with the quote convention echoed back for checking."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the return series differ in length",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F04-A06.json",
        "call": "calculate({\"localReturns\":[0.01,-0.004,0.006,0.002,-0.003],\"fxReturns\":[0.002,0.001,-0.003,0.004,-0.001],\"baseLevel\":1000,\"quote\":\"base currency per local currency\"})",
        "args": [
          {
            "value": {
              "localReturns": [
                0.01,
                -0.004,
                0.006,
                0.002,
                -0.003
              ],
              "fxReturns": [
                0.002,
                0.001,
                -0.003,
                0.004,
                -0.001
              ],
              "baseLevel": 1000,
              "quote": "base currency per local currency"
            },
            "elided": null
          }
        ],
        "output": {
          "baseCurrencyReturns": [
            0.01202,
            -0.003004,
            0.002982,
            0.006008,
            -0.003997
          ],
          "levels": [
            1000,
            1012.02,
            1008.979892,
            1011.98867,
            1018.068698,
            1013.999477
          ],
          "endingLevel": 1013.999477,
          "quote": "base currency per local currency"
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: baseCurrencyReturns, levels, endingLevel, quote"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a06/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a06/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a06/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Currency-Converted Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Currency-Converted Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Currency-Converted Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/return-variants/currency-converted-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/return-variants/currency-converted-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F04-A07",
      "name": "Currency-Hedged Index",
      "headline": null,
      "slug": "currency-hedged-index",
      "path": "index-and-benchmark-engineering/return-variants/currency-hedged-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F04",
        "family": "Return Variants",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/return-variants/currency-hedged-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Neutralises currency exposure with rolling forwards. Hedged and converted variants of the same index can diverge by double digits over a year — they are different products, not a formatting choice.",
        "params": [
          {
            "name": "data",
            "type": "{ baseCurrencyReturns: number[]; forwardOffsets: number[]; hedgeRatio: number; baseLevel: number }",
            "required": true,
            "description": "`forwardOffsets` carry the forward points, which is where the interest-rate differential enters — a hedge is not free. `hedgeRatio` allows partial hedging. `baseLevel` is the index value at the start of the series; it scales the level but never the returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ hedgedReturns, levels, endingLevel, hedgeRatio }",
          "description": "Hedged returns and levels, with the ratio applied."
        },
        "warmup": null,
        "errors": [
          {
            "when": "hedgeRatio falls outside 0…1",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F04-A07.json",
        "call": "calculate({\"baseCurrencyReturns\":[0.01202,-0.003004,0.002982,0.006008,-0.003997],\"forwardOffsets\":[-0.0018,-0.0009,0.0027,-0.0036,0.0009],\"hedgeRatio\":1,\"baseLevel\":1000})",
        "args": [
          {
            "value": {
              "baseCurrencyReturns": [
                0.01202,
                -0.003004,
                0.002982,
                0.006008,
                -0.003997
              ],
              "forwardOffsets": [
                -0.0018,
                -0.0009,
                0.0027,
                -0.0036,
                0.0009
              ],
              "hedgeRatio": 1,
              "baseLevel": 1000
            },
            "elided": null
          }
        ],
        "output": {
          "hedgedReturns": [
            0.01022,
            -0.003904,
            0.005682,
            0.002408,
            -0.003097
          ],
          "levels": [
            1000,
            1010.22,
            1006.276101,
            1011.993762,
            1014.430643,
            1011.288951
          ],
          "endingLevel": 1011.288951,
          "hedgeRatio": 1
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: hedgedReturns, levels, endingLevel, hedgeRatio"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a07/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a07/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f04-a07/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Currency-Hedged Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Currency-Hedged Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Currency-Hedged Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/return-variants/currency-hedged-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/return-variants/currency-hedged-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F05-A01",
      "name": "Leveraged Daily-Reset Index",
      "headline": null,
      "slug": "leveraged-daily-reset-index",
      "path": "index-and-benchmark-engineering/strategy-indices/leveraged-daily-reset-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F05",
        "family": "Strategy Indices",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/strategy-indices/leveraged-daily-reset-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Applies a leverage multiple that resets every day. Daily reset is why a 2× product does not deliver 2× over a month: in a choppy market, compounding the reset erodes the level even when the underlying ends flat.",
        "params": [
          {
            "name": "data",
            "type": "{ returns: number[]; leverage: number; dailyCost: number; baseLevel: number }",
            "required": true,
            "description": "`dailyCost` is the financing drag applied each day, which is what makes the long-run gap wider than volatility decay alone. `baseLevel` is the index value at the start of the series; it scales the level but never the returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ strategyReturns, levels, endingLevel, multiple }",
          "description": "The leveraged return series and levels."
        },
        "warmup": null,
        "errors": [
          {
            "when": "leverage is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F05-A01.json",
        "call": "calculate({\"returns\":[0.02,-0.015,0.01,-0.025,0.018,0.006],\"leverage\":2,\"dailyCost\":0.0001,\"baseLevel\":1000})",
        "args": [
          {
            "value": {
              "returns": [
                0.02,
                -0.015,
                0.01,
                -0.025,
                0.018,
                0.006
              ],
              "leverage": 2,
              "dailyCost": 0.0001,
              "baseLevel": 1000
            },
            "elided": null
          }
        ],
        "output": {
          "strategyReturns": [
            0.0399,
            -0.0301,
            0.0199,
            -0.0501,
            0.0359,
            0.0119
          ],
          "levels": [
            1000,
            1039.9,
            1008.59901,
            1028.67013,
            977.133757,
            1012.212859
          ],
          "endingLevel": 1024.258192,
          "multiple": 2
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: strategyReturns, levels, endingLevel, multiple"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a01/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a01/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Leveraged Daily-Reset Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Leveraged Daily-Reset Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Leveraged Daily-Reset Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/strategy-indices/leveraged-daily-reset-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/strategy-indices/leveraged-daily-reset-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F05-A02",
      "name": "Inverse Daily-Reset Index",
      "headline": null,
      "slug": "inverse-daily-reset-index",
      "path": "index-and-benchmark-engineering/strategy-indices/inverse-daily-reset-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F05",
        "family": "Strategy Indices",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/strategy-indices/inverse-daily-reset-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "An inverse multiple reset daily. The same path dependence as the leveraged case and in the same direction: over any period longer than a day, the result is not the negative of the underlying's return.",
        "params": [
          {
            "name": "data",
            "type": "{ returns: number[]; inverseMultiple: number; dailyCost: number; baseLevel: number }",
            "required": true,
            "description": "`inverseMultiple` is given as a positive magnitude. `baseLevel` is the index value at the start of the series; it scales the level but never the returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ strategyReturns, levels, endingLevel, multiple }",
          "description": "The inverse return series and levels."
        },
        "warmup": null,
        "errors": [
          {
            "when": "inverseMultiple is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F05-A02.json",
        "call": "calculate({\"returns\":[0.02,-0.015,0.01,-0.025,0.018,0.006],\"inverseMultiple\":1,\"dailyCost\":0.0001,\"baseLevel\":1000})",
        "args": [
          {
            "value": {
              "returns": [
                0.02,
                -0.015,
                0.01,
                -0.025,
                0.018,
                0.006
              ],
              "inverseMultiple": 1,
              "dailyCost": 0.0001,
              "baseLevel": 1000
            },
            "elided": null
          }
        ],
        "output": {
          "strategyReturns": [
            -0.0201,
            0.0149,
            -0.0101,
            0.0249,
            -0.0181,
            -0.0061
          ],
          "levels": [
            1000,
            979.9,
            994.50051,
            984.456055,
            1008.969011,
            990.706672
          ],
          "endingLevel": 984.663361,
          "multiple": 1
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: strategyReturns, levels, endingLevel, multiple"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a02/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a02/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Inverse Daily-Reset Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Inverse Daily-Reset Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Inverse Daily-Reset Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/strategy-indices/inverse-daily-reset-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/strategy-indices/inverse-daily-reset-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F05-A03",
      "name": "Volatility-Control Index",
      "headline": null,
      "slug": "volatility-control-index",
      "path": "index-and-benchmark-engineering/strategy-indices/volatility-control-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F05",
        "family": "Strategy Indices",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/strategy-indices/volatility-control-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Scales exposure to hold realised volatility near a target, cutting it when markets get rough. Exposure is set from *trailing* volatility, so the mechanism always acts after the fact — it dampens rather than avoids.",
        "params": [
          {
            "name": "data",
            "type": "{ returns: number[]; lookback: number; annualization: number; targetVolatility: number; maxExposure: number; cashReturn: number; baseLevel: number }",
            "required": true,
            "description": "`lookback` is the realised-volatility window and `annualization` the scaling factor (252 for daily data). `maxExposure` caps leverage when volatility is low. `baseLevel` is the index value at the start of the series; it scales the level but never the returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ exposures, strategyReturns, levels, endingLevel }",
          "description": "The exposure actually taken each day alongside the returns — the exposure path is what explains the strategy's behaviour."
        },
        "warmup": null,
        "errors": [
          {
            "when": "lookback < 1, or targetVolatility is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × lookback)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F05-A03.json",
        "call": "calculate({\"returns\":[0.004,-0.003,0.005,0.002,-0.012,0.015],\"lookback\":4,\"annualization\":252,\"targetVolatility\":0.1,\"maxExposure\":1.5,\"cashReturn\":0.0001,\"baseLevel\":1000})",
        "args": [
          {
            "value": {
              "returns": [
                0.004,
                -0.003,
                0.005,
                0.002,
                -0.012,
                0.015
              ],
              "lookback": 4,
              "annualization": 252,
              "targetVolatility": 0.1,
              "maxExposure": 1.5,
              "cashReturn": 0.0001,
              "baseLevel": 1000
            },
            "elided": null
          }
        ],
        "output": {
          "exposures": [
            1,
            1,
            1,
            1,
            1.5,
            0.84685
          ],
          "strategyReturns": [
            0.004,
            -0.003,
            0.005,
            0.002,
            -0.01805,
            0.012718
          ],
          "levels": [
            1000,
            1004,
            1000.988,
            1005.99294,
            1008.004926,
            989.810437
          ],
          "endingLevel": 1006.077264
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: exposures, strategyReturns, levels, endingLevel"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a03/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a03/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Volatility-Control Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Volatility-Control Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Volatility-Control Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/strategy-indices/volatility-control-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/strategy-indices/volatility-control-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F05-A04",
      "name": "Fixed-Decrement Index",
      "headline": null,
      "slug": "fixed-decrement-index",
      "path": "index-and-benchmark-engineering/strategy-indices/fixed-decrement-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F05",
        "family": "Strategy Indices",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/strategy-indices/fixed-decrement-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Deducts a fixed number of index points per year. Decrement indices exist to make option pricing on them cheaper, and the deduction is a real drag borne by the holder — not a fee schedule.",
        "params": [
          {
            "name": "data",
            "type": "{ underlyingLevels: number[]; annualDecrementPoints: number; dayCount: number; baseLevel: number }",
            "required": true,
            "description": "`dayCount` sets the convention used to pro-rate the annual figure; 360 and 365 give different answers. `baseLevel` is the index value at the start of the series; it scales the level but never the returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ dailyDeductions, levels, endingLevel }",
          "description": "The deduction applied each day and the resulting level series."
        },
        "warmup": null,
        "errors": [
          {
            "when": "dayCount is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F05-A04.json",
        "call": "calculate({\"underlyingLevels\":[100,101,100.5,102,103,102.6],\"annualDecrementPoints\":5,\"dayCount\":360,\"baseLevel\":100})",
        "args": [
          {
            "value": {
              "underlyingLevels": [
                100,
                101,
                100.5,
                102,
                103,
                102.6
              ],
              "annualDecrementPoints": 5,
              "dayCount": 360,
              "baseLevel": 100
            },
            "elided": null
          }
        ],
        "output": {
          "dailyDeductions": [
            0.013889,
            0.013889,
            0.013889,
            0.013889,
            0.013889,
            0.013889
          ],
          "levels": [
            100,
            100.986111,
            100.472291,
            101.957989,
            102.943688,
            102.530018
          ],
          "endingLevel": 103.915174
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: dailyDeductions, levels, endingLevel"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a04/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a04/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Fixed-Decrement Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Fixed-Decrement Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Fixed-Decrement Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/strategy-indices/fixed-decrement-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/strategy-indices/fixed-decrement-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F05-A05",
      "name": "Percentage-Decrement Index",
      "headline": null,
      "slug": "percentage-decrement-index",
      "path": "index-and-benchmark-engineering/strategy-indices/percentage-decrement-index",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F05",
        "family": "Strategy Indices",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/strategy-indices/percentage-decrement-index",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "The same idea as a fixed decrement, but proportional to the level. The two diverge as the index moves: a points decrement bites harder when the level is low, a percentage one scales with it.",
        "params": [
          {
            "name": "data",
            "type": "{ underlyingLevels: number[]; annualDecrementRate: number; dayCount: number; baseLevel: number }",
            "required": true,
            "description": "`annualDecrementRate` is a fraction per year, pro-rated by `dayCount`. `baseLevel` is the index value at the start of the series; it scales the level but never the returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ dailyDeductions, levels, endingLevel }",
          "description": "The proportional deduction per day and the level series."
        },
        "warmup": null,
        "errors": [
          {
            "when": "dayCount is not positive, or the rate is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F05-A05.json",
        "call": "calculate({\"underlyingLevels\":[100,101,100.5,102,103,102.6],\"annualDecrementRate\":0.05,\"dayCount\":360,\"baseLevel\":100})",
        "args": [
          {
            "value": {
              "underlyingLevels": [
                100,
                101,
                100.5,
                102,
                103,
                102.6
              ],
              "annualDecrementRate": 0.05,
              "dayCount": 360,
              "baseLevel": 100
            },
            "elided": null
          }
        ],
        "output": {
          "dailyDeductions": [
            0.000139,
            0.000139,
            0.000139,
            0.000139,
            0.000139,
            0.000139
          ],
          "levels": [
            100,
            100.986111,
            100.472154,
            101.957784,
            102.943209,
            102.529132
          ],
          "endingLevel": 103.913925
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: dailyDeductions, levels, endingLevel"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a05/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a05/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Percentage-Decrement Index calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Percentage-Decrement Index\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Percentage-Decrement Index methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/strategy-indices/percentage-decrement-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/strategy-indices/percentage-decrement-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F05-A06",
      "name": "Index-of-Indices",
      "headline": null,
      "slug": "index-of-indices",
      "path": "index-and-benchmark-engineering/strategy-indices/index-of-indices",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F05",
        "family": "Strategy Indices",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/strategy-indices/index-of-indices",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Combines several index return streams into one under fixed weights. Straightforward, with one thing to get right: the component returns must be the same variant — mixing a price-return component with a total-return one biases the blend.",
        "params": [
          {
            "name": "data",
            "type": "{ componentIds: string[]; weights: number[]; componentReturns: number[][]; baseLevel: number }",
            "required": true,
            "description": "`componentReturns` is one series per component, all covering the same periods. `baseLevel` is the index value at the start of the series; it scales the level but never the returns.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ componentIds, portfolioReturns, levels, endingLevel }",
          "description": "The blended return series and level."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the weights and components differ in length, or the return series are ragged",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × components)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F05-A06.json",
        "call": "calculate({\"componentIds\":[\"Equity\",\"Bond\",\"Commodity\"],\"weights\":[0.5,0.3,0.2],\"componentReturns\":[[0.01,0.002,-0.004],[-0.006,0.003,0.008],[0.004,-0.001,0.002]],\"baseLevel\":1000})",
        "args": [
          {
            "value": {
              "componentIds": [
                "Equity",
                "Bond",
                "Commodity"
              ],
              "weights": [
                0.5,
                0.3,
                0.2
              ],
              "componentReturns": [
                [
                  0.01,
                  0.002,
                  -0.004
                ],
                [
                  -0.006,
                  0.003,
                  0.008
                ],
                [
                  0.004,
                  -0.001,
                  0.002
                ]
              ],
              "baseLevel": 1000
            },
            "elided": null
          }
        ],
        "output": {
          "componentIds": [
            "Equity",
            "Bond",
            "Commodity"
          ],
          "portfolioReturns": [
            0.0048,
            -0.0005,
            0.0021,
            0.0035,
            0
          ],
          "levels": [
            1000,
            1004.8,
            1004.2976,
            1006.406625,
            1009.929048,
            1009.929048
          ],
          "endingLevel": 1009.929048
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: componentIds, portfolioReturns, levels, endingLevel"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a06/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a06/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f05-a06/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Index-of-Indices calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Index-of-Indices\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Index-of-Indices methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/strategy-indices/index-of-indices/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/strategy-indices/index-of-indices/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F06-A01",
      "name": "Eligibility Screen",
      "headline": null,
      "slug": "eligibility-screen",
      "path": "index-and-benchmark-engineering/governance-and-maintenance/eligibility-screen",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F06",
        "family": "Governance and Maintenance",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/governance-and-maintenance/eligibility-screen",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Applies the qualification rules that decide what may be considered for membership at all — domicile, listing status, share class, and the rest. The first gate, and the one that defines what the index claims to represent.",
        "params": [
          {
            "name": "data",
            "type": "{ candidates: Candidate[] }",
            "required": true,
            "description": "Each candidate carries the attributes the rules test. The rules travel with the data rather than being hard-coded, so a rule change is a data change.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ results, eligibleIds, rejectedCount }",
          "description": "A per-candidate result naming which rule rejected it — a rejection without a reason cannot be appealed or audited."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a candidate is missing an attribute a rule requires",
            "behaviour": "recorded as a rejection reason rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(n × rules)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F06-A01.json",
        "call": "calculate({\"candidates\":[{\"id\":\"A\",\"primaryListing\":true,\"eligibleType\":true,\"minPricePass\":true,\"historyPass\":true},{\"id\":\"B\",\"primaryListing\":false,\"eligibleType\":true,\"minPricePass\":true,\"historyPass\":true},{\"id\":\"C\",\"primaryListing\":true,\"eligibleType\":true,\"minPricePass\":false,\"historyPass\":true}]})",
        "args": [
          {
            "value": {
              "candidates": [
                {
                  "id": "A",
                  "primaryListing": true,
                  "eligibleType": true,
                  "minPricePass": true,
                  "historyPass": true
                },
                {
                  "id": "B",
                  "primaryListing": false,
                  "eligibleType": true,
                  "minPricePass": true,
                  "historyPass": true
                },
                {
                  "id": "C",
                  "primaryListing": true,
                  "eligibleType": true,
                  "minPricePass": false,
                  "historyPass": true
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "results": [
            {
              "id": "A",
              "eligible": true,
              "reasons": []
            },
            {
              "id": "B",
              "eligible": false,
              "reasons": [
                "primaryListing"
              ]
            },
            {
              "id": "C",
              "eligible": false,
              "reasons": [
                "minPricePass"
              ]
            }
          ],
          "eligibleIds": [
            "A",
            "D"
          ],
          "rejectedCount": 3
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: results, eligibleIds, rejectedCount"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a01/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a01/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a01/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Eligibility Screen calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Eligibility Screen\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Eligibility Screen methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/governance-and-maintenance/eligibility-screen/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/governance-and-maintenance/eligibility-screen/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F06-A02",
      "name": "Liquidity Screen",
      "headline": null,
      "slug": "liquidity-screen",
      "path": "index-and-benchmark-engineering/governance-and-maintenance/liquidity-screen",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F06",
        "family": "Governance and Maintenance",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/governance-and-maintenance/liquidity-screen",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Requires sustained tradability, not a single good month. Median turnover over a minimum number of months is the standard test, and the median is deliberate: a mean is dominated by one spike of activity.",
        "params": [
          {
            "name": "data",
            "type": "{ records: Record[]; minimumMedianTurnover: number; minimumMonths: number }",
            "required": true,
            "description": "`minimumMonths` is the sustained-history requirement, which is what stops a newly listed name qualifying on a burst of IPO volume.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ results, passingIds, threshold }",
          "description": "Per-candidate results with the realised median and the threshold applied."
        },
        "warmup": null,
        "errors": [
          {
            "when": "minimumMonths is less than 1",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × months)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F06-A02.json",
        "call": "calculate({\"records\":[{\"id\":\"A\",\"monthlyTurnover\":[0.18,0.21,0.2,0.17,0.23,0.19]},{\"id\":\"B\",\"monthlyTurnover\":[0.04,0.06,0.05,0.03,0.05,0.04]},{\"id\":\"C\",\"monthlyTurnover\":[0.12,0.11,0.14,0.1,0.13,0.12]}],\"minimumMedianTurnover\":0.08,\"minimumMonths\":6})",
        "args": [
          {
            "value": {
              "records": [
                {
                  "id": "A",
                  "monthlyTurnover": [
                    0.18,
                    0.21,
                    0.2,
                    0.17,
                    0.23,
                    0.19
                  ]
                },
                {
                  "id": "B",
                  "monthlyTurnover": [
                    0.04,
                    0.06,
                    0.05,
                    0.03,
                    0.05,
                    0.04
                  ]
                },
                {
                  "id": "C",
                  "monthlyTurnover": [
                    0.12,
                    0.11,
                    0.14,
                    0.1,
                    0.13,
                    0.12
                  ]
                }
              ],
              "minimumMedianTurnover": 0.08,
              "minimumMonths": 6
            },
            "elided": null
          }
        ],
        "output": {
          "results": [
            {
              "id": "A",
              "medianTurnover": 0.195,
              "passes": true
            },
            {
              "id": "B",
              "medianTurnover": 0.045,
              "passes": false
            },
            {
              "id": "C",
              "medianTurnover": 0.12,
              "passes": true
            }
          ],
          "passingIds": [
            "A",
            "C",
            "D"
          ],
          "threshold": 0.08
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: results, passingIds, threshold"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a02/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a02/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a02/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Liquidity Screen calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Liquidity Screen\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Liquidity Screen methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/governance-and-maintenance/liquidity-screen/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/governance-and-maintenance/liquidity-screen/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F06-A03",
      "name": "Free-Float Factor Calculation",
      "headline": null,
      "slug": "free-float-factor-calculation",
      "path": "index-and-benchmark-engineering/governance-and-maintenance/free-float-factor-calculation",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F06",
        "family": "Governance and Maintenance",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/governance-and-maintenance/free-float-factor-calculation",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Derives the free-float factor by removing strategic, government, insider and cross-holdings, then rounds it to a band. Rounding is deliberate: unrounded factors would force a weight change every time a holding moved a fraction of a percent.",
        "params": [
          {
            "name": "data",
            "type": "{ records: Record[]; roundingStep: number }",
            "required": true,
            "description": "`roundingStep` is the band width — 5% is common. It trades a little precision for a great deal less turnover.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ results, roundingStep }",
          "description": "The raw and rounded factor per constituent, with the excluded holdings that produced it."
        },
        "warmup": null,
        "errors": [
          {
            "when": "roundingStep is not between 0 and 1",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × holdings)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F06-A03.json",
        "call": "calculate({\"records\":[{\"id\":\"A\",\"issuedShares\":1000000,\"strategicShares\":280000},{\"id\":\"B\",\"issuedShares\":2000000,\"strategicShares\":900000},{\"id\":\"C\",\"issuedShares\":500000,\"strategicShares\":25000}],\"roundingStep\":0.05})",
        "args": [
          {
            "value": {
              "records": [
                {
                  "id": "A",
                  "issuedShares": 1000000,
                  "strategicShares": 280000
                },
                {
                  "id": "B",
                  "issuedShares": 2000000,
                  "strategicShares": 900000
                },
                {
                  "id": "C",
                  "issuedShares": 500000,
                  "strategicShares": 25000
                }
              ],
              "roundingStep": 0.05
            },
            "elided": null
          }
        ],
        "output": {
          "results": [
            {
              "id": "A",
              "rawFreeFloat": 0.72,
              "freeFloatFactor": 0.75
            },
            {
              "id": "B",
              "rawFreeFloat": 0.55,
              "freeFloatFactor": 0.55
            },
            {
              "id": "C",
              "rawFreeFloat": 0.95,
              "freeFloatFactor": 0.95
            }
          ],
          "roundingStep": 0.05
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: results, roundingStep"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a03/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a03/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a03/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Free-Float Factor Calculation calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Free-Float Factor Calculation\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Free-Float Factor Calculation methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/governance-and-maintenance/free-float-factor-calculation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/governance-and-maintenance/free-float-factor-calculation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F06-A04",
      "name": "IPO Fast-Entry Rule",
      "headline": null,
      "slug": "ipo-fast-entry-rule",
      "path": "index-and-benchmark-engineering/governance-and-maintenance/ipo-fast-entry-rule",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F06",
        "family": "Governance and Maintenance",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/governance-and-maintenance/ipo-fast-entry-rule",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Admits a large new listing between scheduled reviews. Without a fast-entry rule an index can spend months not holding one of the biggest companies in its own market.",
        "params": [
          {
            "name": "data",
            "type": "{ candidates: Candidate[]; minimumFloatMarketCap: number; minimumLiquidityDays: number; minimumTradingDays: number }",
            "required": true,
            "description": "The three thresholds are simultaneous: size alone does not qualify a listing that has not yet traded enough to be buyable.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ results, fastEntryIds }",
          "description": "Which candidates qualify and which threshold blocked the rest."
        },
        "warmup": null,
        "errors": [
          {
            "when": "any threshold is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F06-A04.json",
        "call": "calculate({\"candidates\":[{\"id\":\"IPO-A\",\"floatMarketCap\":1800,\"liquidityDays\":10,\"tradingDays\":10},{\"id\":\"IPO-B\",\"floatMarketCap\":900,\"liquidityDays\":9,\"tradingDays\":10},{\"id\":\"IPO-C\",\"floatMarketCap\":2200,\"liquidityDays\":4,\"tradingDays\":5}],\"minimumFloatMarketCap\":1500,\"minimumLiquidityDays\":5,\"minimumTradingDays\":5})",
        "args": [
          {
            "value": {
              "candidates": [
                {
                  "id": "IPO-A",
                  "floatMarketCap": 1800,
                  "liquidityDays": 10,
                  "tradingDays": 10
                },
                {
                  "id": "IPO-B",
                  "floatMarketCap": 900,
                  "liquidityDays": 9,
                  "tradingDays": 10
                },
                {
                  "id": "IPO-C",
                  "floatMarketCap": 2200,
                  "liquidityDays": 4,
                  "tradingDays": 5
                }
              ],
              "minimumFloatMarketCap": 1500,
              "minimumLiquidityDays": 5,
              "minimumTradingDays": 5
            },
            "elided": null
          }
        ],
        "output": {
          "results": [
            {
              "id": "IPO-A",
              "sizePass": true,
              "liquidityPass": true,
              "seasoningPass": true,
              "fastEntry": true
            },
            {
              "id": "IPO-B",
              "sizePass": false,
              "liquidityPass": true,
              "seasoningPass": true,
              "fastEntry": false
            },
            {
              "id": "IPO-C",
              "sizePass": true,
              "liquidityPass": false,
              "seasoningPass": true,
              "fastEntry": false
            }
          ],
          "fastEntryIds": [
            "IPO-A"
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: results, fastEntryIds"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a04/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a04/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a04/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "IPO Fast-Entry Rule calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate IPO Fast-Entry Rule\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "IPO Fast-Entry Rule methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/governance-and-maintenance/ipo-fast-entry-rule/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/governance-and-maintenance/ipo-fast-entry-rule/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F06-A05",
      "name": "Reconstitution Algorithm",
      "headline": null,
      "slug": "reconstitution-algorithm",
      "path": "index-and-benchmark-engineering/governance-and-maintenance/reconstitution-algorithm",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F06",
        "family": "Governance and Maintenance",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/governance-and-maintenance/reconstitution-algorithm",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Chooses the membership at a scheduled review, using an incumbent buffer so a name hovering at the boundary is not swapped in and out every period. The buffer is what separates an index from a churn machine.",
        "params": [
          {
            "name": "data",
            "type": "{ candidates: Candidate[]; targetCount: number; incumbentBuffer: number }",
            "required": true,
            "description": "`incumbentBuffer` lets an existing member stay while it ranks within the buffer beyond the cutoff — asymmetric on purpose, because turnover costs the tracking funds real money.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ selectedIds, additions, deletions, targetCount }",
          "description": "The new membership with the explicit adds and drops it implies."
        },
        "warmup": null,
        "errors": [
          {
            "when": "targetCount exceeds the candidate count",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F06-A05.json",
        "call": "calculate({\"candidates\":[{\"id\":\"A\",\"score\":98,\"incumbent\":true},{\"id\":\"B\",\"score\":94,\"incumbent\":true},{\"id\":\"C\",\"score\":90,\"incumbent\":false}],\"targetCount\":5,\"incumbentBuffer\":1})",
        "args": [
          {
            "value": {
              "candidates": [
                {
                  "id": "A",
                  "score": 98,
                  "incumbent": true
                },
                {
                  "id": "B",
                  "score": 94,
                  "incumbent": true
                },
                {
                  "id": "C",
                  "score": 90,
                  "incumbent": false
                }
              ],
              "targetCount": 5,
              "incumbentBuffer": 1
            },
            "elided": null
          }
        ],
        "output": {
          "selectedIds": [
            "A",
            "B",
            "C",
            "D",
            "F"
          ],
          "additions": [
            "C"
          ],
          "deletions": [],
          "targetCount": 5
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: selectedIds, additions, deletions, targetCount"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a05/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a05/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a05/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Reconstitution Algorithm calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Reconstitution Algorithm\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Reconstitution Algorithm methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/governance-and-maintenance/reconstitution-algorithm/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/governance-and-maintenance/reconstitution-algorithm/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F06-A06",
      "name": "Rebalancing Algorithm",
      "headline": null,
      "slug": "rebalancing-algorithm",
      "path": "index-and-benchmark-engineering/governance-and-maintenance/rebalancing-algorithm",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F06",
        "family": "Governance and Maintenance",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/governance-and-maintenance/rebalancing-algorithm",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Turns a weight change into the trades that implement it, and reports the turnover. Turnover is the number that predicts what tracking the index will cost.",
        "params": [
          {
            "name": "data",
            "type": "{ records: Record[]; notional: number }",
            "required": true,
            "description": "`records` carry current and target weights per constituent; `notional` is the portfolio size the trades are sized against.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ trades, oneWayTurnover, grossTradeValue }",
          "description": "The trade list plus one-way turnover — stated as one-way explicitly, because quoting two-way turnover doubles the apparent cost."
        },
        "warmup": null,
        "errors": [
          {
            "when": "notional is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F06-A06.json",
        "call": "calculate({\"records\":[{\"id\":\"A\",\"price\":50,\"oldWeight\":0.35,\"targetWeight\":0.3},{\"id\":\"B\",\"price\":25,\"oldWeight\":0.25,\"targetWeight\":0.3},{\"id\":\"C\",\"price\":80,\"oldWeight\":0.22,\"targetWeight\":0.2}],\"notional\":100000000})",
        "args": [
          {
            "value": {
              "records": [
                {
                  "id": "A",
                  "price": 50,
                  "oldWeight": 0.35,
                  "targetWeight": 0.3
                },
                {
                  "id": "B",
                  "price": 25,
                  "oldWeight": 0.25,
                  "targetWeight": 0.3
                },
                {
                  "id": "C",
                  "price": 80,
                  "oldWeight": 0.22,
                  "targetWeight": 0.2
                }
              ],
              "notional": 100000000
            },
            "elided": null
          }
        ],
        "output": {
          "trades": [
            {
              "id": "A",
              "tradeValue": -5000000,
              "targetIndexShares": 600000
            },
            {
              "id": "B",
              "tradeValue": 5000000,
              "targetIndexShares": 1200000
            },
            {
              "id": "C",
              "tradeValue": -2000000,
              "targetIndexShares": 250000
            }
          ],
          "oneWayTurnover": 0.07,
          "grossTradeValue": 14000000
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: trades, oneWayTurnover, grossTradeValue"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a06/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a06/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a06/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Rebalancing Algorithm calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Rebalancing Algorithm\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Rebalancing Algorithm methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/governance-and-maintenance/rebalancing-algorithm/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/governance-and-maintenance/rebalancing-algorithm/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F06-A07",
      "name": "Turnover Buffer Rule",
      "headline": null,
      "slug": "turnover-buffer-rule",
      "path": "index-and-benchmark-engineering/governance-and-maintenance/turnover-buffer-rule",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F06",
        "family": "Governance and Maintenance",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/governance-and-maintenance/turnover-buffer-rule",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "The buffer in isolation: a band around the cutoff inside which incumbents keep their place. Widening it cuts turnover and lets the membership drift further from the pure ranking — that trade-off is the whole design decision.",
        "params": [
          {
            "name": "data",
            "type": "{ candidates: Candidate[]; targetCount: number; buffer: number }",
            "required": true,
            "description": "`buffer` is expressed in ranks or in weight, depending on the index's own rulebook.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ selectedIds, additions, deletions, targetCount }",
          "description": "The membership after the buffer is applied, with the changes it permitted."
        },
        "warmup": null,
        "errors": [
          {
            "when": "buffer is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F06-A07.json",
        "call": "calculate({\"candidates\":[{\"id\":\"A\",\"rank\":1,\"incumbent\":true},{\"id\":\"B\",\"rank\":2,\"incumbent\":false},{\"id\":\"C\",\"rank\":3,\"incumbent\":true}],\"targetCount\":5,\"buffer\":1})",
        "args": [
          {
            "value": {
              "candidates": [
                {
                  "id": "A",
                  "rank": 1,
                  "incumbent": true
                },
                {
                  "id": "B",
                  "rank": 2,
                  "incumbent": false
                },
                {
                  "id": "C",
                  "rank": 3,
                  "incumbent": true
                }
              ],
              "targetCount": 5,
              "buffer": 1
            },
            "elided": null
          }
        ],
        "output": {
          "selectedIds": [
            "A",
            "B",
            "C",
            "E",
            "F"
          ],
          "additions": [
            "B"
          ],
          "deletions": [],
          "targetCount": 5
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: selectedIds, additions, deletions, targetCount"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a07/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a07/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a07/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Turnover Buffer Rule calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Turnover Buffer Rule\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Turnover Buffer Rule methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/governance-and-maintenance/turnover-buffer-rule/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/governance-and-maintenance/turnover-buffer-rule/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D03-F06-A08",
      "name": "Index Replication-Cost Estimator",
      "headline": null,
      "slug": "index-replication-cost-estimator",
      "path": "index-and-benchmark-engineering/governance-and-maintenance/index-replication-cost-estimator",
      "taxonomy": {
        "domainId": "D03",
        "domain": "Index and Benchmark Engineering",
        "familyId": "D03-F06",
        "family": "Governance and Maintenance",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/index-and-benchmark-engineering/governance-and-maintenance/index-replication-cost-estimator",
        "entry": "calculate",
        "params": [
          "data"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(data)"
      },
      "api": {
        "summary": "Estimates what a rebalance costs to implement — spread, market impact and commission. This is where the rulebook meets reality: a screen that looks clean on paper can be expensive to track.",
        "params": [
          {
            "name": "data",
            "type": "{ trades: Trade[] }",
            "required": true,
            "description": "Each trade carries size, spread and the liquidity measures the impact model consumes.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ results, estimatedCost, costBpsOnGrossTrade }",
          "description": "Per-trade costs plus the total in basis points of gross traded value, which is the unit these are compared in."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a trade is missing a liquidity input the model requires",
            "behaviour": "recorded on the result rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D03-F06-A08.json",
        "call": "calculate({\"trades\":[{\"id\":\"A\",\"tradeValue\":12000000,\"spreadBps\":6,\"impactCoefficientBps\":18,\"participation\":0.08},{\"id\":\"B\",\"tradeValue\":-7000000,\"spreadBps\":10,\"impactCoefficientBps\":25,\"participation\":0.12},{\"id\":\"C\",\"tradeValue\":3500000,\"spreadBps\":14,\"impactCoefficientBps\":30,\"participation\":0.18}]})",
        "args": [
          {
            "value": {
              "trades": [
                {
                  "id": "A",
                  "tradeValue": 12000000,
                  "spreadBps": 6,
                  "impactCoefficientBps": 18,
                  "participation": 0.08
                },
                {
                  "id": "B",
                  "tradeValue": -7000000,
                  "spreadBps": 10,
                  "impactCoefficientBps": 25,
                  "participation": 0.12
                },
                {
                  "id": "C",
                  "tradeValue": 3500000,
                  "spreadBps": 14,
                  "impactCoefficientBps": 30,
                  "participation": 0.18
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "results": [
            {
              "id": "A",
              "spreadCost": 3600,
              "impactCost": 6109.402589,
              "totalCost": 9709.402589
            },
            {
              "id": "B",
              "spreadCost": 3500,
              "impactCost": 6062.177826,
              "totalCost": 9562.177826
            },
            {
              "id": "C",
              "spreadCost": 2450,
              "impactCost": 4454.772721,
              "totalCost": 6904.772721
            }
          ],
          "estimatedCost": 28401.098007,
          "costBpsOnGrossTrade": 11.360439
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: results, estimatedCost, costBpsOnGrossTrade"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a08/static/article-hero.svg"
          },
          {
            "file": "failure-guard.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a08/static/failure-guard.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d03-f06-a08/static/worked-example.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Index Replication-Cost Estimator calculation flow",
            "source": "flowchart LR\n    A[\"Point-in-time inputs\"] --> B[\"Validate units and timing\"]\n    B --> C{\"Contract feasible?\"}\n    C -->|No| D[\"Reject with reason\"]\n    C -->|Yes| E[\"Calculate Index Replication-Cost Estimator\"]\n    E --> F[\"Recompute invariants\"]\n    F --> G{\"Checks pass?\"}\n    G -->|No| D\n    G -->|Yes| H[\"Publish audited output\"]"
          },
          {
            "file": "methodology-state.md",
            "caption": "Index Replication-Cost Estimator methodology state",
            "source": "stateDiagram-v2\n    [*] --> FrozenInputs\n    FrozenInputs --> Validated: contract passes\n    FrozenInputs --> Rejected: missing or infeasible\n    Validated --> Calculated: apply named rule\n    Calculated --> Audited: invariants pass\n    Calculated --> Rejected: invariant fails\n    Audited --> Published: version and timestamp recorded\n    Published --> Revised: approved correction\n    Revised --> FrozenInputs: rebuild from retained source state"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "S&P Dow Jones Indices Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        },
        {
          "key": "R2",
          "title": "S&P DJI Equity Indices Policies & Practices",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-equity-indices-policies-practices.pdf"
        },
        {
          "key": "R3",
          "title": "FTSE Russell Capping Methodology",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/policy-documents/capping-methodology-guide.pdf"
        },
        {
          "key": "R4",
          "title": "FTSE Russell Index Policy and Methodology Library",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/en/ftse-russell/governance/index-policy-and-methodology"
        },
        {
          "key": "R5",
          "title": "MSCI Global Investable Market Indexes Methodology Library",
          "author": "MSCI",
          "url": "https://www.msci.com/eqb/gimi/stdindex/methodology.html"
        },
        {
          "key": "R6",
          "title": "MSCI Minimum Volatility Indexes Methodology",
          "author": "MSCI",
          "url": "https://www.msci.com/msci-minimum-volatility-indexes"
        },
        {
          "key": "R7",
          "title": "S&P Risk Control 2.0 Indices Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-sp-risk-control-2-indices.pdf"
        },
        {
          "key": "R8",
          "title": "Principles for Financial Benchmarks",
          "author": "International Organization of Securities Commissions",
          "url": "https://www.iosco.org/library/pubdocs/pdf/ioscopd415.pdf"
        },
        {
          "key": "R9",
          "title": "Regulation (EU) 2016/1011",
          "author": "European Union",
          "url": "https://eur-lex.europa.eu/eli/reg/2016/1011"
        },
        {
          "key": "R10",
          "title": "Portfolio Selection",
          "author": "Harry Markowitz",
          "url": "https://doi.org/10.1111/j.1540-6261.1952.tb01525.x"
        },
        {
          "key": "R11",
          "title": "On the Properties of Equally-Weighted Risk Contributions Portfolios",
          "author": "Sébastien Maillard, Thierry Roncalli, and Jérôme Teïletche",
          "url": "https://doi.org/10.3905/jpm.2010.36.4.060"
        },
        {
          "key": "R12",
          "title": "Fundamental Indexation",
          "author": "Robert Arnott, Jason Hsu, and Philip Moore",
          "url": "https://www.researchaffiliates.com/documents/FAJ_Mar_Apr_2005_Fundamental_Indexation.pdf"
        },
        {
          "key": "R13",
          "title": "FTSE Currency Hedging Methodology Overview",
          "author": "FTSE Russell, LSEG",
          "url": "https://www.lseg.com/content/dam/ftse-russell/en_us/documents/other/ftse-currency-hedging-methodology-cut-sheet.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/index-and-benchmark-engineering/governance-and-maintenance/index-replication-cost-estimator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/index-and-benchmark-engineering/governance-and-maintenance/index-replication-cost-estimator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F01-A01",
      "name": "Net Advances",
      "headline": "Count Participation Without Hiding Data Gaps",
      "slug": "net-advances",
      "path": "market-breadth-and-internals/advance-decline-breadth/net-advances",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F01",
        "family": "Advance/Decline Breadth",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/advance-decline-breadth/net-advances",
        "entry": "calculateNetAdvances",
        "params": [
          "request"
        ],
        "exports": [
          "calculateNetAdvances"
        ],
        "archetype": "record-transform",
        "signature": "calculateNetAdvances(request)"
      },
      "api": {
        "summary": "Advances minus declines for a session. The simplest breadth measure and the input to most of the others — its value is that it counts companies rather than weighting them, so it says what *most* of the market did.",
        "params": [
          {
            "name": "request",
            "type": "BreadthRequest",
            "required": true,
            "description": "Carries the session identity (`session_date`, `session_id`, `venue_id`, `universe_id`) plus the rules that decide what counts as an advance: `comparison_basis` (which price is compared against which), `corporate_action_policy`, and `price_tolerance` for unchanged. `calculation_as_of` bounds which revisions are usable.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, direction, metric, session_date, universe_id, … }",
          "description": "The count with a `status` and the full identity of what was counted — two systems disagreeing on breadth almost always disagree about the universe, not the arithmetic."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the comparison basis or corporate-action policy is unrecognised",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(members)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F01-A01.json",
        "call": "calculateNetAdvances({\"session_date\":\"2026-01-05\",\"session_id\":\"regular\",\"session_timezone\":\"UTC\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-3\",\"comparison_basis\":\"comparable-prior-close\",\"corporate_action_policy\":\"provider-adjusted\",\"price_tolerance\":0,\"calculation_as_of\":\"2026-01-05T22:00:00Z\",\"revisions\":[{\"revision_id\":\"R1\",\"revision_sequence\":1,\"supersedes_revision_id\":null,\"effective_at\":\"2026-01-05T21:00:00Z\",\"available_at\":\"2026-01-05T21:05:00Z\",\"is_final\":true,\"members\":[{\"listing_id\":\"L-A\",\"security_id\":\"S-A\",\"ticker\":\"A\",\"state\":\"eligible\",\"current_price\":11,\"prior_comparable_price\":10},{\"listing_id\":\"L-D\",\"security_id\":\"S-D\",\"ticker\":\"D\",\"state\":\"eligible\",\"current_price\":9,\"prior_comparable_price\":10},{\"listing_id\":\"L-U\",\"security_id\":\"S-U\",\"ticker\":\"U\",\"state\":\"eligible\",\"current_price\":10,\"prior_comparable_price\":10}]}]})",
        "args": [
          {
            "value": {
              "session_date": "2026-01-05",
              "session_id": "regular",
              "session_timezone": "UTC",
              "venue_id": "SYNTH-X",
              "universe_id": "SYNTH-3",
              "comparison_basis": "comparable-prior-close",
              "corporate_action_policy": "provider-adjusted",
              "price_tolerance": 0,
              "calculation_as_of": "2026-01-05T22:00:00Z",
              "revisions": [
                {
                  "revision_id": "R1",
                  "revision_sequence": 1,
                  "supersedes_revision_id": null,
                  "effective_at": "2026-01-05T21:00:00Z",
                  "available_at": "2026-01-05T21:05:00Z",
                  "is_final": true,
                  "members": [
                    {
                      "listing_id": "L-A",
                      "security_id": "S-A",
                      "ticker": "A",
                      "state": "eligible",
                      "current_price": 11,
                      "prior_comparable_price": 10
                    },
                    {
                      "listing_id": "L-D",
                      "security_id": "S-D",
                      "ticker": "D",
                      "state": "eligible",
                      "current_price": 9,
                      "prior_comparable_price": 10
                    },
                    {
                      "listing_id": "L-U",
                      "security_id": "S-U",
                      "ticker": "U",
                      "state": "eligible",
                      "current_price": 10,
                      "prior_comparable_price": 10
                    }
                  ]
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "status": "ready",
          "direction": "balanced",
          "selected_revision_id": "R1",
          "advances": 1,
          "declines": 1,
          "unchanged": 1,
          "excluded": 0,
          "unclassified": 0,
          "universe_size": 3,
          "mover_count": 2,
          "classified_count": 3,
          "coverage_ratio": 1,
          "net_advances": 0,
          "is_provisional": false
        },
        "outputElided": null,
        "outputShape": "object with 14 fields: status, direction, selected_revision_id, advances, declines, unchanged, excluded, unclassified, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "historical-opposite-breadth.svg",
            "url": "https://thefintechbuilder.com/content/d04-f01-a01/static/historical-opposite-breadth.svg"
          },
          {
            "file": "net-advances-balance.svg",
            "url": "https://thefintechbuilder.com/content/d04-f01-a01/static/net-advances-balance.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Net Advances evidence and calculation flow",
            "source": "flowchart TD\n    A[\"Session, universe, identity, and price policy\"] --> B[\"Select revision effective and available by query time\"]\n    B --> C{\"Unique revision chain and listing IDs?\"}\n    C -- \"No\" --> D[\"ambiguous; net is null\"]\n    C -- \"Yes\" --> E[\"Classify every point-in-time member\"]\n    E --> F{\"Missing or unclassified evidence?\"}\n    F -- \"Yes\" --> G[\"incomplete; net is null\"]\n    F -- \"No\" --> H[\"Reconcile A + D + U + X = N\"]\n    H --> I{\"Universe or movers empty?\"}\n    I -- \"Universe empty\" --> J[\"empty_universe; net 0\"]\n    I -- \"No movers\" --> K[\"no_movers; net 0\"]\n    I -- \"Movers present\" --> L[\"ready; net = A - D\"]"
          },
          {
            "file": "snapshot-lifecycle.md",
            "caption": "Revision lifecycle with two clocks",
            "source": "flowchart LR\n    S[\"Session close effective 21:00\"] --> R1[\"R1 available 21:05\"]\n    R1 --> Q1[\"21:30 query selects R1: 5 - 3 = +2\"]\n    S --> R2[\"R2 correction available 22:00\"]\n    R2 --> Q2[\"22:30 query selects R2: 4 - 4 = 0\"]\n    R2 -. \"Unavailable at 21:30\" .-> N[\"Must not affect or appear in Q1\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R1 - Nasdaq A-D glossary",
          "title": "R1 - Nasdaq A-D glossary",
          "author": null,
          "url": null
        },
        {
          "key": "R2 - Nasdaq Daily Market Summary definitions",
          "title": "R2 - Nasdaq Daily Market Summary definitions",
          "author": null,
          "url": null
        },
        {
          "key": "R3 - Nasdaq Daily Market Files and 2026 CSV",
          "title": "R3 - Nasdaq Daily Market Files and 2026 CSV",
          "author": null,
          "url": null
        },
        {
          "key": "R4 - Consolidated Tape System output specification",
          "title": "R4 - Consolidated Tape System output specification",
          "author": null,
          "url": null
        },
        {
          "key": "R5 - FINRA TRACE End of Day Market Breadth correction",
          "title": "R5 - FINRA TRACE End of Day Market Breadth correction",
          "author": null,
          "url": null
        },
        {
          "key": "R6 - NYSE Daily TAQ catalog and reference data",
          "title": "R6 - NYSE Daily TAQ catalog and reference data",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/advance-decline-breadth/net-advances/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Net-Advances-Market-Breadth-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/advance-decline-breadth/net-advances/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F01-A02",
      "name": "Advance/Decline Ratio",
      "headline": "Advancing Issues per Declining Issue",
      "slug": "advance-decline-ratio",
      "path": "market-breadth-and-internals/advance-decline-breadth/advance-decline-ratio",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F01",
        "family": "Advance/Decline Breadth",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/advance-decline-breadth/advance-decline-ratio",
        "entry": "calculateAdvanceDeclineRatio",
        "params": [
          "snapshot"
        ],
        "exports": [
          "calculateAdvanceDeclineRatio",
          "evaluateAdvanceDeclineRatioAsOf"
        ],
        "archetype": "record-transform",
        "signature": "calculateAdvanceDeclineRatio(snapshot)"
      },
      "api": {
        "summary": "Advances divided by declines. Scale-free where net advances is not, so readings stay comparable as the universe grows — the reason a raw A/D count from the 1960s cannot be compared with one from today.",
        "params": [
          {
            "name": "snapshot",
            "type": "BreadthSnapshot",
            "required": true,
            "description": "One session's counts with their evidence state and full identity — venue, calendar, session and universe.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ evidence_state, ratio_state, advance_decline_ratio, direction, observed_partition_ratio, observed }",
          "description": "The ratio plus a separate `evidence_state` and `ratio_state`, which distinguish a genuine reading from one the data could not support."
        },
        "warmup": null,
        "errors": [
          {
            "when": "declines is zero, making the ratio undefined",
            "behaviour": "reported as a ratio_state rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F01-A02.json",
        "call": "calculateAdvanceDeclineRatio({\"series_id\":\"SYNTH-ADR\",\"record_id\":\"ADR-R1\",\"session_date\":\"2026-01-05\",\"effective_at\":\"2026-01-05T21:00:00Z\",\"available_at\":\"2026-01-05T21:05:00Z\",\"venue_id\":\"SYNTH-X\",\"calendar_id\":\"SYNTH-CAL\",\"session_id\":\"regular\",\"universe_id\":\"SYNTH-100\",\"universe_revision\":\"U1\",\"listing_id_scheme\":\"synthetic-listing-id\",\"security_type_policy\":\"common-equity\",\"comparison_basis\":\"comparable-prior-close\",\"corporate_action_policy\":\"provider-adjusted\"})",
        "args": [
          {
            "value": {
              "series_id": "SYNTH-ADR",
              "record_id": "ADR-R1",
              "session_date": "2026-01-05",
              "effective_at": "2026-01-05T21:00:00Z",
              "available_at": "2026-01-05T21:05:00Z",
              "venue_id": "SYNTH-X",
              "calendar_id": "SYNTH-CAL",
              "session_id": "regular",
              "universe_id": "SYNTH-100",
              "universe_revision": "U1",
              "listing_id_scheme": "synthetic-listing-id",
              "security_type_policy": "common-equity",
              "comparison_basis": "comparable-prior-close",
              "corporate_action_policy": "provider-adjusted"
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 27
            }
          }
        ],
        "output": {
          "evidence_state": "resolved",
          "ratio_state": "finite",
          "advance_decline_ratio": 2,
          "direction": "advances_dominant",
          "observed_partition_ratio": 2,
          "selected_record_id": "ADR-R1",
          "selected_revision": 1,
          "excluded_count": 0,
          "mover_count": 90,
          "classified_count": 100,
          "coverage_ratio": 1,
          "is_provisional": false,
          "reasons": []
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: evidence_state, ratio_state, advance_decline_ratio, direction, observed_partition_ratio, selected_record_id, selected_revision, excluded_count, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "ratio-balance.svg",
            "url": "https://thefintechbuilder.com/content/d04-f01-a02/static/ratio-balance.svg"
          },
          {
            "file": "same-ratio-different-coverage.svg",
            "url": "https://thefintechbuilder.com/content/d04-f01-a02/static/same-ratio-different-coverage.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Evidence and ratio state flow",
            "source": "flowchart TD\n    Q[\"Declared as-of query\"] --> F[\"Match identity, policy, and available time\"]\n    F --> N{\"Eligible snapshot exists?\"}\n    N -->|\"No\"| U[\"unsupported; no metric\"]\n    N -->|\"Yes\"| C{\"Revision chain unique, contiguous, linked?\"}\n    C -->|\"No\"| A[\"ambiguous; no metric\"]\n    C -->|\"Yes\"| P[\"Validate category partition and coverage\"]\n    P --> E{\"Final with no exclusions?\"}\n    E -->|\"No\"| I[\"incomplete; observed diagnostic only\"]\n    E -->|\"Yes\"| R[\"resolved evidence\"]\n    R --> Z{\"Universe or denominator edge?\"}\n    Z -->|\"Empty universe\"| Z1[\"empty_universe; null\"]\n    Z -->|\"No movers\"| Z2[\"no_movers; null\"]\n    Z -->|\"No declines\"| Z3[\"no_declines; null\"]\n    Z -->|\"Declines positive\"| O[\"finite A divided by D\"]"
          },
          {
            "file": "snapshot-lifecycle.md",
            "caption": "Correction-aware snapshot lifecycle",
            "source": "sequenceDiagram\n    participant M as Point-in-time security master\n    participant P as Comparable closing prices\n    participant C as Corporate-action policy\n    participant B as Breadth publisher\n    participant Q as As-of evaluator\n\n    M->>B: Stable listing roster and universe revision\n    P->>B: Current and comparable prior closes\n    C->>B: Adjustment and exclusion decisions\n    B->>Q: Revision 1 with effective_at and available_at\n    Q-->>Q: Use revision 1 before any later correction is available\n    B->>Q: Revision 2 supersedes revision 1\n    Q-->>Q: Use revision 2 only after its available_at\n    B-xQ: Conflicting or broken chain\n    Q-->>Q: Return ambiguous rather than guess"
          }
        ]
      },
      "references": [
        {
          "key": "R01 - Advance/Decline Ratio glossary",
          "title": "R01 - Advance/Decline Ratio glossary",
          "author": null,
          "url": null
        },
        {
          "key": "R02 - Daily Market Files landing page",
          "title": "R02 - Daily Market Files landing page",
          "author": null,
          "url": null
        },
        {
          "key": "R03 - 2026 Daily Market Statistics CSV",
          "title": "R03 - 2026 Daily Market Statistics CSV",
          "author": null,
          "url": null
        },
        {
          "key": "R04 - Daily TAQ catalog",
          "title": "R04 - Daily TAQ catalog",
          "author": null,
          "url": null
        },
        {
          "key": "R05 - TAQ NYSE Closing Prices Client Specification",
          "title": "R05 - TAQ NYSE Closing Prices Client Specification",
          "author": null,
          "url": null
        },
        {
          "key": "R06 - NYSE Reference Data",
          "title": "R06 - NYSE Reference Data",
          "author": null,
          "url": null
        },
        {
          "key": "R07 - NYSE Corporate Actions",
          "title": "R07 - NYSE Corporate Actions",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/advance-decline-breadth/advance-decline-ratio/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Advance-Decline-Ratio-Market-Breadth-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/advance-decline-breadth/advance-decline-ratio/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F01-A03",
      "name": "Cumulative Advance/Decline Line",
      "headline": "Recompute History Without Looking Ahead",
      "slug": "cumulative-advance-decline-line",
      "path": "market-breadth-and-internals/advance-decline-breadth/cumulative-advance-decline-line",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F01",
        "family": "Advance/Decline Breadth",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/advance-decline-breadth/cumulative-advance-decline-line",
        "entry": "calculateCumulativeAdvanceDeclineLine",
        "params": [
          "contract",
          "events",
          "knowledgeCutoff"
        ],
        "exports": [
          "calculateCumulativeAdvanceDeclineLine"
        ],
        "archetype": "record-transform",
        "signature": "calculateCumulativeAdvanceDeclineLine(contract, events, knowledgeCutoff)"
      },
      "api": {
        "summary": "Runs net advances into a cumulative line. Its level is arbitrary; the information is in the shape, and specifically in divergence — when the index makes a high the line does not, participation is narrowing.",
        "params": [
          {
            "name": "contract",
            "type": "LineContract",
            "required": true,
            "description": "Series identity and the `seed` the accumulation starts from. The seed only shifts the level, never the shape.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "events",
            "type": "BreadthEvent[]",
            "required": true,
            "description": "Session events including revisions and supersessions, each with an ingest sequence.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "knowledgeCutoff",
            "type": "string",
            "required": true,
            "description": "Point-in-time bound. Revisions arriving after the cutoff are ignored rather than applied, so the series is exactly what was computable at that moment. Breadth data is revised routinely, and a cumulative line silently rebuilt from revised inputs is not the line anyone traded.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, reasons, knowledge_cutoff, points, final_value, causal_prefix_diagnostic, missing_sessions, … }",
          "description": "The line plus a causal-prefix diagnostic and the sessions that were missing — a gap in a cumulative series propagates forward forever, so it must be visible."
        },
        "warmup": null,
        "errors": [
          {
            "when": "events are missing an ingest sequence needed to order them",
            "behaviour": "reported in reasons rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(events)",
          "space": "O(sessions)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F01-A03.json",
        "call": "calculateCumulativeAdvanceDeclineLine({\"metric\":\"cumulative_issue_count_advance_decline_line\",\"series_id\":\"SYNTH-AD\",\"continuity_id\":\"SYNTH-CONTINUITY\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-5\",\"calendar_id\":\"SYNTH-CAL\",\"session_type\":\"regular\",\"comparison_basis\":\"comparable-prior-close\",\"seed\":0,\"seed_lineage_id\":\"SEED-0\",\"seed_effective_at\":\"2026-01-04T21:00:00Z\",\"seed_available_at\":\"2026-01-04T21:05:00Z\",\"expected_sessions\":[{\"session_sequence\":1,\"session_date\":\"2026-01-05\"},{\"session_sequence\":2,\"session_date\":\"2026-01-06\"}]}, [{\"event_id\":\"AD-1\",\"ingest_sequence\":1,\"revision_number\":1,\"supersedes_event_id\":null,\"action\":\"upsert\",\"session_sequence\":1,\"session_date\":\"2026-01-05\",\"effective_at\":\"2026-01-05T21:00:00Z\",\"available_at\":\"2026-01-05T21:05:00Z\",\"series_id\":\"SYNTH-AD\",\"continuity_id\":\"SYNTH-CONTINUITY\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-5\",\"calendar_id\":\"SYNTH-CAL\"},{\"event_id\":\"AD-2\",\"ingest_sequence\":2,\"revision_number\":1,\"supersedes_event_id\":null,\"action\":\"upsert\",\"session_sequence\":2,\"session_date\":\"2026-01-06\",\"effective_at\":\"2026-01-06T21:00:00Z\",\"available_at\":\"2026-01-06T21:05:00Z\",\"series_id\":\"SYNTH-AD\",\"continuity_id\":\"SYNTH-CONTINUITY\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-5\",\"calendar_id\":\"SYNTH-CAL\"}], \"2026-01-06T22:00:00Z\")",
        "args": [
          {
            "value": {
              "metric": "cumulative_issue_count_advance_decline_line",
              "series_id": "SYNTH-AD",
              "continuity_id": "SYNTH-CONTINUITY",
              "venue_id": "SYNTH-X",
              "universe_id": "SYNTH-5",
              "calendar_id": "SYNTH-CAL",
              "session_type": "regular",
              "comparison_basis": "comparable-prior-close",
              "seed": 0,
              "seed_lineage_id": "SEED-0",
              "seed_effective_at": "2026-01-04T21:00:00Z",
              "seed_available_at": "2026-01-04T21:05:00Z",
              "expected_sessions": [
                {
                  "session_sequence": 1,
                  "session_date": "2026-01-05"
                },
                {
                  "session_sequence": 2,
                  "session_date": "2026-01-06"
                }
              ]
            },
            "elided": null
          },
          {
            "value": [
              {
                "event_id": "AD-1",
                "ingest_sequence": 1,
                "revision_number": 1,
                "supersedes_event_id": null,
                "action": "upsert",
                "session_sequence": 1,
                "session_date": "2026-01-05",
                "effective_at": "2026-01-05T21:00:00Z",
                "available_at": "2026-01-05T21:05:00Z",
                "series_id": "SYNTH-AD",
                "continuity_id": "SYNTH-CONTINUITY",
                "venue_id": "SYNTH-X",
                "universe_id": "SYNTH-5",
                "calendar_id": "SYNTH-CAL"
              },
              {
                "event_id": "AD-2",
                "ingest_sequence": 2,
                "revision_number": 1,
                "supersedes_event_id": null,
                "action": "upsert",
                "session_sequence": 2,
                "session_date": "2026-01-06",
                "effective_at": "2026-01-06T21:00:00Z",
                "available_at": "2026-01-06T21:05:00Z",
                "series_id": "SYNTH-AD",
                "continuity_id": "SYNTH-CONTINUITY",
                "venue_id": "SYNTH-X",
                "universe_id": "SYNTH-5",
                "calendar_id": "SYNTH-CAL"
              }
            ],
            "elided": null
          },
          {
            "value": "2026-01-06T22:00:00Z",
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "reasons": [],
          "final_value": 1,
          "contains_provisional": false,
          "ignored_future_event_count": 0,
          "points": {
            "0": {
              "session_sequence": 1,
              "net_advances": 2,
              "cumulative_line": 2
            },
            "1": {
              "session_sequence": 2,
              "net_advances": -1,
              "cumulative_line": 1
            }
          }
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: status, reasons, final_value, contains_provisional, ignored_future_event_count, points"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "cumulative-line-staircase.svg",
            "url": "https://thefintechbuilder.com/content/d04-f01-a03/static/cumulative-line-staircase.svg"
          },
          {
            "file": "seed-shift-invariance.svg",
            "url": "https://thefintechbuilder.com/content/d04-f01-a03/static/seed-shift-invariance.svg"
          }
        ],
        "mermaid": [
          {
            "file": "correction-propagation.md",
            "caption": "Revision lineage and suffix recomputation",
            "source": "flowchart LR\n    A[\"Session k revision 1\"] --> B[\"Revision 2 names revision 1 as parent\"]\n    B --> C{\"Revision 2 available by cutoff?\"}\n    C -- \"No\" --> D[\"Keep revision 1\"]\n    C -- \"Yes\" --> E[\"Select revision 2\"]\n    E --> F[\"Recompute session k\"]\n    F --> G[\"Recompute every later session\"]\n    G --> H[\"Publish new resolved suffix\"]"
          },
          {
            "file": "recurrence-flow.md",
            "caption": "Causal recurrence and publication flow",
            "source": "flowchart TD\n    A[\"Continuity contract and knowledge cutoff\"] --> B[\"Parse availability time\"]\n    B --> C{\"Event known by cutoff?\"}\n    C -- \"No\" --> D[\"Ignore future event\"]\n    C -- \"Yes\" --> E[\"Validate visible order, identity, and daily evidence\"]\n    E --> F[\"Select one contiguous revision chain per session\"]\n    F --> G{\"All expected sessions ready and final?\"}\n    G -- \"No\" --> H[\"Suppress main line and label diagnostic prefix\"]\n    G -- \"Yes\" --> I[\"Add Net Advances in declared calendar order\"]\n    I --> J[\"Publish resolved points and final value\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "Nasdaq Trader Daily Market Files",
          "author": null,
          "url": null
        },
        {
          "key": "R2",
          "title": "Nasdaq Trader Daily Market Summary Definitions",
          "author": null,
          "url": null
        },
        {
          "key": "R3",
          "title": "Fidelity advance/decline education",
          "author": null,
          "url": null
        },
        {
          "key": "R4",
          "title": "Nasdaq A-D glossary",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/advance-decline-breadth/cumulative-advance-decline-line/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Cumulative-Advance-Decline-Line-Market-Breadth-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/advance-decline-breadth/cumulative-advance-decline-line/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F01-A04",
      "name": "Normalized Advance/Decline Line",
      "headline": "Cumulative (A-D)/(A+D) Breadth",
      "slug": "normalized-advance-decline-line",
      "path": "market-breadth-and-internals/advance-decline-breadth/normalized-advance-decline-line",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F01",
        "family": "Advance/Decline Breadth",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/advance-decline-breadth/normalized-advance-decline-line",
        "entry": "calculateNormalizedAdLine",
        "params": [
          "records",
          "options"
        ],
        "exports": [
          "calculateNormalizedAdLine"
        ],
        "archetype": "record-transform",
        "signature": "calculateNormalizedAdLine(records, options)"
      },
      "api": {
        "summary": "Divides net advances by the number of issues traded before accumulating, which keeps the line comparable across decades as listing counts change.",
        "params": [
          {
            "name": "records",
            "type": "BreadthRecord[]",
            "required": true,
            "description": "Session records with revision and supersession fields.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "options",
            "type": "{ cutoff: string; expectedStartSequence: number; expectedEndSequence: number; initialValue: number; scale: number; minimumCoverage: number }",
            "required": true,
            "description": "`minimumCoverage` refuses to emit a line when too many sessions are missing, rather than producing one with invisible holes. `scale` sets the units; `cutoff` applies the point-in-time bound.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, reason_codes, points, ignored_future_revisions, denominator_policy, … }",
          "description": "The normalised line with the denominator policy applied and a count of revisions ignored for arriving after the cutoff."
        },
        "warmup": null,
        "errors": [
          {
            "when": "coverage falls below minimumCoverage",
            "behaviour": "reported as a state rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(records)",
          "space": "O(sessions)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F01-A04.json",
        "call": "calculateNormalizedAdLine([{\"event_id\":\"NAD-1\",\"revision\":1,\"supersedes_revision\":null,\"event_type\":\"upsert\",\"session_sequence\":1,\"session_date\":\"2026-01-05\",\"effective_at\":\"2026-01-05T21:00:00Z\",\"available_at\":\"2026-01-05T21:05:00Z\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-100\",\"calendar_id\":\"SYNTH-CAL\",\"session\":\"regular\",\"comparison_basis\":\"comparable-prior-close\",\"corporate_action_policy\":\"provider-adjusted\"},{\"event_id\":\"NAD-2\",\"revision\":1,\"supersedes_revision\":null,\"event_type\":\"upsert\",\"session_sequence\":2,\"session_date\":\"2026-01-06\",\"effective_at\":\"2026-01-06T21:00:00Z\",\"available_at\":\"2026-01-06T21:05:00Z\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-100\",\"calendar_id\":\"SYNTH-CAL\",\"session\":\"regular\",\"comparison_basis\":\"comparable-prior-close\",\"corporate_action_policy\":\"provider-adjusted\"}], {\"cutoff\":\"2026-01-06T22:00:00Z\",\"expectedStartSequence\":1,\"expectedEndSequence\":2,\"initialValue\":0,\"scale\":100,\"minimumCoverage\":0.95})",
        "args": [
          {
            "value": [
              {
                "event_id": "NAD-1",
                "revision": 1,
                "supersedes_revision": null,
                "event_type": "upsert",
                "session_sequence": 1,
                "session_date": "2026-01-05",
                "effective_at": "2026-01-05T21:00:00Z",
                "available_at": "2026-01-05T21:05:00Z",
                "venue_id": "SYNTH-X",
                "universe_id": "SYNTH-100",
                "calendar_id": "SYNTH-CAL",
                "session": "regular",
                "comparison_basis": "comparable-prior-close",
                "corporate_action_policy": "provider-adjusted"
              },
              {
                "event_id": "NAD-2",
                "revision": 1,
                "supersedes_revision": null,
                "event_type": "upsert",
                "session_sequence": 2,
                "session_date": "2026-01-06",
                "effective_at": "2026-01-06T21:00:00Z",
                "available_at": "2026-01-06T21:05:00Z",
                "venue_id": "SYNTH-X",
                "universe_id": "SYNTH-100",
                "calendar_id": "SYNTH-CAL",
                "session": "regular",
                "comparison_basis": "comparable-prior-close",
                "corporate_action_policy": "provider-adjusted"
              }
            ],
            "elided": null
          },
          {
            "value": {
              "cutoff": "2026-01-06T22:00:00Z",
              "expectedStartSequence": 1,
              "expectedEndSequence": 2,
              "initialValue": 0,
              "scale": 100,
              "minimumCoverage": 0.95
            },
            "elided": null
          }
        ],
        "output": {
          "state": "resolved",
          "reason_codes": [],
          "ignored_future_revisions": 0,
          "points": {
            "0": {
              "net_advances": 30,
              "mover_count": 90,
              "scaled_contribution": 33.33333333333333,
              "normalized_line": 33.33333333333333
            },
            "1": {
              "net_advances": -20,
              "mover_count": 90,
              "scaled_contribution": -22.22222222222222,
              "normalized_line": 11.111111111111107
            }
          }
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: state, reason_codes, ignored_future_revisions, points"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "normalized-line-path.svg",
            "url": "https://thefintechbuilder.com/content/d04-f01-a04/static/normalized-line-path.svg"
          },
          {
            "file": "scale-invariance.svg",
            "url": "https://thefintechbuilder.com/content/d04-f01-a04/static/scale-invariance.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Causal normalized-line publication flow",
            "source": "flowchart LR\n  A[Read available time] --> B{Visible at cutoff?}\n  B -- No --> C[Count ignored future record]\n  B -- Yes --> D[Validate visible event]\n  D --> E[Resolve revision heads]\n  E --> F{Every expected session resolved?}\n  F -- No --> G[Return state and reasons with no points]\n  F -- Yes --> H[Verify stable identity seed scale and denominator]\n  H --> I[Compute ratio as A minus D over A plus D]\n  I --> J[Add scaled ratio to prior line]\n  J --> K[Return traceable cumulative points]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "Nasdaq Trader Daily Market Files",
          "author": null,
          "url": null
        },
        {
          "key": "R2",
          "title": "Nasdaq Trader 2026 daily CSV",
          "author": null,
          "url": null
        },
        {
          "key": "R3",
          "title": "Nasdaq Trader field definitions",
          "author": null,
          "url": null
        },
        {
          "key": "R4",
          "title": "McClellan breadth normalization",
          "author": "McClellan Financial Publications",
          "url": null
        },
        {
          "key": "R5",
          "title": "StockCharts A/D Percent",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence map",
          "title": "Evidence map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/advance-decline-breadth/normalized-advance-decline-line/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Normalized-Advance-Decline-Line-Market-Breadth-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/advance-decline-breadth/normalized-advance-decline-line/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F01-A05",
      "name": "Absolute Breadth Index",
      "headline": null,
      "slug": "absolute-breadth-index",
      "path": "market-breadth-and-internals/advance-decline-breadth/absolute-breadth-index",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F01",
        "family": "Advance/Decline Breadth",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/advance-decline-breadth/absolute-breadth-index",
        "entry": "evaluateAbsoluteBreadthIndex",
        "params": [
          "request"
        ],
        "exports": [
          "evaluateAbsoluteBreadthIndex"
        ],
        "archetype": "snapshot-evaluate",
        "signature": "evaluateAbsoluteBreadthIndex(request)"
      },
      "api": {
        "summary": "The absolute difference between advances and declines — direction discarded on purpose. It measures how *decisive* a session was, not which way, so it reads as an activity or conviction gauge rather than a directional signal.",
        "params": [
          {
            "name": "request",
            "type": "{ decision_time: string; metric_variant: string; records: Record[] }",
            "required": true,
            "description": "`metric_variant` selects the raw or normalised form; `decision_time` bounds which revisions are usable.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ session_date, venue_id, universe_id, universe_revision, comparison_basis, … }",
          "description": "The index with the full provenance of the universe it was computed over, including the universe revision."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the metric variant is unrecognised",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(records)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F01-A05.json",
        "call": "evaluateAbsoluteBreadthIndex({\"decision_time\":\"2026-01-05T22:00:00Z\",\"metric_variant\":\"raw_issue_count\",\"records\":[{\"record_id\":\"ABI-R1\",\"revision\":1,\"supersedes_record_id\":null,\"kind\":\"observation\",\"effective_at\":\"2026-01-05T21:00:00Z\",\"available_at\":\"2026-01-05T21:05:00Z\",\"is_final\":true,\"session_date\":\"2026-01-05\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-100\",\"universe_revision\":\"U1\",\"session_id\":\"regular\",\"calendar_id\":\"SYNTH-CAL\",\"comparison_basis\":\"comparable-prior-close\"}]})",
        "args": [
          {
            "value": {
              "decision_time": "2026-01-05T22:00:00Z",
              "metric_variant": "raw_issue_count",
              "records": [
                {
                  "record_id": "ABI-R1",
                  "revision": 1,
                  "supersedes_record_id": null,
                  "kind": "observation",
                  "effective_at": "2026-01-05T21:00:00Z",
                  "available_at": "2026-01-05T21:05:00Z",
                  "is_final": true,
                  "session_date": "2026-01-05",
                  "venue_id": "SYNTH-X",
                  "universe_id": "SYNTH-100",
                  "universe_revision": "U1",
                  "session_id": "regular",
                  "calendar_id": "SYNTH-CAL",
                  "comparison_basis": "comparable-prior-close"
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "evaluation_state": "resolved",
          "publishable": true,
          "reason_codes": [],
          "record_id": "ABI-R1",
          "revision": 1,
          "is_provisional": false,
          "net_advances": 30,
          "absolute_breadth_index": 30,
          "mover_count": 90,
          "classified_count": 98,
          "coverage_ratio": 0.98,
          "breadth_state": "advances_imbalanced"
        },
        "outputElided": null,
        "outputShape": "object with 12 fields: evaluation_state, publishable, reason_codes, record_id, revision, is_provisional, net_advances, absolute_breadth_index, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "direction-fold.svg",
            "url": "https://thefintechbuilder.com/content/d04-f01-a05/static/direction-fold.svg"
          },
          {
            "file": "session-magnitudes.svg",
            "url": "https://thefintechbuilder.com/content/d04-f01-a05/static/session-magnitudes.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Absolute Breadth Index evidence and calculation flow",
            "source": "flowchart LR\n    A[\"Raw issue-count request\"] --> B{\"Supported variant?\"}\n    B -- \"No\" --> U[\"Unsupported; ABI null\"]\n    B -- \"Yes\" --> C[\"Keep records effective and available by decision time\"]\n    C --> D{\"Any causal record?\"}\n    D -- \"No\" --> I[\"Incomplete; ABI null\"]\n    D -- \"Yes\" --> E{\"One identity and contiguous lineage?\"}\n    E -- \"No\" --> M[\"Ambiguous; ABI null\"]\n    E -- \"Yes\" --> F{\"Current record complete and not cancelled?\"}\n    F -- \"No\" --> I\n    F -- \"Yes\" --> G[\"Net Advances = A - D\"]\n    G --> H[\"Raw ABI = absolute value of Net Advances\"]\n    H --> R[\"Resolved; retain counts, sign, clocks, revision, finality\"]"
          }
        ]
      },
      "references": [
        {
          "key": "ABI-01",
          "title": "Schwab thinkorswim AdvanceDecline study",
          "author": null,
          "url": null
        },
        {
          "key": "ABI-02",
          "title": "TC2000 T2101 help",
          "author": null,
          "url": null
        },
        {
          "key": "ABI-03",
          "title": "Nasdaq Trader Daily Market Files",
          "author": null,
          "url": null
        },
        {
          "key": "ABI-04",
          "title": "Nasdaq Daily Market Summary definitions",
          "author": null,
          "url": null
        },
        {
          "key": "ABI-05",
          "title": "Nasdaq Trader 2026 annual CSV",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence reconciliation",
          "title": "Evidence reconciliation",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/advance-decline-breadth/absolute-breadth-index/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Absolute-Breadth-Index-Market-Breadth-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/advance-decline-breadth/absolute-breadth-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F02-A01",
      "name": "Traditional McClellan Oscillator",
      "headline": "Compare Fast and Slow Raw Breadth",
      "slug": "traditional-mcclellan-oscillator",
      "path": "market-breadth-and-internals/mcclellan-family/traditional-mcclellan-oscillator",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F02",
        "family": "McClellan Family",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/mcclellan-family/traditional-mcclellan-oscillator",
        "entry": "calculateMcClellanValues",
        "params": [
          "netAdvances"
        ],
        "exports": [
          "calculateMcClellanValues",
          "calculateMcClellan"
        ],
        "archetype": "record-transform",
        "signature": "calculateMcClellanValues(netAdvances)"
      },
      "api": {
        "summary": "The difference between a 19-day and a 39-day EMA of net advances. Because both averages are taken over raw counts, values are not comparable across eras in which the number of listed issues changed — which is exactly what the ratio-adjusted variant fixes.",
        "params": [
          {
            "name": "netAdvances",
            "type": "number[]",
            "required": true,
            "description": "Net advances per session, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ema19, ema39, oscillator }",
          "description": "Both EMAs alongside the oscillator, so a reading can be traced to its components."
        },
        "warmup": null,
        "errors": [
          {
            "when": "fewer sessions are supplied than the longer EMA needs",
            "behaviour": "returns nulls during warm-up rather than throwing"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F02-A01.json",
        "call": "calculateMcClellanValues([0,0,0,0,0,0])",
        "args": [
          {
            "value": [
              0,
              0,
              0,
              0,
              0,
              0
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 44
            }
          }
        ],
        "output": {
          "38": {
            "observation": 39,
            "fast_ema": 0,
            "slow_ema": 0,
            "oscillator": 0,
            "status": "ready"
          },
          "39": {
            "observation": 40,
            "fast_ema": 10,
            "slow_ema": 5,
            "oscillator": 5,
            "status": "ready"
          },
          "40": {
            "observation": 41,
            "fast_ema": 19,
            "slow_ema": 9.75,
            "oscillator": 9.25,
            "status": "ready"
          },
          "41": {
            "observation": 42,
            "fast_ema": 7.1,
            "slow_ema": 4.2625,
            "oscillator": 2.8375,
            "status": "ready"
          },
          "42": {
            "observation": 43,
            "fast_ema": 6.39,
            "slow_ema": 4.049375,
            "oscillator": 2.340625,
            "status": "ready"
          },
          "43": {
            "observation": 44,
            "fast_ema": -4.249,
            "slow_ema": -1.15309375,
            "oscillator": -3.09590625,
            "status": "ready"
          }
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: 38, 39, 40, 41, 42, 43"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "ema-update.svg",
            "url": "https://thefintechbuilder.com/content/d04-f02-a01/static/ema-update.svg"
          },
          {
            "file": "worked-path.svg",
            "url": "https://thefintechbuilder.com/content/d04-f02-a01/static/worked-path.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Traditional McClellan Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"Source revisions\"] --> B[\"Keep available-at or before cutoff\"]\n    B --> C[\"Resolve one head per expected session\"]\n    C --> D{\"All evidence ready, complete, and coherent?\"}\n    D -- \"No\" --> E[\"Emit non-resolved result with no points\"]\n    D -- \"Yes\" --> F[\"Net Advances = A - D\"]\n    F --> G[\"Seed or update fast 10% trend\"]\n    F --> H[\"Seed or update slow 5% trend\"]\n    G --> I{\"Both states ready?\"}\n    H --> I\n    I -- \"No\" --> J[\"Emit resolved warm-up point\"]\n    I -- \"Yes\" --> K[\"Oscillator = fast - slow\"]\n    K --> L[\"Emit point with revision and diagnostics\"]"
          }
        ]
      },
      "references": [
        {
          "key": "MCO-01",
          "title": "Calculating the McClellan Oscillator",
          "author": "McClellan Financial Publications; explanation by Tom McClellan",
          "url": null
        },
        {
          "key": "MCO-02",
          "title": "The McClellan Oscillator and Summation Index",
          "author": "McClellan Financial Publications",
          "url": null
        },
        {
          "key": "MCO-03",
          "title": "2004 MTA Lifetime Achievement Award booklet",
          "author": "Sherman and Marian McClellan / McClellan Financial Publications",
          "url": null
        },
        {
          "key": "MCO-04",
          "title": "StockCharts ChartSchool methodology",
          "author": "StockCharts.com",
          "url": null
        },
        {
          "key": "MCO-05",
          "title": "Schwab thinkorswim McClellanOscillator",
          "author": "Charles Schwab / thinkorswim",
          "url": null
        },
        {
          "key": "MCO-06",
          "title": "Nasdaq A-D definition",
          "author": "Nasdaq, Inc.",
          "url": null
        },
        {
          "key": "MCO-07",
          "title": "Nasdaq Trader Daily Market Files",
          "author": "Nasdaq, Inc.",
          "url": null
        },
        {
          "key": "MCO-08",
          "title": "Daily Market Summary Data Fields and Definitions",
          "author": "Nasdaq, Inc.",
          "url": null
        },
        {
          "key": "Evidence and design reconciliation",
          "title": "Evidence and design reconciliation",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/mcclellan-family/traditional-mcclellan-oscillator/",
        "repo": "https://github.com/IslamBaraka90/Fintech-McClellan-Oscillator-Market-Breadth-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/mcclellan-family/traditional-mcclellan-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F02-A02",
      "name": "Ratio-Adjusted McClellan Oscillator",
      "headline": null,
      "slug": "ratio-adjusted-mcclellan-oscillator",
      "path": "market-breadth-and-internals/mcclellan-family/ratio-adjusted-mcclellan-oscillator",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F02",
        "family": "McClellan Family",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/mcclellan-family/ratio-adjusted-mcclellan-oscillator",
        "entry": "calculate",
        "params": [
          "records",
          "cutoff"
        ],
        "exports": [
          "transformRecord",
          "calculateValues",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(records, cutoff)"
      },
      "api": {
        "summary": "The McClellan oscillator computed on net advances divided by advances plus declines. Ratio adjustment is what makes a 1970 reading comparable with a 2026 one — without it the oscillator's range grows with the exchange.",
        "params": [
          {
            "name": "records",
            "type": "BreadthRecord[]",
            "required": true,
            "description": "Session records with revision and event-type fields.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "cutoff",
            "type": "string",
            "required": true,
            "description": "Point-in-time bound. Revisions arriving after the cutoff are ignored rather than applied, so the series is exactly what was computable at that moment. Breadth data is revised routinely, and a cumulative line silently rebuilt from revised inputs is not the line anyone traded.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, reason_codes, points, latest_oscillator, latest_index_value, ignored_future_records, seed_state }",
          "description": "The oscillator series with its seeding state — an EMA's seed matters here because the summation index accumulates it forever."
        },
        "warmup": null,
        "errors": [
          {
            "when": "records cannot be ordered",
            "behaviour": "reported in reason_codes rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(records)",
          "space": "O(sessions)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F02-A02.json",
        "call": "calculate([{\"session_date\":\"2026-01-02\",\"session_sequence\":1,\"effective_at\":\"2026-01-02T21:00:00Z\",\"available_at\":\"2026-01-02T21:20:00Z\",\"revision\":0,\"event_type\":\"upsert\",\"source_evidence_state\":\"ready\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-STABLE-200\",\"methodology_id\":\"close-vs-comparable-prior-close-v1\",\"calendar_id\":\"SYNTH-WEEKDAY\",\"volume_unit\":\"shares\",\"volume_adjustment_basis\":\"reported-unadjusted\",\"advances\":100}], \"2026-04-01T00:00:00Z\")",
        "args": [
          {
            "value": [
              {
                "session_date": "2026-01-02",
                "session_sequence": 1,
                "effective_at": "2026-01-02T21:00:00Z",
                "available_at": "2026-01-02T21:20:00Z",
                "revision": 0,
                "event_type": "upsert",
                "source_evidence_state": "ready",
                "venue_id": "SYNTH-X",
                "universe_id": "SYNTH-STABLE-200",
                "methodology_id": "close-vs-comparable-prior-close-v1",
                "calendar_id": "SYNTH-WEEKDAY",
                "volume_unit": "shares",
                "volume_adjustment_basis": "reported-unadjusted",
                "advances": 100
              }
            ],
            "elided": null
          },
          {
            "value": "2026-04-01T00:00:00Z",
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "latest_oscillator": null,
          "latest_index_value": null,
          "ignored_future_records": 0
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: status, latest_oscillator, latest_index_value, ignored_future_records"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "family-transform.svg",
            "url": "https://thefintechbuilder.com/content/d04-f02-a02/static/family-transform.svg"
          },
          {
            "file": "worked-state.svg",
            "url": "https://thefintechbuilder.com/content/d04-f02-a02/static/worked-state.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Ratio-Adjusted McClellan Oscillator calculation flow",
            "source": "flowchart TD\n    A[\"Records available at knowledge cutoff\"] --> B{\"Contiguous, unique, ready evidence?\"}\n    B -->|No| C[\"Withhold path and report reason\"]\n    B -->|Yes| D[\"Apply Ratio-Adjusted McClellan Oscillator input transform\"]\n    D --> E[\"SMA-19 fast seed and 10% Trend\"]\n    D --> F[\"SMA-39 slow seed and 5% Trend\"]\n    E --> G{\"Both states ready?\"}\n    F --> G\n    G -->|No| H[\"Warm-up diagnostics\"]\n    G -->|Yes| I[\"Fast minus slow oscillator\"]\n    I --> J[\"Publish oscillator diagnostics\"]\n    J --> K[\"Provenance and current regime\"]"
          }
        ]
      },
      "references": [
        {
          "key": "MCO-01",
          "title": "Calculating the McClellan Oscillator",
          "author": "McClellan Financial Publications; Tom McClellan",
          "url": null
        },
        {
          "key": "MCO-02",
          "title": "Ratio Adjusted Summation Index",
          "author": "McClellan Financial Publications; Tom McClellan",
          "url": null
        },
        {
          "key": "NASD-01",
          "title": "A-D definition",
          "author": "Nasdaq, Inc.",
          "url": null
        },
        {
          "key": "Evidence reconciliation",
          "title": "Evidence reconciliation",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/mcclellan-family/ratio-adjusted-mcclellan-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/mcclellan-family/ratio-adjusted-mcclellan-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F02-A03",
      "name": "Traditional McClellan Summation Index",
      "headline": null,
      "slug": "traditional-mcclellan-summation-index",
      "path": "market-breadth-and-internals/mcclellan-family/traditional-mcclellan-summation-index",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F02",
        "family": "McClellan Family",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/mcclellan-family/traditional-mcclellan-summation-index",
        "entry": "calculate",
        "params": [
          "records",
          "cutoff"
        ],
        "exports": [
          "transformRecord",
          "calculateValues",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(records, cutoff)"
      },
      "api": {
        "summary": "The running total of the McClellan oscillator. Turns a fast, noisy signal into a slow regime gauge — the oscillator says what is happening this week, the summation index what has been happening for months.",
        "params": [
          {
            "name": "records",
            "type": "BreadthRecord[]",
            "required": true,
            "description": "Session records with revision and event-type fields.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "cutoff",
            "type": "string",
            "required": true,
            "description": "Point-in-time bound. Revisions arriving after the cutoff are ignored rather than applied, so the series is exactly what was computable at that moment. Breadth data is revised routinely, and a cumulative line silently rebuilt from revised inputs is not the line anyone traded.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, points, latest_oscillator, latest_index_value, seed_state, … }",
          "description": "The summation series and its seed. Because the index accumulates without bound, the seed choice shifts every subsequent value — it is reported rather than assumed."
        },
        "warmup": null,
        "errors": [
          {
            "when": "records cannot be ordered",
            "behaviour": "reported in reason_codes rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(records)",
          "space": "O(sessions)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F02-A03.json",
        "call": "calculate([{\"session_date\":\"2026-01-02\",\"session_sequence\":1,\"effective_at\":\"2026-01-02T21:00:00Z\",\"available_at\":\"2026-01-02T21:20:00Z\",\"revision\":0,\"event_type\":\"upsert\",\"source_evidence_state\":\"ready\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-STABLE-200\",\"methodology_id\":\"close-vs-comparable-prior-close-v1\",\"calendar_id\":\"SYNTH-WEEKDAY\",\"volume_unit\":\"shares\",\"volume_adjustment_basis\":\"reported-unadjusted\",\"advances\":100}], \"2026-04-01T00:00:00Z\")",
        "args": [
          {
            "value": [
              {
                "session_date": "2026-01-02",
                "session_sequence": 1,
                "effective_at": "2026-01-02T21:00:00Z",
                "available_at": "2026-01-02T21:20:00Z",
                "revision": 0,
                "event_type": "upsert",
                "source_evidence_state": "ready",
                "venue_id": "SYNTH-X",
                "universe_id": "SYNTH-STABLE-200",
                "methodology_id": "close-vs-comparable-prior-close-v1",
                "calendar_id": "SYNTH-WEEKDAY",
                "volume_unit": "shares",
                "volume_adjustment_basis": "reported-unadjusted",
                "advances": 100
              }
            ],
            "elided": null
          },
          {
            "value": "2026-04-01T00:00:00Z",
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "latest_oscillator": null,
          "latest_index_value": null,
          "ignored_future_records": 0
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: status, latest_oscillator, latest_index_value, ignored_future_records"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "family-transform.svg",
            "url": "https://thefintechbuilder.com/content/d04-f02-a03/static/family-transform.svg"
          },
          {
            "file": "worked-state.svg",
            "url": "https://thefintechbuilder.com/content/d04-f02-a03/static/worked-state.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Traditional McClellan Summation Index calculation flow",
            "source": "flowchart TD\n    A[\"Records available at knowledge cutoff\"] --> B{\"Contiguous, unique, ready evidence?\"}\n    B -->|No| C[\"Withhold path and report reason\"]\n    B -->|Yes| D[\"Apply Traditional McClellan Summation Index input transform\"]\n    D --> E[\"SMA-19 fast seed and 10% Trend\"]\n    D --> F[\"SMA-39 slow seed and 5% Trend\"]\n    E --> G{\"Both states ready?\"}\n    F --> G\n    G -->|No| H[\"Warm-up diagnostics\"]\n    G -->|Yes| I[\"Fast minus slow oscillator\"]\n    I --> J[\"Add to declared cumulative state\"]\n    J --> K[\"Provenance and current regime\"]"
          }
        ]
      },
      "references": [
        {
          "key": "MCO-01",
          "title": "Calculating the McClellan Oscillator",
          "author": "McClellan Financial Publications; Tom McClellan",
          "url": null
        },
        {
          "key": "MCO-03",
          "title": "The McClellan Oscillator and Summation Index",
          "author": "McClellan Financial Publications",
          "url": null
        },
        {
          "key": "NASD-01",
          "title": "A-D definition",
          "author": "Nasdaq, Inc.",
          "url": null
        },
        {
          "key": "Evidence reconciliation",
          "title": "Evidence reconciliation",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/mcclellan-family/traditional-mcclellan-summation-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/mcclellan-family/traditional-mcclellan-summation-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F02-A04",
      "name": "Ratio-Adjusted Summation Index (RASI)",
      "headline": null,
      "slug": "ratio-adjusted-summation-index-rasi",
      "path": "market-breadth-and-internals/mcclellan-family/ratio-adjusted-summation-index-rasi",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F02",
        "family": "McClellan Family",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/mcclellan-family/ratio-adjusted-summation-index-rasi",
        "entry": "calculate",
        "params": [
          "records",
          "cutoff"
        ],
        "exports": [
          "transformRecord",
          "calculateValues",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(records, cutoff)"
      },
      "api": {
        "summary": "RASI: the summation index built on the ratio-adjusted oscillator. The variant most practitioners mean when they quote 'the summation index', and the only one whose historical thresholds hold up across eras.",
        "params": [
          {
            "name": "records",
            "type": "BreadthRecord[]",
            "required": true,
            "description": "Session records with revision and event-type fields.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "cutoff",
            "type": "string",
            "required": true,
            "description": "Point-in-time bound. Revisions arriving after the cutoff are ignored rather than applied, so the series is exactly what was computable at that moment. Breadth data is revised routinely, and a cumulative line silently rebuilt from revised inputs is not the line anyone traded.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, points, latest_oscillator, latest_index_value, seed_state, … }",
          "description": "The RASI series with its seeding state."
        },
        "warmup": null,
        "errors": [
          {
            "when": "records cannot be ordered",
            "behaviour": "reported in reason_codes rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(records)",
          "space": "O(sessions)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F02-A04.json",
        "call": "calculate([{\"session_date\":\"2026-01-02\",\"session_sequence\":1,\"effective_at\":\"2026-01-02T21:00:00Z\",\"available_at\":\"2026-01-02T21:20:00Z\",\"revision\":0,\"event_type\":\"upsert\",\"source_evidence_state\":\"ready\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-STABLE-200\",\"methodology_id\":\"close-vs-comparable-prior-close-v1\",\"calendar_id\":\"SYNTH-WEEKDAY\",\"volume_unit\":\"shares\",\"volume_adjustment_basis\":\"reported-unadjusted\",\"advances\":100}], \"2026-04-01T00:00:00Z\")",
        "args": [
          {
            "value": [
              {
                "session_date": "2026-01-02",
                "session_sequence": 1,
                "effective_at": "2026-01-02T21:00:00Z",
                "available_at": "2026-01-02T21:20:00Z",
                "revision": 0,
                "event_type": "upsert",
                "source_evidence_state": "ready",
                "venue_id": "SYNTH-X",
                "universe_id": "SYNTH-STABLE-200",
                "methodology_id": "close-vs-comparable-prior-close-v1",
                "calendar_id": "SYNTH-WEEKDAY",
                "volume_unit": "shares",
                "volume_adjustment_basis": "reported-unadjusted",
                "advances": 100
              }
            ],
            "elided": null
          },
          {
            "value": "2026-04-01T00:00:00Z",
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "latest_oscillator": null,
          "latest_index_value": null,
          "ignored_future_records": 0
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: status, latest_oscillator, latest_index_value, ignored_future_records"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "family-transform.svg",
            "url": "https://thefintechbuilder.com/content/d04-f02-a04/static/family-transform.svg"
          },
          {
            "file": "worked-state.svg",
            "url": "https://thefintechbuilder.com/content/d04-f02-a04/static/worked-state.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Ratio-Adjusted Summation Index (RASI) calculation flow",
            "source": "flowchart TD\n    A[\"Records available at knowledge cutoff\"] --> B{\"Contiguous, unique, ready evidence?\"}\n    B -->|No| C[\"Withhold path and report reason\"]\n    B -->|Yes| D[\"Apply Ratio-Adjusted Summation Index (RASI) input transform\"]\n    D --> E[\"SMA-19 fast seed and 10% Trend\"]\n    D --> F[\"SMA-39 slow seed and 5% Trend\"]\n    E --> G{\"Both states ready?\"}\n    F --> G\n    G -->|No| H[\"Warm-up diagnostics\"]\n    G -->|Yes| I[\"Fast minus slow oscillator\"]\n    I --> J[\"Add to declared cumulative state\"]\n    J --> K[\"Provenance and current regime\"]"
          }
        ]
      },
      "references": [
        {
          "key": "MCO-01",
          "title": "Calculating the McClellan Oscillator",
          "author": "McClellan Financial Publications; Tom McClellan",
          "url": null
        },
        {
          "key": "MCO-02",
          "title": "Ratio Adjusted Summation Index",
          "author": "McClellan Financial Publications; Tom McClellan",
          "url": null
        },
        {
          "key": "MCO-03",
          "title": "The McClellan Oscillator and Summation Index",
          "author": "McClellan Financial Publications",
          "url": null
        },
        {
          "key": "NASD-01",
          "title": "A-D definition",
          "author": "Nasdaq, Inc.",
          "url": null
        },
        {
          "key": "Evidence reconciliation",
          "title": "Evidence reconciliation",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/mcclellan-family/ratio-adjusted-summation-index-rasi/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/mcclellan-family/ratio-adjusted-summation-index-rasi/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F02-A05",
      "name": "McClellan Volume Oscillator",
      "headline": null,
      "slug": "mcclellan-volume-oscillator",
      "path": "market-breadth-and-internals/mcclellan-family/mcclellan-volume-oscillator",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F02",
        "family": "McClellan Family",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/mcclellan-family/mcclellan-volume-oscillator",
        "entry": "calculate",
        "params": [
          "records",
          "cutoff"
        ],
        "exports": [
          "transformRecord",
          "calculateValues",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(records, cutoff)"
      },
      "api": {
        "summary": "The McClellan construction applied to advancing minus declining *volume* rather than issue counts. It weights participation by size, so it can disagree with the issue-based oscillator — and that disagreement is itself the signal.",
        "params": [
          {
            "name": "records",
            "type": "BreadthRecord[]",
            "required": true,
            "description": "Session records carrying advancing and declining volume.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "cutoff",
            "type": "string",
            "required": true,
            "description": "Point-in-time bound. Revisions arriving after the cutoff are ignored rather than applied, so the series is exactly what was computable at that moment. Breadth data is revised routinely, and a cumulative line silently rebuilt from revised inputs is not the line anyone traded.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, points, latest_oscillator, latest_index_value, … }",
          "description": "The volume oscillator series."
        },
        "warmup": null,
        "errors": [
          {
            "when": "volume fields are absent",
            "behaviour": "reported in reason_codes rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(records)",
          "space": "O(sessions)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F02-A05.json",
        "call": "calculate([{\"session_date\":\"2026-01-02\",\"session_sequence\":1,\"effective_at\":\"2026-01-02T21:00:00Z\",\"available_at\":\"2026-01-02T21:20:00Z\",\"revision\":0,\"event_type\":\"upsert\",\"source_evidence_state\":\"ready\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-STABLE-200\",\"methodology_id\":\"close-vs-comparable-prior-close-v1\",\"calendar_id\":\"SYNTH-WEEKDAY\",\"volume_unit\":\"shares\",\"volume_adjustment_basis\":\"reported-unadjusted\",\"advances\":100}], \"2026-04-01T00:00:00Z\")",
        "args": [
          {
            "value": [
              {
                "session_date": "2026-01-02",
                "session_sequence": 1,
                "effective_at": "2026-01-02T21:00:00Z",
                "available_at": "2026-01-02T21:20:00Z",
                "revision": 0,
                "event_type": "upsert",
                "source_evidence_state": "ready",
                "venue_id": "SYNTH-X",
                "universe_id": "SYNTH-STABLE-200",
                "methodology_id": "close-vs-comparable-prior-close-v1",
                "calendar_id": "SYNTH-WEEKDAY",
                "volume_unit": "shares",
                "volume_adjustment_basis": "reported-unadjusted",
                "advances": 100
              }
            ],
            "elided": null
          },
          {
            "value": "2026-04-01T00:00:00Z",
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "latest_oscillator": null,
          "latest_index_value": null,
          "ignored_future_records": 0
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: status, latest_oscillator, latest_index_value, ignored_future_records"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "family-transform.svg",
            "url": "https://thefintechbuilder.com/content/d04-f02-a05/static/family-transform.svg"
          },
          {
            "file": "worked-state.svg",
            "url": "https://thefintechbuilder.com/content/d04-f02-a05/static/worked-state.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "McClellan Volume Oscillator calculation flow",
            "source": "flowchart TD\n    A[\"Records available at knowledge cutoff\"] --> B{\"Contiguous, unique, ready evidence?\"}\n    B -->|No| C[\"Withhold path and report reason\"]\n    B -->|Yes| D[\"Apply McClellan Volume Oscillator input transform\"]\n    D --> E[\"SMA-19 fast seed and 10% Trend\"]\n    D --> F[\"SMA-39 slow seed and 5% Trend\"]\n    E --> G{\"Both states ready?\"}\n    F --> G\n    G -->|No| H[\"Warm-up diagnostics\"]\n    G -->|Yes| I[\"Fast minus slow oscillator\"]\n    I --> J[\"Publish oscillator diagnostics\"]\n    J --> K[\"Provenance and current regime\"]"
          }
        ]
      },
      "references": [
        {
          "key": "MCO-01",
          "title": "Calculating the McClellan Oscillator",
          "author": "McClellan Financial Publications; Tom McClellan",
          "url": null
        },
        {
          "key": "MCO-04",
          "title": "A Subtle Message in the Volume Summation Index",
          "author": "McClellan Financial Publications; Tom McClellan",
          "url": null
        },
        {
          "key": "MCO-05",
          "title": "Understanding Oscillators and Other Indicators",
          "author": "McClellan Financial Publications",
          "url": null
        },
        {
          "key": "NASD-01",
          "title": "A-D definition",
          "author": "Nasdaq, Inc.",
          "url": null
        },
        {
          "key": "Evidence reconciliation",
          "title": "Evidence reconciliation",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/mcclellan-family/mcclellan-volume-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/mcclellan-family/mcclellan-volume-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F02-A06",
      "name": "McClellan Volume Summation Index",
      "headline": null,
      "slug": "mcclellan-volume-summation-index",
      "path": "market-breadth-and-internals/mcclellan-family/mcclellan-volume-summation-index",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F02",
        "family": "McClellan Family",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/mcclellan-family/mcclellan-volume-summation-index",
        "entry": "calculate",
        "params": [
          "records",
          "cutoff"
        ],
        "exports": [
          "transformRecord",
          "calculateValues",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(records, cutoff)"
      },
      "api": {
        "summary": "The running total of the volume oscillator — the volume-weighted counterpart of the summation index.",
        "params": [
          {
            "name": "records",
            "type": "BreadthRecord[]",
            "required": true,
            "description": "Session records carrying advancing and declining volume.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "cutoff",
            "type": "string",
            "required": true,
            "description": "Point-in-time bound. Revisions arriving after the cutoff are ignored rather than applied, so the series is exactly what was computable at that moment. Breadth data is revised routinely, and a cumulative line silently rebuilt from revised inputs is not the line anyone traded.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, points, latest_index_value, seed_state, … }",
          "description": "The volume summation series with its seed."
        },
        "warmup": null,
        "errors": [
          {
            "when": "volume fields are absent",
            "behaviour": "reported in reason_codes rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(records)",
          "space": "O(sessions)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F02-A06.json",
        "call": "calculate([{\"session_date\":\"2026-01-02\",\"session_sequence\":1,\"effective_at\":\"2026-01-02T21:00:00Z\",\"available_at\":\"2026-01-02T21:20:00Z\",\"revision\":0,\"event_type\":\"upsert\",\"source_evidence_state\":\"ready\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-STABLE-200\",\"methodology_id\":\"close-vs-comparable-prior-close-v1\",\"calendar_id\":\"SYNTH-WEEKDAY\",\"volume_unit\":\"shares\",\"volume_adjustment_basis\":\"reported-unadjusted\",\"advances\":100}], \"2026-04-01T00:00:00Z\")",
        "args": [
          {
            "value": [
              {
                "session_date": "2026-01-02",
                "session_sequence": 1,
                "effective_at": "2026-01-02T21:00:00Z",
                "available_at": "2026-01-02T21:20:00Z",
                "revision": 0,
                "event_type": "upsert",
                "source_evidence_state": "ready",
                "venue_id": "SYNTH-X",
                "universe_id": "SYNTH-STABLE-200",
                "methodology_id": "close-vs-comparable-prior-close-v1",
                "calendar_id": "SYNTH-WEEKDAY",
                "volume_unit": "shares",
                "volume_adjustment_basis": "reported-unadjusted",
                "advances": 100
              }
            ],
            "elided": null
          },
          {
            "value": "2026-04-01T00:00:00Z",
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "latest_oscillator": null,
          "latest_index_value": null,
          "ignored_future_records": 0
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: status, latest_oscillator, latest_index_value, ignored_future_records"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "family-transform.svg",
            "url": "https://thefintechbuilder.com/content/d04-f02-a06/static/family-transform.svg"
          },
          {
            "file": "worked-state.svg",
            "url": "https://thefintechbuilder.com/content/d04-f02-a06/static/worked-state.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "McClellan Volume Summation Index calculation flow",
            "source": "flowchart TD\n    A[\"Records available at knowledge cutoff\"] --> B{\"Contiguous, unique, ready evidence?\"}\n    B -->|No| C[\"Withhold path and report reason\"]\n    B -->|Yes| D[\"Apply McClellan Volume Summation Index input transform\"]\n    D --> E[\"SMA-19 fast seed and 10% Trend\"]\n    D --> F[\"SMA-39 slow seed and 5% Trend\"]\n    E --> G{\"Both states ready?\"}\n    F --> G\n    G -->|No| H[\"Warm-up diagnostics\"]\n    G -->|Yes| I[\"Fast minus slow oscillator\"]\n    I --> J[\"Add to declared cumulative state\"]\n    J --> K[\"Provenance and current regime\"]"
          }
        ]
      },
      "references": [
        {
          "key": "MCO-01",
          "title": "Calculating the McClellan Oscillator",
          "author": "McClellan Financial Publications; Tom McClellan",
          "url": null
        },
        {
          "key": "MCO-03",
          "title": "The McClellan Oscillator and Summation Index",
          "author": "McClellan Financial Publications",
          "url": null
        },
        {
          "key": "MCO-04",
          "title": "A Subtle Message in the Volume Summation Index",
          "author": "McClellan Financial Publications; Tom McClellan",
          "url": null
        },
        {
          "key": "MCO-05",
          "title": "Understanding Oscillators and Other Indicators",
          "author": "McClellan Financial Publications",
          "url": null
        },
        {
          "key": "NASD-01",
          "title": "A-D definition",
          "author": "Nasdaq, Inc.",
          "url": null
        },
        {
          "key": "Evidence reconciliation",
          "title": "Evidence reconciliation",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/mcclellan-family/mcclellan-volume-summation-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/mcclellan-family/mcclellan-volume-summation-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F03-A01",
      "name": "New Highs–New Lows",
      "headline": null,
      "slug": "new-highs-new-lows",
      "path": "market-breadth-and-internals/high-low-and-trend-breadth/new-highs-new-lows",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F03",
        "family": "High/Low and Trend Breadth",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/high-low-and-trend-breadth/new-highs-new-lows",
        "entry": "calculate",
        "params": [
          "records",
          "decisionTime"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(records, decisionTime)"
      },
      "api": {
        "summary": "Counts issues making new 52-week highs and lows. Unlike advance/decline it measures position against a long lookback rather than one session, so it detects a rally where fewer and fewer names reach new ground.",
        "params": [
          {
            "name": "records",
            "type": "Record[]",
            "required": true,
            "description": "Session records with evidence state and universe identity.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "decisionTime",
            "type": "string",
            "required": true,
            "description": "Point-in-time bound on which revisions may be used.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Row[]",
          "length": "same-as-input",
          "description": "Per-session highs and lows with the eligible count — the denominator matters, because a count of 30 new highs means different things in a universe of 500 and one of 3,000."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a record lacks the lookback history the count requires",
            "behaviour": "excluded and reported rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(records)",
          "space": "O(sessions)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F03-A01.json",
        "call": "calculate([{\"session_date\":\"2026-01-15\",\"available_at\":\"2026-01-15T21:30:00Z\",\"source_evidence_state\":\"ready\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-HIGH-LOW-12\",\"methodology_id\":\"synthetic-high-low-v1\",\"lookback_sessions\":252,\"new_highs\":2,\"new_lows\":10,\"eligible_issues\":12,\"overlap_issues\":0}], \"2026-03-01T00:00:00Z\")",
        "args": [
          {
            "value": [
              {
                "session_date": "2026-01-15",
                "available_at": "2026-01-15T21:30:00Z",
                "source_evidence_state": "ready",
                "venue_id": "SYNTH-X",
                "universe_id": "SYNTH-HIGH-LOW-12",
                "methodology_id": "synthetic-high-low-v1",
                "lookback_sessions": 252,
                "new_highs": 2,
                "new_lows": 10,
                "eligible_issues": 12,
                "overlap_issues": 0
              }
            ],
            "elided": null
          },
          {
            "value": "2026-03-01T00:00:00Z",
            "elided": null
          }
        ],
        "output": {
          "0": {
            "session_date": "2026-01-15",
            "new_highs": 2,
            "new_lows": 10,
            "value": -8,
            "status": "resolved",
            "reason": null
          }
        },
        "outputElided": null,
        "outputShape": "object with 1 field: 0"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a01/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a01/static/family-map.svg"
          },
          {
            "file": "worked-state.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a01/static/worked-state.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "NASDAQ-FUNDAMENTAL",
          "title": "Nasdaq Fundamental Data",
          "author": null,
          "url": null
        },
        {
          "key": "TRADINGVIEW-HIGHLOW",
          "title": "How High/Low and New High/New Low Are Calculated",
          "author": null,
          "url": null
        },
        {
          "key": "STOCKCHARTS-HIGHLOW",
          "title": "New 52-Week Highs and Lows for Exchanges",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/high-low-and-trend-breadth/new-highs-new-lows/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/high-low-and-trend-breadth/new-highs-new-lows/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F03-A02",
      "name": "High-Low Ratio",
      "headline": null,
      "slug": "high-low-ratio",
      "path": "market-breadth-and-internals/high-low-and-trend-breadth/high-low-ratio",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F03",
        "family": "High/Low and Trend Breadth",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/high-low-and-trend-breadth/high-low-ratio",
        "entry": "calculate",
        "params": [
          "records",
          "decisionTime"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(records, decisionTime)"
      },
      "api": {
        "summary": "New highs as a share of new highs plus new lows — the scale-free form, comparable across universes and eras.",
        "params": [
          {
            "name": "records",
            "type": "Record[]",
            "required": true,
            "description": "Session records with evidence state.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "decisionTime",
            "type": "string",
            "required": true,
            "description": "Point-in-time bound.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Row[]",
          "length": "same-as-input",
          "description": "The ratio per session with the counts behind it."
        },
        "warmup": null,
        "errors": [
          {
            "when": "highs and lows are both zero, making the ratio undefined",
            "behaviour": "reported per row rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(records)",
          "space": "O(sessions)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F03-A02.json",
        "call": "calculate([{\"session_date\":\"2026-01-15\",\"available_at\":\"2026-01-15T21:30:00Z\",\"source_evidence_state\":\"ready\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-HIGH-LOW-12\",\"methodology_id\":\"synthetic-high-low-v1\",\"lookback_sessions\":252,\"new_highs\":2,\"new_lows\":10,\"eligible_issues\":12,\"overlap_issues\":0}], \"2026-03-01T00:00:00Z\")",
        "args": [
          {
            "value": [
              {
                "session_date": "2026-01-15",
                "available_at": "2026-01-15T21:30:00Z",
                "source_evidence_state": "ready",
                "venue_id": "SYNTH-X",
                "universe_id": "SYNTH-HIGH-LOW-12",
                "methodology_id": "synthetic-high-low-v1",
                "lookback_sessions": 252,
                "new_highs": 2,
                "new_lows": 10,
                "eligible_issues": 12,
                "overlap_issues": 0
              }
            ],
            "elided": null
          },
          {
            "value": "2026-03-01T00:00:00Z",
            "elided": null
          }
        ],
        "output": {
          "0": {
            "session_date": "2026-01-15",
            "new_highs": 2,
            "new_lows": 10,
            "value": 0.2,
            "status": "resolved",
            "reason": null
          }
        },
        "outputElided": null,
        "outputShape": "object with 1 field: 0"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a02/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a02/static/family-map.svg"
          },
          {
            "file": "worked-state.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a02/static/worked-state.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "NASDAQ-FUNDAMENTAL",
          "title": "Nasdaq Fundamental Data",
          "author": null,
          "url": null
        },
        {
          "key": "TRADINGVIEW-HIGHLOW",
          "title": "How High/Low and New High/New Low Are Calculated",
          "author": null,
          "url": null
        },
        {
          "key": "STOCKCHARTS-HIGHLOW",
          "title": "New 52-Week Highs and Lows for Exchanges",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/high-low-and-trend-breadth/high-low-ratio/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/high-low-and-trend-breadth/high-low-ratio/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F03-A03",
      "name": "High-Low Index",
      "headline": null,
      "slug": "high-low-index",
      "path": "market-breadth-and-internals/high-low-and-trend-breadth/high-low-index",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F03",
        "family": "High/Low and Trend Breadth",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/high-low-and-trend-breadth/high-low-index",
        "entry": "calculate",
        "params": [
          "records",
          "decisionTime"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(records, decisionTime)"
      },
      "api": {
        "summary": "A moving average of the high–low ratio, which turns a noisy daily reading into something with a usable trend.",
        "params": [
          {
            "name": "records",
            "type": "Record[]",
            "required": true,
            "description": "Session records with evidence state.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "decisionTime",
            "type": "string",
            "required": true,
            "description": "Point-in-time bound.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Row[]",
          "length": "same-as-input",
          "description": "The smoothed index per session."
        },
        "warmup": null,
        "errors": [
          {
            "when": "insufficient history for the smoothing window",
            "behaviour": "reported per row rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(records)",
          "space": "O(sessions)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F03-A03.json",
        "call": "calculate([{\"session_date\":\"2026-01-06\",\"available_at\":\"2026-01-06T21:30:00Z\",\"source_evidence_state\":\"ready\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-HIGH-LOW-12\",\"methodology_id\":\"synthetic-high-low-v1\",\"lookback_sessions\":252,\"new_highs\":7,\"new_lows\":5,\"eligible_issues\":12,\"overlap_issues\":0},{\"session_date\":\"2026-01-07\",\"available_at\":\"2026-01-07T21:30:00Z\",\"source_evidence_state\":\"ready\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-HIGH-LOW-12\",\"methodology_id\":\"synthetic-high-low-v1\",\"lookback_sessions\":252,\"new_highs\":7,\"new_lows\":5,\"eligible_issues\":12,\"overlap_issues\":0},{\"session_date\":\"2026-01-08\",\"available_at\":\"2026-01-08T21:30:00Z\",\"source_evidence_state\":\"ready\",\"venue_id\":\"SYNTH-X\",\"universe_id\":\"SYNTH-HIGH-LOW-12\",\"methodology_id\":\"synthetic-high-low-v1\",\"lookback_sessions\":252,\"new_highs\":7,\"new_lows\":5,\"eligible_issues\":12,\"overlap_issues\":0}], \"2026-03-01T00:00:00Z\")",
        "args": [
          {
            "value": [
              {
                "session_date": "2026-01-06",
                "available_at": "2026-01-06T21:30:00Z",
                "source_evidence_state": "ready",
                "venue_id": "SYNTH-X",
                "universe_id": "SYNTH-HIGH-LOW-12",
                "methodology_id": "synthetic-high-low-v1",
                "lookback_sessions": 252,
                "new_highs": 7,
                "new_lows": 5,
                "eligible_issues": 12,
                "overlap_issues": 0
              },
              {
                "session_date": "2026-01-07",
                "available_at": "2026-01-07T21:30:00Z",
                "source_evidence_state": "ready",
                "venue_id": "SYNTH-X",
                "universe_id": "SYNTH-HIGH-LOW-12",
                "methodology_id": "synthetic-high-low-v1",
                "lookback_sessions": 252,
                "new_highs": 7,
                "new_lows": 5,
                "eligible_issues": 12,
                "overlap_issues": 0
              },
              {
                "session_date": "2026-01-08",
                "available_at": "2026-01-08T21:30:00Z",
                "source_evidence_state": "ready",
                "venue_id": "SYNTH-X",
                "universe_id": "SYNTH-HIGH-LOW-12",
                "methodology_id": "synthetic-high-low-v1",
                "lookback_sessions": 252,
                "new_highs": 7,
                "new_lows": 5,
                "eligible_issues": 12,
                "overlap_issues": 0
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 10
            }
          },
          {
            "value": "2026-03-01T00:00:00Z",
            "elided": null
          }
        ],
        "output": {
          "9": {
            "session_date": "2026-01-15",
            "new_highs": 2,
            "new_lows": 10,
            "value": 54.166666666666664,
            "status": "resolved",
            "reason": null
          }
        },
        "outputElided": null,
        "outputShape": "object with 1 field: 9"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a03/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a03/static/family-map.svg"
          },
          {
            "file": "worked-state.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a03/static/worked-state.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "NASDAQ-FUNDAMENTAL",
          "title": "Nasdaq Fundamental Data",
          "author": null,
          "url": null
        },
        {
          "key": "TRADINGVIEW-HIGHLOW",
          "title": "How High/Low and New High/New Low Are Calculated",
          "author": null,
          "url": null
        },
        {
          "key": "STOCKCHARTS-INDEX",
          "title": "High-Low Index",
          "author": null,
          "url": null
        },
        {
          "key": "PANDAS-ROLLING",
          "title": "Rolling Mean Documentation",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/high-low-and-trend-breadth/high-low-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/high-low-and-trend-breadth/high-low-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F03-A04",
      "name": "Percent Above 20-Day MA",
      "headline": null,
      "slug": "percent-above-20-day-ma",
      "path": "market-breadth-and-internals/high-low-and-trend-breadth/percent-above-20-day-ma",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F03",
        "family": "High/Low and Trend Breadth",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/high-low-and-trend-breadth/percent-above-20-day-ma",
        "entry": "evaluateSnapshot",
        "params": [
          "snapshot",
          "decisionTime"
        ],
        "exports": [
          "evaluateSnapshot"
        ],
        "archetype": "snapshot-evaluate",
        "signature": "evaluateSnapshot(snapshot, decisionTime)"
      },
      "api": {
        "summary": "The share of the universe trading above its own 20-day moving average — a short-horizon participation gauge that turns over quickly.",
        "params": [
          {
            "name": "snapshot",
            "type": "Snapshot",
            "required": true,
            "description": "Universe snapshot with `price_field`, `window_sessions` and per-security history. `universe_revision` is carried so a changing roster does not silently change the denominator.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "decisionTime",
            "type": "string",
            "required": true,
            "description": "Point-in-time bound on which prices may be used.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, window_sessions, eligible_count, above_count, equal_count, percent_above, rows }",
          "description": "The percentage with its numerator and denominator, and `equal_count` broken out separately — securities sitting exactly on their average are neither above nor below, and folding them either way biases the reading."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a security has fewer sessions than the window requires",
            "behaviour": "excluded from the denominator and reported"
          }
        ],
        "complexity": {
          "time": "O(securities × window)",
          "space": "O(securities)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F03-A04.json",
        "call": "evaluateSnapshot({\"window_sessions\":20,\"price_field\":\"adjusted_close\",\"securities\":[{\"security_id\":\"SYNTH-ABOVE\",\"member_at_session\":true,\"source_evidence_state\":\"ready\",\"available_at\":\"2026-06-30T21:30:00Z\",\"adjustment_basis\":\"split-adjusted-price-return\",\"prices\":[100,100,100,100,100,100]}]}, \"2026-06-30T22:00:00Z\")",
        "args": [
          {
            "value": {
              "window_sessions": 20,
              "price_field": "adjusted_close",
              "securities": [
                {
                  "security_id": "SYNTH-ABOVE",
                  "member_at_session": true,
                  "source_evidence_state": "ready",
                  "available_at": "2026-06-30T21:30:00Z",
                  "adjustment_basis": "split-adjusted-price-return",
                  "prices": [
                    100,
                    100,
                    100,
                    100,
                    100,
                    100
                  ]
                }
              ]
            },
            "elided": null
          },
          {
            "value": "2026-06-30T22:00:00Z",
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "reason": null,
          "window_sessions": 20,
          "eligible_count": 1,
          "above_count": 1,
          "equal_count": 0,
          "percent_above": 100
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: status, reason, window_sessions, eligible_count, above_count, equal_count, percent_above"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a04/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a04/static/family-map.svg"
          },
          {
            "file": "worked-state.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a04/static/worked-state.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "STOCKCHARTS-PERCENT",
          "title": "Percent Above Moving Average",
          "author": null,
          "url": null
        },
        {
          "key": "NASDAQ-CORPORATE-ACTIONS",
          "title": "Corporate Actions and Events Manual, Equities",
          "author": null,
          "url": null
        },
        {
          "key": "PANDAS-ROLLING",
          "title": "Rolling Mean Documentation",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/high-low-and-trend-breadth/percent-above-20-day-ma/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/high-low-and-trend-breadth/percent-above-20-day-ma/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F03-A05",
      "name": "Percent Above 50-Day MA",
      "headline": null,
      "slug": "percent-above-50-day-ma",
      "path": "market-breadth-and-internals/high-low-and-trend-breadth/percent-above-50-day-ma",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F03",
        "family": "High/Low and Trend Breadth",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/high-low-and-trend-breadth/percent-above-50-day-ma",
        "entry": "evaluateSnapshot",
        "params": [
          "snapshot",
          "decisionTime"
        ],
        "exports": [
          "evaluateSnapshot"
        ],
        "archetype": "snapshot-evaluate",
        "signature": "evaluateSnapshot(snapshot, decisionTime)"
      },
      "api": {
        "summary": "The same participation measure over 50 sessions — the intermediate-horizon reading, and the one most often quoted for trend health.",
        "params": [
          {
            "name": "snapshot",
            "type": "Snapshot",
            "required": true,
            "description": "Universe snapshot with `price_field`, `window_sessions` and per-security history.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "decisionTime",
            "type": "string",
            "required": true,
            "description": "Point-in-time bound.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, eligible_count, above_count, equal_count, percent_above, rows }",
          "description": "The percentage with its counts."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a security has fewer sessions than the window requires",
            "behaviour": "excluded from the denominator and reported"
          }
        ],
        "complexity": {
          "time": "O(securities × window)",
          "space": "O(securities)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F03-A05.json",
        "call": "evaluateSnapshot({\"window_sessions\":50,\"price_field\":\"adjusted_close\",\"securities\":[{\"security_id\":\"SYNTH-ABOVE\",\"member_at_session\":true,\"source_evidence_state\":\"ready\",\"available_at\":\"2026-06-30T21:30:00Z\",\"adjustment_basis\":\"split-adjusted-price-return\",\"prices\":[100,100,100,100,100,100]}]}, \"2026-06-30T22:00:00Z\")",
        "args": [
          {
            "value": {
              "window_sessions": 50,
              "price_field": "adjusted_close",
              "securities": [
                {
                  "security_id": "SYNTH-ABOVE",
                  "member_at_session": true,
                  "source_evidence_state": "ready",
                  "available_at": "2026-06-30T21:30:00Z",
                  "adjustment_basis": "split-adjusted-price-return",
                  "prices": [
                    100,
                    100,
                    100,
                    100,
                    100,
                    100
                  ]
                }
              ]
            },
            "elided": null
          },
          {
            "value": "2026-06-30T22:00:00Z",
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "reason": null,
          "window_sessions": 50,
          "eligible_count": 1,
          "above_count": 1,
          "equal_count": 0,
          "percent_above": 100
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: status, reason, window_sessions, eligible_count, above_count, equal_count, percent_above"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a05/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a05/static/family-map.svg"
          },
          {
            "file": "worked-state.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a05/static/worked-state.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "STOCKCHARTS-PERCENT",
          "title": "Percent Above Moving Average",
          "author": null,
          "url": null
        },
        {
          "key": "NASDAQ-CORPORATE-ACTIONS",
          "title": "Corporate Actions and Events Manual, Equities",
          "author": null,
          "url": null
        },
        {
          "key": "PANDAS-ROLLING",
          "title": "Rolling Mean Documentation",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/high-low-and-trend-breadth/percent-above-50-day-ma/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/high-low-and-trend-breadth/percent-above-50-day-ma/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F03-A06",
      "name": "Percent Above 200-Day MA",
      "headline": null,
      "slug": "percent-above-200-day-ma",
      "path": "market-breadth-and-internals/high-low-and-trend-breadth/percent-above-200-day-ma",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F03",
        "family": "High/Low and Trend Breadth",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/high-low-and-trend-breadth/percent-above-200-day-ma",
        "entry": "evaluateSnapshot",
        "params": [
          "snapshot",
          "decisionTime"
        ],
        "exports": [
          "evaluateSnapshot"
        ],
        "archetype": "snapshot-evaluate",
        "signature": "evaluateSnapshot(snapshot, decisionTime)"
      },
      "api": {
        "summary": "Participation over 200 sessions — the long-horizon gauge. A rally with 80% of names above their 200-day average is a different market from one with 35%, even at the same index level.",
        "params": [
          {
            "name": "snapshot",
            "type": "Snapshot",
            "required": true,
            "description": "Universe snapshot with `price_field`, `window_sessions` and per-security history.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "decisionTime",
            "type": "string",
            "required": true,
            "description": "Point-in-time bound.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, eligible_count, above_count, equal_count, percent_above, rows }",
          "description": "The percentage with its counts."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a security has fewer sessions than the window requires",
            "behaviour": "excluded from the denominator and reported"
          }
        ],
        "complexity": {
          "time": "O(securities × window)",
          "space": "O(securities)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D04-F03-A06.json",
        "call": "evaluateSnapshot({\"window_sessions\":200,\"price_field\":\"adjusted_close\",\"securities\":[{\"security_id\":\"SYNTH-ABOVE\",\"member_at_session\":true,\"source_evidence_state\":\"ready\",\"available_at\":\"2026-06-30T21:30:00Z\",\"adjustment_basis\":\"split-adjusted-price-return\",\"prices\":[100,100,100,100,100,100]}]}, \"2026-06-30T22:00:00Z\")",
        "args": [
          {
            "value": {
              "window_sessions": 200,
              "price_field": "adjusted_close",
              "securities": [
                {
                  "security_id": "SYNTH-ABOVE",
                  "member_at_session": true,
                  "source_evidence_state": "ready",
                  "available_at": "2026-06-30T21:30:00Z",
                  "adjustment_basis": "split-adjusted-price-return",
                  "prices": [
                    100,
                    100,
                    100,
                    100,
                    100,
                    100
                  ]
                }
              ]
            },
            "elided": null
          },
          {
            "value": "2026-06-30T22:00:00Z",
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "reason": null,
          "window_sessions": 200,
          "eligible_count": 1,
          "above_count": 1,
          "equal_count": 0,
          "percent_above": 100
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: status, reason, window_sessions, eligible_count, above_count, equal_count, percent_above"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a06/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a06/static/family-map.svg"
          },
          {
            "file": "worked-state.svg",
            "url": "https://thefintechbuilder.com/content/d04-f03-a06/static/worked-state.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "STOCKCHARTS-PERCENT",
          "title": "Percent Above Moving Average",
          "author": null,
          "url": null
        },
        {
          "key": "NASDAQ-CORPORATE-ACTIONS",
          "title": "Corporate Actions and Events Manual, Equities",
          "author": null,
          "url": null
        },
        {
          "key": "PANDAS-ROLLING",
          "title": "Rolling Mean Documentation",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decision",
          "title": "Evidence decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/high-low-and-trend-breadth/percent-above-200-day-ma/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/high-low-and-trend-breadth/percent-above-200-day-ma/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F04-A01",
      "name": "Zweig Breadth Thrust",
      "headline": null,
      "slug": "zweig-breadth-thrust",
      "path": "market-breadth-and-internals/thrust-and-pressure/zweig-breadth-thrust",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F04",
        "family": "Thrust and Pressure",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/thrust-and-pressure/zweig-breadth-thrust",
        "entry": "calculate",
        "params": [
          "rows",
          "emaLength",
          "lowThreshold",
          "highThreshold",
          "maxSessions"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(rows, emaLength, lowThreshold, highThreshold, maxSessions)"
      },
      "api": {
        "summary": "Detects the rare initiation signal: the advance ratio moving from below a low threshold to above a high one inside a bounded number of sessions. It fires a handful of times in a generation, which is the point — and also why it cannot be validated on a short sample.",
        "params": [
          {
            "name": "rows",
            "type": "Row[]",
            "required": true,
            "description": "Sessions carrying advances and declines. Rows carry a `ready` flag; a row that is not ready is excluded rather than treated as zero, because a missing count and a count of zero mean opposite things about market breadth.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "emaLength",
            "type": "number",
            "required": true,
            "description": "EMA length applied to the advance ratio. Zweig's original is 10.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "lowThreshold",
            "type": "number",
            "required": true,
            "description": "The ratio the EMA must fall below to arm the signal. Conventionally 0.40.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "highThreshold",
            "type": "number",
            "required": true,
            "description": "The ratio it must then exceed. Conventionally 0.615.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "maxSessions",
            "type": "number",
            "required": true,
            "description": "Maximum sessions permitted between the two crossings; beyond it the move is not a thrust.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, trigger_date, ema, sessions, series }",
          "description": "The trigger date if one occurred, with the EMA path and session count so a near-miss can be seen rather than merely absent."
        },
        "warmup": null,
        "errors": [
          {
            "when": "lowThreshold ≥ highThreshold",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate([{\"session_date\":\"2026-01-05\",\"advances\":520,\"declines\":480,\"ready\":true},{\"session_date\":\"2026-01-06\",\"advances\":500,\"declines\":500,\"ready\":true},{\"session_date\":\"2026-01-07\",\"advances\":480,\"declines\":520,\"ready\":true}], 10, 0.4, 0.615, 10)",
        "args": [
          {
            "value": [
              {
                "session_date": "2026-01-05",
                "advances": 520,
                "declines": 480,
                "ready": true
              },
              {
                "session_date": "2026-01-06",
                "advances": 500,
                "declines": 500,
                "ready": true
              },
              {
                "session_date": "2026-01-07",
                "advances": 480,
                "declines": 520,
                "ready": true
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 24
            }
          },
          {
            "value": 10,
            "elided": null
          },
          {
            "value": 0.4,
            "elided": null
          },
          {
            "value": 0.615,
            "elided": null
          },
          {
            "value": 10,
            "elided": null
          }
        ],
        "output": {
          "status": "thrust",
          "trigger_date": "2026-01-28",
          "ema": 0.6648021169863199,
          "sessions": 6,
          "series": [
            {
              "date": "2026-01-05",
              "ratio": 0.52,
              "ema": 0.52,
              "state": "idle"
            },
            {
              "date": "2026-01-06",
              "ratio": 0.5,
              "ema": 0.5163636363636364,
              "state": "idle"
            },
            {
              "date": "2026-01-07",
              "ratio": 0.48,
              "ema": 0.5097520661157025,
              "state": "idle"
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: status, trigger_date, ema, sessions, series"
      },
      "verification": {
        "tier": "verified",
        "via": "row-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f04-a01/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f04-a01/static/family-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "STOCKCHARTS-BREADTH",
          "title": "Advance-Decline Indicators",
          "author": "StockCharts ChartSchool",
          "url": null
        },
        {
          "key": "STOCKCHARTS-ZBT",
          "title": "Advance Decline Ratio Indicators, Chapter 5",
          "author": "Greg Morris, StockCharts",
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/thrust-and-pressure/zweig-breadth-thrust/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/thrust-and-pressure/zweig-breadth-thrust/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F04-A02",
      "name": "Arms Index (TRIN)",
      "headline": null,
      "slug": "arms-index-trin",
      "path": "market-breadth-and-internals/thrust-and-pressure/arms-index-trin",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F04",
        "family": "Thrust and Pressure",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/thrust-and-pressure/arms-index-trin",
        "entry": "calculate",
        "params": [
          "row"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(row)"
      },
      "api": {
        "summary": "TRIN: the advance/decline issue ratio divided by the advance/decline volume ratio. Above 1 means declining issues are absorbing proportionally more volume than their numbers suggest — the arithmetic is a comparison of two ratios, and inverting either flips the reading.",
        "params": [
          {
            "name": "row",
            "type": "Row",
            "required": true,
            "description": "One session's advances, declines, unchanged and directional volume. Rows carry a `ready` flag; a row that is not ready is excluded rather than treated as zero, because a missing count and a count of zero mean opposite things about market breadth.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, value, issue_ratio, volume_ratio }",
          "description": "TRIN with both component ratios exposed, which is what makes an unexpected value diagnosable."
        },
        "warmup": null,
        "errors": [
          {
            "when": "either denominator is zero",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"session_date\":\"2026-02-05\",\"advances\":600,\"declines\":400,\"unchanged\":20,\"advancing_volume\":120000000,\"declining_volume\":60000000,\"ready\":true})",
        "args": [
          {
            "value": {
              "session_date": "2026-02-05",
              "advances": 600,
              "declines": 400,
              "unchanged": 20,
              "advancing_volume": 120000000,
              "declining_volume": 60000000,
              "ready": true
            },
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "value": 0.75,
          "issue_ratio": 1.5,
          "volume_ratio": 2
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: status, value, issue_ratio, volume_ratio"
      },
      "verification": {
        "tier": "verified",
        "via": "row-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f04-a02/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f04-a02/static/family-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "FIDELITY-TRIN",
          "title": "Arms Index (TRIN)",
          "author": "Fidelity",
          "url": null
        },
        {
          "key": "STOCKCHARTS-TRIN",
          "title": "Arms Index (TRIN)",
          "author": "StockCharts ChartSchool",
          "url": null
        },
        {
          "key": "TRADESTATION-TRIN",
          "title": "ArmsIndex Function",
          "author": "TradeStation",
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/thrust-and-pressure/arms-index-trin/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/thrust-and-pressure/arms-index-trin/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F04-A03",
      "name": "Advance/Decline Volume Line",
      "headline": null,
      "slug": "advance-decline-volume-line",
      "path": "market-breadth-and-internals/thrust-and-pressure/advance-decline-volume-line",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F04",
        "family": "Thrust and Pressure",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/thrust-and-pressure/advance-decline-volume-line",
        "entry": "calculate",
        "params": [
          "rows",
          "seed"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(rows, seed)"
      },
      "api": {
        "summary": "The cumulative line built from advancing minus declining volume rather than issue counts. Where the issue-based line counts participants, this one weights them by how much they traded.",
        "params": [
          {
            "name": "rows",
            "type": "Row[]",
            "required": true,
            "description": "Sessions carrying directional volume. Rows carry a `ready` flag; a row that is not ready is excluded rather than treated as zero, because a missing count and a count of zero mean opposite things about market breadth.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "seed",
            "type": "number",
            "required": true,
            "description": "Starting value of the accumulation; affects the level only.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, value, series }",
          "description": "The cumulative series and its latest value."
        },
        "warmup": null,
        "errors": [
          {
            "when": "volume fields are absent on a ready row",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate([{\"session_date\":\"2026-01-05\",\"advances\":520,\"declines\":480,\"unchanged\":20,\"advancing_volume\":92000000,\"declining_volume\":78000000,\"ready\":true},{\"session_date\":\"2026-01-06\",\"advances\":480,\"declines\":520,\"unchanged\":20,\"advancing_volume\":86000000,\"declining_volume\":94000000,\"ready\":true},{\"session_date\":\"2026-01-07\",\"advances\":540,\"declines\":460,\"unchanged\":20,\"advancing_volume\":108000000,\"declining_volume\":72000000,\"ready\":true}], 0)",
        "args": [
          {
            "value": [
              {
                "session_date": "2026-01-05",
                "advances": 520,
                "declines": 480,
                "unchanged": 20,
                "advancing_volume": 92000000,
                "declining_volume": 78000000,
                "ready": true
              },
              {
                "session_date": "2026-01-06",
                "advances": 480,
                "declines": 520,
                "unchanged": 20,
                "advancing_volume": 86000000,
                "declining_volume": 94000000,
                "ready": true
              },
              {
                "session_date": "2026-01-07",
                "advances": 540,
                "declines": 460,
                "unchanged": 20,
                "advancing_volume": 108000000,
                "declining_volume": 72000000,
                "ready": true
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 24
            }
          },
          {
            "value": 0,
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "value": 96000000,
          "series": [
            {
              "date": "2026-01-05",
              "net": 14000000,
              "value": 14000000
            },
            {
              "date": "2026-01-06",
              "net": -8000000,
              "value": 6000000
            },
            {
              "date": "2026-01-07",
              "net": 36000000,
              "value": 42000000
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: status, value, series"
      },
      "verification": {
        "tier": "verified",
        "via": "row-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f04-a03/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f04-a03/static/family-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "STOCKCHARTS-ADVL",
          "title": "Advance-Decline Volume Line",
          "author": "StockCharts ChartSchool",
          "url": null
        },
        {
          "key": "STOCKCHARTS-BREADTH",
          "title": "Advance-Decline Indicators",
          "author": "StockCharts ChartSchool",
          "url": null
        },
        {
          "key": "NYSE-VOLUME",
          "title": "Volume Summary Client Specification v1.1d",
          "author": "New York Stock Exchange",
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/thrust-and-pressure/advance-decline-volume-line/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/thrust-and-pressure/advance-decline-volume-line/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F04-A04",
      "name": "Upside/Downside Volume Ratio",
      "headline": null,
      "slug": "upside-downside-volume-ratio",
      "path": "market-breadth-and-internals/thrust-and-pressure/upside-downside-volume-ratio",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F04",
        "family": "Thrust and Pressure",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/thrust-and-pressure/upside-downside-volume-ratio",
        "entry": "calculate",
        "params": [
          "row"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(row)"
      },
      "api": {
        "summary": "Advancing volume over declining volume for one session. Extreme readings mark the days that matter — a 9-to-1 up day is a recognised initiation signal precisely because it is rare.",
        "params": [
          {
            "name": "row",
            "type": "Row",
            "required": true,
            "description": "One session's directional volume. Rows carry a `ready` flag; a row that is not ready is excluded rather than treated as zero, because a missing count and a count of zero mean opposite things about market breadth.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, value }",
          "description": "The ratio, or a status explaining why it could not be formed."
        },
        "warmup": null,
        "errors": [
          {
            "when": "declining volume is zero",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate({\"session_date\":\"2026-02-05\",\"advances\":600,\"declines\":400,\"unchanged\":20,\"advancing_volume\":120000000,\"declining_volume\":60000000,\"ready\":true})",
        "args": [
          {
            "value": {
              "session_date": "2026-02-05",
              "advances": 600,
              "declines": 400,
              "unchanged": 20,
              "advancing_volume": 120000000,
              "declining_volume": 60000000,
              "ready": true
            },
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "value": 2
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: status, value"
      },
      "verification": {
        "tier": "verified",
        "via": "row-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f04-a04/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f04-a04/static/family-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "STOCKCHARTS-UPDOWN",
          "title": "Up Volume Down Volume Indicators, Chapter 8",
          "author": "Greg Morris, StockCharts",
          "url": null
        },
        {
          "key": "STOCKCHARTS-CATALOG",
          "title": "NYSE Breadth Symbol Catalog",
          "author": "StockCharts",
          "url": null
        },
        {
          "key": "NYSE-VOLUME",
          "title": "Volume Summary Client Specification v1.1d",
          "author": "New York Stock Exchange",
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/thrust-and-pressure/upside-downside-volume-ratio/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/thrust-and-pressure/upside-downside-volume-ratio/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F04-A05",
      "name": "Cumulative TICK",
      "headline": null,
      "slug": "cumulative-tick",
      "path": "market-breadth-and-internals/thrust-and-pressure/cumulative-tick",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F04",
        "family": "Thrust and Pressure",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/thrust-and-pressure/cumulative-tick",
        "entry": "calculate",
        "params": [
          "rows",
          "seed",
          "intervalSeconds"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(rows, seed, intervalSeconds)"
      },
      "api": {
        "summary": "Accumulates the net count of issues trading on an uptick versus a downtick. An intraday pressure gauge — it measures the balance of buying and selling *urgency* within the session rather than the outcome at the close.",
        "params": [
          {
            "name": "rows",
            "type": "TickRow[]",
            "required": true,
            "description": "Intraday observations of uptick, downtick and neutral issue counts. Rows carry a `ready` flag; a row that is not ready is excluded rather than treated as zero, because a missing count and a count of zero mean opposite things about market breadth.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "seed",
            "type": "number",
            "required": true,
            "description": "Starting value of the accumulation.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "intervalSeconds",
            "type": "number",
            "required": true,
            "description": "Sampling interval of the observations, recorded so a series sampled at one rate is not compared with one sampled at another.",
            "constraints": {
              "min": 1
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, value, interval_seconds, series }",
          "description": "The cumulative series with the interval it was sampled at."
        },
        "warmup": null,
        "errors": [
          {
            "when": "intervalSeconds is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate([{\"timestamp\":\"2026-01-05T09:30:00-05:00\",\"session_id\":\"XNYS-2026-01-05\",\"uptick_issues\":560,\"downtick_issues\":440,\"neutral_issues\":20,\"ready\":true},{\"timestamp\":\"2026-01-05T09:31:00-05:00\",\"session_id\":\"XNYS-2026-01-05\",\"uptick_issues\":470,\"downtick_issues\":530,\"neutral_issues\":20,\"ready\":true},{\"timestamp\":\"2026-01-05T09:32:00-05:00\",\"session_id\":\"XNYS-2026-01-05\",\"uptick_issues\":540,\"downtick_issues\":460,\"neutral_issues\":20,\"ready\":true}], 0, 60)",
        "args": [
          {
            "value": [
              {
                "timestamp": "2026-01-05T09:30:00-05:00",
                "session_id": "XNYS-2026-01-05",
                "uptick_issues": 560,
                "downtick_issues": 440,
                "neutral_issues": 20,
                "ready": true
              },
              {
                "timestamp": "2026-01-05T09:31:00-05:00",
                "session_id": "XNYS-2026-01-05",
                "uptick_issues": 470,
                "downtick_issues": 530,
                "neutral_issues": 20,
                "ready": true
              },
              {
                "timestamp": "2026-01-05T09:32:00-05:00",
                "session_id": "XNYS-2026-01-05",
                "uptick_issues": 540,
                "downtick_issues": 460,
                "neutral_issues": 20,
                "ready": true
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 36
            }
          },
          {
            "value": 0,
            "elided": null
          },
          {
            "value": 60,
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "value": 1380,
          "interval_seconds": 60,
          "series": [
            {
              "timestamp": "2026-01-05T09:30:00-05:00",
              "tick": 120,
              "value": 120
            },
            {
              "timestamp": "2026-01-05T09:31:00-05:00",
              "tick": -60,
              "value": 60
            },
            {
              "timestamp": "2026-01-05T09:32:00-05:00",
              "tick": 80,
              "value": 140
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: status, value, interval_seconds, series"
      },
      "verification": {
        "tier": "verified",
        "via": "row-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f04-a05/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f04-a05/static/family-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "STOCKCHARTS-TICK",
          "title": "Glossary: TICK",
          "author": "StockCharts ChartSchool",
          "url": null
        },
        {
          "key": "NYSE-REALTIME",
          "title": "NYSE Real-Time Data",
          "author": "New York Stock Exchange",
          "url": null
        },
        {
          "key": "NYSE-TECHDOCS",
          "title": "NYSE Proprietary Data Products Technical Documents",
          "author": "New York Stock Exchange",
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/thrust-and-pressure/cumulative-tick/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/thrust-and-pressure/cumulative-tick/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F04-A06",
      "name": "Breadth-Divergence Detector",
      "headline": null,
      "slug": "breadth-divergence-detector",
      "path": "market-breadth-and-internals/thrust-and-pressure/breadth-divergence-detector",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F04",
        "family": "Thrust and Pressure",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/thrust-and-pressure/breadth-divergence-detector",
        "entry": "calculate",
        "params": [
          "rows",
          "left",
          "right",
          "minPriceChange",
          "minBreadthSeparation",
          "breadthScale"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(rows, left, right, minPriceChange, minBreadthSeparation, breadthScale)"
      },
      "api": {
        "summary": "Flags sessions where the index and a breadth measure move meaningfully in opposite directions — the classic warning that an advance is being carried by fewer and fewer names.",
        "params": [
          {
            "name": "rows",
            "type": "Row[]",
            "required": true,
            "description": "Sessions carrying an index level and a breadth value. Rows carry a `ready` flag; a row that is not ready is excluded rather than treated as zero, because a missing count and a count of zero mean opposite things about market breadth.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "left",
            "type": "number",
            "required": true,
            "description": "Left comparison offset in sessions.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "right",
            "type": "number",
            "required": true,
            "description": "Right comparison offset in sessions.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "minPriceChange",
            "type": "number",
            "required": true,
            "description": "Minimum index move required before a divergence is considered; filters noise.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "minBreadthSeparation",
            "type": "number",
            "required": true,
            "description": "Minimum breadth move required, expressed in the units `breadthScale` implies.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "breadthScale",
            "type": "number",
            "required": true,
            "description": "Scaling applied to the breadth series before comparison. **Note:** the published fixture and this implementation currently disagree on the unit of the resulting `breadth_separation` — the fixture states a ratio, the implementation returns a scaled value. See the article before relying on an absolute threshold.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, events }",
          "description": "The divergence events detected, each naming the sessions compared and the separation measured."
        },
        "warmup": null,
        "errors": [
          {
            "when": "left ≤ right, making the comparison window invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(events)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate([{\"session_date\":\"2026-01-05\",\"index_level\":100,\"breadth_value\":500,\"ready\":true},{\"session_date\":\"2026-01-06\",\"index_level\":101,\"breadth_value\":520,\"ready\":true},{\"session_date\":\"2026-01-07\",\"index_level\":102,\"breadth_value\":540,\"ready\":true}], 2, 2, 0.01, 0.05, 1000)",
        "args": [
          {
            "value": [
              {
                "session_date": "2026-01-05",
                "index_level": 100,
                "breadth_value": 500,
                "ready": true
              },
              {
                "session_date": "2026-01-06",
                "index_level": 101,
                "breadth_value": 520,
                "ready": true
              },
              {
                "session_date": "2026-01-07",
                "index_level": 102,
                "breadth_value": 540,
                "ready": true
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 36
            }
          },
          {
            "value": 2,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          },
          {
            "value": 0.01,
            "elided": null
          },
          {
            "value": 0.05,
            "elided": null
          },
          {
            "value": 1000,
            "elided": null
          }
        ],
        "output": {
          "status": "bearish",
          "events": [
            {
              "status": "bearish",
              "first_pivot_date": "2026-01-19",
              "second_pivot_date": "2026-02-05",
              "confirmation_date": "2026-02-09",
              "price_change": 0.05454545454545454,
              "breadth_separation": -0.13,
              "breadth_scale": 1000
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: status, events"
      },
      "verification": {
        "tier": "verified",
        "via": "row-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f04-a06/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f04-a06/static/family-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "FIDELITY-DIVERGENCE",
          "title": "Advance/Decline Indicator",
          "author": "Fidelity",
          "url": null
        },
        {
          "key": "STOCKCHARTS-ADVL",
          "title": "Advance-Decline Volume Line",
          "author": "StockCharts ChartSchool",
          "url": null
        },
        {
          "key": "STOCKCHARTS-BREADTH",
          "title": "Advance-Decline Indicators",
          "author": "StockCharts ChartSchool",
          "url": null
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/thrust-and-pressure/breadth-divergence-detector/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/thrust-and-pressure/breadth-divergence-detector/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F05-A01",
      "name": "Top-N Index Contribution",
      "headline": null,
      "slug": "top-n-index-contribution",
      "path": "market-breadth-and-internals/concentration-and-diffusion/top-n-index-contribution",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F05",
        "family": "Concentration and Diffusion",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/concentration-and-diffusion/top-n-index-contribution",
        "entry": "calculate",
        "params": [
          "rows",
          "topN"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(rows, topN)"
      },
      "api": {
        "summary": "How much of an index's move came from its largest N members. This is the arithmetic behind 'seven stocks are holding up the market' — a claim that is usually asserted and rarely measured.",
        "params": [
          {
            "name": "rows",
            "type": "Row[]",
            "required": true,
            "description": "Constituents with weight, return and sector. Rows carry a `ready` flag; a row that is not ready is excluded rather than treated as zero, because a missing count and a count of zero mean opposite things about market breadth.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "topN",
            "type": "number",
            "required": true,
            "description": "How many leading contributors to attribute separately.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, top_n, top_contribution, total_contribution, share, leaders }",
          "description": "The leaders' contribution, the total, and the share — plus the leaders themselves, so the claim can be named rather than gestured at."
        },
        "warmup": null,
        "errors": [
          {
            "when": "topN exceeds the number of ready constituents",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate([{\"security_id\":\"S01\",\"weight\":0.17821782178217824,\"return\":0.065,\"sector\":\"Tech\",\"ready\":true},{\"security_id\":\"S02\",\"weight\":0.13861386138613863,\"return\":0.041,\"sector\":\"Financials\",\"ready\":true},{\"security_id\":\"S03\",\"weight\":0.10891089108910892,\"return\":0.028,\"sector\":\"Industrials\",\"ready\":true}], 5)",
        "args": [
          {
            "value": [
              {
                "security_id": "S01",
                "weight": 0.17821782178217824,
                "return": 0.065,
                "sector": "Tech",
                "ready": true
              },
              {
                "security_id": "S02",
                "weight": 0.13861386138613863,
                "return": 0.041,
                "sector": "Financials",
                "ready": true
              },
              {
                "security_id": "S03",
                "weight": 0.10891089108910892,
                "return": 0.028,
                "sector": "Industrials",
                "ready": true
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 24
            }
          },
          {
            "value": 5,
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "top_n": 5,
          "top_contribution": 0.02225742574257426,
          "total_contribution": 0.021676237623762376,
          "share": 1.0268122230850045,
          "leaders": [
            {
              "security_id": "S01",
              "contribution": 0.011584158415841586
            },
            {
              "security_id": "S02",
              "contribution": 0.005683168316831684
            },
            {
              "security_id": "S03",
              "contribution": 0.00304950495049505
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: status, top_n, top_contribution, total_contribution, share, leaders"
      },
      "verification": {
        "tier": "verified",
        "via": "row-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f05-a01/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f05-a01/static/family-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "SPDJI-MATH",
          "title": "S&P Dow Jones Indices: Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/concentration-and-diffusion/top-n-index-contribution/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/concentration-and-diffusion/top-n-index-contribution/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F05-A02",
      "name": "Herfindahl Constituent Concentration",
      "headline": null,
      "slug": "herfindahl-constituent-concentration",
      "path": "market-breadth-and-internals/concentration-and-diffusion/herfindahl-constituent-concentration",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F05",
        "family": "Concentration and Diffusion",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/concentration-and-diffusion/herfindahl-constituent-concentration",
        "entry": "calculate",
        "params": [
          "rows"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(rows)"
      },
      "api": {
        "summary": "The Herfindahl–Hirschman index of constituent weights: the sum of squared weights. Squaring is what makes it a concentration measure — it is dominated by the largest holdings in a way a simple count never is.",
        "params": [
          {
            "name": "rows",
            "type": "Row[]",
            "required": true,
            "description": "Constituents with weights. Rows carry a `ready` flag; a row that is not ready is excluded rather than treated as zero, because a missing count and a count of zero mean opposite things about market breadth.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, hhi, hhi_points }",
          "description": "HHI as a fraction and in the conventional points form, which differ by a factor of 10,000 and are frequently confused."
        },
        "warmup": null,
        "errors": [
          {
            "when": "weights do not sum to approximately 1",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate([{\"security_id\":\"S01\",\"weight\":0.17821782178217824,\"return\":0.065,\"sector\":\"Tech\",\"ready\":true},{\"security_id\":\"S02\",\"weight\":0.13861386138613863,\"return\":0.041,\"sector\":\"Financials\",\"ready\":true},{\"security_id\":\"S03\",\"weight\":0.10891089108910892,\"return\":0.028,\"sector\":\"Industrials\",\"ready\":true}])",
        "args": [
          {
            "value": [
              {
                "security_id": "S01",
                "weight": 0.17821782178217824,
                "return": 0.065,
                "sector": "Tech",
                "ready": true
              },
              {
                "security_id": "S02",
                "weight": 0.13861386138613863,
                "return": 0.041,
                "sector": "Financials",
                "ready": true
              },
              {
                "security_id": "S03",
                "weight": 0.10891089108910892,
                "return": 0.028,
                "sector": "Industrials",
                "ready": true
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 24
            }
          }
        ],
        "output": {
          "status": "resolved",
          "hhi": 0.0898088422703657,
          "hhi_points": 898.088422703657
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: status, hhi, hhi_points"
      },
      "verification": {
        "tier": "verified",
        "via": "row-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f05-a02/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f05-a02/static/family-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "DOJ-HHI",
          "title": "Herfindahl-Hirschman Index",
          "author": "U.S. Department of Justice, Antitrust Division",
          "url": "https://www.justice.gov/atr/herfindahl-hirschman-index"
        },
        {
          "key": "SPDJI-MATH",
          "title": "S&P Dow Jones Indices: Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/concentration-and-diffusion/herfindahl-constituent-concentration/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/concentration-and-diffusion/herfindahl-constituent-concentration/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F05-A03",
      "name": "Effective Number of Constituents",
      "headline": null,
      "slug": "effective-number-of-constituents",
      "path": "market-breadth-and-internals/concentration-and-diffusion/effective-number-of-constituents",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F05",
        "family": "Concentration and Diffusion",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/concentration-and-diffusion/effective-number-of-constituents",
        "entry": "calculate",
        "params": [
          "rows"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(rows)"
      },
      "api": {
        "summary": "The reciprocal of HHI: how many equally weighted holdings would give the same concentration. An index of 500 names with an effective number of 60 is, for risk purposes, a 60-stock portfolio.",
        "params": [
          {
            "name": "rows",
            "type": "Row[]",
            "required": true,
            "description": "Constituents with weights. Rows carry a `ready` flag; a row that is not ready is excluded rather than treated as zero, because a missing count and a count of zero mean opposite things about market breadth.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, effective_n, actual_n, hhi }",
          "description": "The effective count beside the actual count — the gap between them is the entire message."
        },
        "warmup": null,
        "errors": [
          {
            "when": "weights do not sum to approximately 1",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate([{\"security_id\":\"S01\",\"weight\":0.17821782178217824,\"return\":0.065,\"sector\":\"Tech\",\"ready\":true},{\"security_id\":\"S02\",\"weight\":0.13861386138613863,\"return\":0.041,\"sector\":\"Financials\",\"ready\":true},{\"security_id\":\"S03\",\"weight\":0.10891089108910892,\"return\":0.028,\"sector\":\"Industrials\",\"ready\":true}])",
        "args": [
          {
            "value": [
              {
                "security_id": "S01",
                "weight": 0.17821782178217824,
                "return": 0.065,
                "sector": "Tech",
                "ready": true
              },
              {
                "security_id": "S02",
                "weight": 0.13861386138613863,
                "return": 0.041,
                "sector": "Financials",
                "ready": true
              },
              {
                "security_id": "S03",
                "weight": 0.10891089108910892,
                "return": 0.028,
                "sector": "Industrials",
                "ready": true
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 24
            }
          }
        ],
        "output": {
          "status": "resolved",
          "effective_n": 11.134761062719665,
          "actual_n": 24,
          "hhi": 0.0898088422703657
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: status, effective_n, actual_n, hhi"
      },
      "verification": {
        "tier": "verified",
        "via": "row-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f05-a03/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f05-a03/static/family-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "DOJ-HHI",
          "title": "Herfindahl-Hirschman Index",
          "author": "U.S. Department of Justice, Antitrust Division",
          "url": "https://www.justice.gov/atr/herfindahl-hirschman-index"
        },
        {
          "key": "HILL-1973",
          "title": "Diversity and Evenness: A Unifying Notation and Its Consequences",
          "author": "Mark O. Hill",
          "url": "https://esajournals.onlinelibrary.wiley.com/doi/10.2307/1934352"
        },
        {
          "key": "SPDJI-MATH",
          "title": "S&P Dow Jones Indices: Index Mathematics Methodology",
          "author": "S&P Dow Jones Indices",
          "url": "https://www.spglobal.com/spdji/en/documents/methodologies/methodology-index-math.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/concentration-and-diffusion/effective-number-of-constituents/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/concentration-and-diffusion/effective-number-of-constituents/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F05-A04",
      "name": "Sector Diffusion Index",
      "headline": null,
      "slug": "sector-diffusion-index",
      "path": "market-breadth-and-internals/concentration-and-diffusion/sector-diffusion-index",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F05",
        "family": "Concentration and Diffusion",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/concentration-and-diffusion/sector-diffusion-index",
        "entry": "calculate",
        "params": [
          "rows",
          "tolerance"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(rows, tolerance)"
      },
      "api": {
        "summary": "The share of sectors improving rather than deteriorating. Diffusion asks how *broad* a move is across groups, which a capitalisation-weighted index cannot show — one sector can carry the whole level.",
        "params": [
          {
            "name": "rows",
            "type": "Row[]",
            "required": true,
            "description": "One row per sector carrying its signal change. Rows carry a `ready` flag; a row that is not ready is excluded rather than treated as zero, because a missing count and a count of zero mean opposite things about market breadth.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "tolerance",
            "type": "number",
            "required": true,
            "description": "Band within which a change counts as unchanged rather than improving or deteriorating. Without it, floating-point noise makes everything move.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, value, improving, unchanged, deteriorating, total }",
          "description": "The diffusion value with the three counts behind it."
        },
        "warmup": null,
        "errors": [
          {
            "when": "tolerance is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate([{\"component_id\":\"Communication\",\"signal_change\":0.012,\"ready\":true},{\"component_id\":\"Consumer Discretionary\",\"signal_change\":0.008,\"ready\":true},{\"component_id\":\"Consumer Staples\",\"signal_change\":0.006,\"ready\":true}], 0.002)",
        "args": [
          {
            "value": [
              {
                "component_id": "Communication",
                "signal_change": 0.012,
                "ready": true
              },
              {
                "component_id": "Consumer Discretionary",
                "signal_change": 0.008,
                "ready": true
              },
              {
                "component_id": "Consumer Staples",
                "signal_change": 0.006,
                "ready": true
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 11
            }
          },
          {
            "value": 0.002,
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "value": 59.09090909090909,
          "improving": 5,
          "unchanged": 3,
          "deteriorating": 3,
          "total": 11
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: status, value, improving, unchanged, deteriorating, total"
      },
      "verification": {
        "tier": "verified",
        "via": "row-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f05-a04/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f05-a04/static/family-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "TCB-DIFF",
          "title": "How to Compute Diffusion Indexes",
          "author": "The Conference Board",
          "url": "https://www.conference-board.org/data/bci/index.cfm?id=2180"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/concentration-and-diffusion/sector-diffusion-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/concentration-and-diffusion/sector-diffusion-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D04-F05-A05",
      "name": "Factor Diffusion Index",
      "headline": null,
      "slug": "factor-diffusion-index",
      "path": "market-breadth-and-internals/concentration-and-diffusion/factor-diffusion-index",
      "taxonomy": {
        "domainId": "D04",
        "domain": "Market Breadth and Internals",
        "familyId": "D04-F05",
        "family": "Concentration and Diffusion",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-breadth-and-internals/concentration-and-diffusion/factor-diffusion-index",
        "entry": "calculate",
        "params": [
          "rows",
          "tolerance"
        ],
        "exports": [
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(rows, tolerance)"
      },
      "api": {
        "summary": "The same diffusion measure across factors rather than sectors — momentum, size, volatility — showing whether a move is broad across styles or concentrated in one.",
        "params": [
          {
            "name": "rows",
            "type": "Row[]",
            "required": true,
            "description": "One row per factor carrying its signal change. Rows carry a `ready` flag; a row that is not ready is excluded rather than treated as zero, because a missing count and a count of zero mean opposite things about market breadth.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "tolerance",
            "type": "number",
            "required": true,
            "description": "Band within which a change counts as unchanged.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, value, improving, unchanged, deteriorating, total }",
          "description": "The diffusion value with its component counts."
        },
        "warmup": null,
        "errors": [
          {
            "when": "tolerance is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate([{\"component_id\":\"Value\",\"signal_change\":0.014,\"ready\":true},{\"component_id\":\"Momentum\",\"signal_change\":0.011,\"ready\":true},{\"component_id\":\"Quality\",\"signal_change\":0.007,\"ready\":true}], 0.002)",
        "args": [
          {
            "value": [
              {
                "component_id": "Value",
                "signal_change": 0.014,
                "ready": true
              },
              {
                "component_id": "Momentum",
                "signal_change": 0.011,
                "ready": true
              },
              {
                "component_id": "Quality",
                "signal_change": 0.007,
                "ready": true
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 8
            }
          },
          {
            "value": 0.002,
            "elided": null
          }
        ],
        "output": {
          "status": "resolved",
          "value": 62.5,
          "improving": 4,
          "unchanged": 2,
          "deteriorating": 2,
          "total": 8
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: status, value, improving, unchanged, deteriorating, total"
      },
      "verification": {
        "tier": "verified",
        "via": "row-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d04-f05-a05/static/decision-boundary.svg"
          },
          {
            "file": "family-map.svg",
            "url": "https://thefintechbuilder.com/content/d04-f05-a05/static/family-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "TCB-DIFF",
          "title": "How to Compute Diffusion Indexes",
          "author": "The Conference Board",
          "url": "https://www.conference-board.org/data/bci/index.cfm?id=2180"
        },
        {
          "key": "MSCI-FACTORS",
          "title": "MSCI Factor Indexes",
          "author": "MSCI",
          "url": "https://www.msci.com/indexes/factor-indexes/msci-factor-indexes"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-breadth-and-internals/concentration-and-diffusion/factor-diffusion-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-breadth-and-internals/concentration-and-diffusion/factor-diffusion-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F01-A01",
      "name": "Candle Anatomy",
      "headline": null,
      "slug": "candle-anatomy",
      "path": "price-action-and-candlesticks/candle-foundations/candle-anatomy",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F01",
        "family": "Candle Foundations",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/candle-foundations/candle-anatomy",
        "entry": "analyzeCandle",
        "params": [
          "candle",
          "directionEpsilon"
        ],
        "exports": [
          "analyzeCandle",
          "analyzeCandles"
        ],
        "archetype": "record-transform",
        "signature": "analyzeCandle(candle, directionEpsilon)"
      },
      "api": {
        "summary": "Decomposes one candle into body, upper and lower shadow, and direction. Every candlestick pattern is built on these measurements, so an inconsistent decomposition propagates into every pattern above it.",
        "params": [
          {
            "name": "candle",
            "type": "Candle",
            "required": true,
            "description": "One OHLC candle with `is_closed`. An unclosed candle can still be analysed, but its body may yet change — the flag is carried through so downstream code can decide.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "directionEpsilon",
            "type": "number",
            "required": true,
            "description": "How close open and close must be to count as unchanged rather than up or down. Without it, floating-point noise makes a doji impossible.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ open, high, low, close, body, upper_shadow, lower_shadow, direction, … }",
          "description": "Every measurement a pattern rule needs, in price units."
        },
        "warmup": null,
        "errors": [
          {
            "when": "high is below low, or open or close falls outside the range",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D06-F01-A01.json",
        "call": "analyzeCandle({\"timestamp\":\"2026-01-05T10:00:00Z\",\"instrument_id\":\"SYNTH:ABC\",\"interval\":\"5m\",\"open\":100,\"high\":108,\"low\":97,\"close\":105,\"is_closed\":true,\"price_basis\":\"raw-trades\",\"session\":\"synthetic-utc\"}, 0)",
        "args": [
          {
            "value": {
              "timestamp": "2026-01-05T10:00:00Z",
              "instrument_id": "SYNTH:ABC",
              "interval": "5m",
              "open": 100,
              "high": 108,
              "low": 97,
              "close": 105,
              "is_closed": true,
              "price_basis": "raw-trades",
              "session": "synthetic-utc"
            },
            "elided": null
          },
          {
            "value": 0,
            "elided": null
          }
        ],
        "output": {
          "open": 100,
          "high": 108,
          "low": 97,
          "close": 105,
          "timestamp": "2026-01-05T10:00:00Z",
          "instrument_id": "SYNTH:ABC",
          "interval": "5m",
          "is_closed": true,
          "volume": null,
          "price_basis": "raw-trades",
          "session": "synthetic-utc",
          "body_high": 105,
          "body_low": 100,
          "body": 5
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 23
        },
        "outputShape": "object with 23 fields: open, high, low, close, timestamp, instrument_id, interval, is_closed, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "candle-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d06-f01-a01/static/candle-anatomy.svg"
          },
          {
            "file": "candle-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d06-f01-a01/static/candle-comparison.svg"
          }
        ],
        "mermaid": [
          {
            "file": "bar-lifecycle.md",
            "caption": "Candle lifecycle and revision state",
            "source": "stateDiagram-v2\n    [*] --> Collecting\n    Collecting --> Provisional: first eligible price\n    Provisional --> Provisional: new trade updates high, low, or close\n    Provisional --> Closed: interval ends\n    Closed --> Revised: provider correction\n    Revised --> Closed: corrected OHLC republished\n    Closed --> [*]"
          },
          {
            "file": "calculation-flow.md",
            "caption": "Candle anatomy calculation flow",
            "source": "flowchart TD\n    A[\"Receive OHLC and metadata\"] --> B{\"All OHLC values finite?\"}\n    B -->|\"No\"| X[\"Reject with validation error\"]\n    B -->|\"Yes\"| C{\"High and low contain open and close?\"}\n    C -->|\"No\"| X\n    C -->|\"Yes\"| D[\"Compute body high and body low\"]\n    D --> E[\"Compute body, shadows, and range\"]\n    E --> F[\"Assign direction using epsilon\"]\n    F --> G{\"Range greater than zero?\"}\n    G -->|\"Yes\"| H[\"Compute component ratios and positions\"]\n    G -->|\"No\"| I[\"Set ratios and positions to null\"]\n    H --> J[\"Return anatomy and metadata\"]\n    I --> J"
          }
        ]
      },
      "references": [
        {
          "key": "R01",
          "title": "Chart Types: Candlestick, Line, Bar",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/courses/technical-analysis/chart-types-candlestick-line-bar"
        },
        {
          "key": "R02",
          "title": "Candlestick chart definition",
          "author": "Nasdaq",
          "url": "https://www.nasdaq.com/glossary/c/candlestick-chart"
        },
        {
          "key": "R03",
          "title": "Kline/Candlestick Streams",
          "author": "Binance",
          "url": "https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#klinecandlestick-streams-for-utc"
        },
        {
          "key": "R04",
          "title": "RFC 3339: Date and Time on the Internet: Timestamps",
          "author": "G. Klyne and C. Newman, Internet Engineering Task Force",
          "url": "https://datatracker.ietf.org/doc/html/rfc3339"
        },
        {
          "key": "R05",
          "title": "NYMEX and COMEX Definitions: Settlement Price",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/content/dam/cmegroup/rulebook/NYMEX/1/NYMEX-COMEX_Definitions.pdf"
        },
        {
          "key": "Evidence classification",
          "title": "Evidence classification",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/candle-foundations/candle-anatomy/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/candle-foundations/candle-anatomy/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F01-A02",
      "name": "Scale-Aware Body Classification",
      "headline": null,
      "slug": "scale-aware-body-classification",
      "path": "price-action-and-candlesticks/candle-foundations/scale-aware-body-classification",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F01",
        "family": "Candle Foundations",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/candle-foundations/scale-aware-body-classification",
        "entry": "classifyBody",
        "params": [
          "observation",
          "priorClosedBodies",
          "configInput"
        ],
        "exports": [
          "classifyBody",
          "classifyBodySeries"
        ],
        "archetype": "row-classify",
        "signature": "classifyBody(observation, priorClosedBodies, configInput)"
      },
      "api": {
        "summary": "Classifies a candle body as long, short or doji **relative to recent bodies** rather than against a fixed threshold. A 50-point body is enormous on one instrument and unremarkable on another, so an absolute rule cannot transfer.",
        "params": [
          {
            "name": "observation",
            "type": "Observation",
            "required": true,
            "description": "The candle's body and range, with its price basis and session.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "priorClosedBodies",
            "type": "number[]",
            "required": true,
            "description": "Recent closed bodies forming the comparison distribution. Closed only — including the forming candle would let the present redefine its own context.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "configInput",
            "type": "{ window: number; min_periods: number; tick_size: number; thresholds: object }",
            "required": true,
            "description": "`min_periods` refuses to classify until enough history exists, rather than judging against two candles. `tick_size` floors the comparison so sub-tick noise is not treated as structure.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ classification, percentile, window, min_periods, … }",
          "description": "The classification with the distribution statistics behind it, so the same body can be seen to be long in one regime and short in another."
        },
        "warmup": null,
        "errors": [
          {
            "when": "fewer prior bodies are supplied than min_periods",
            "behaviour": "reported as an unclassified state rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(window)",
          "space": "O(window)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D06-F01-A02.json",
        "call": "classifyBody({\"timestamp\":\"2026-01-05T10:25:00Z\",\"instrument_id\":\"SYNTH:ABC\",\"interval\":\"5m\",\"body\":4,\"range\":6,\"is_closed\":true,\"price_basis\":\"raw\",\"session\":\"continuous\"}, [1,2,2,3,12], {\"window\":5,\"min_periods\":5,\"tick_size\":0.01,\"thresholds\":{\"tiny_max\":0.25,\"small_max\":0.75,\"long_min\":1.5}})",
        "args": [
          {
            "value": {
              "timestamp": "2026-01-05T10:25:00Z",
              "instrument_id": "SYNTH:ABC",
              "interval": "5m",
              "body": 4,
              "range": 6,
              "is_closed": true,
              "price_basis": "raw",
              "session": "continuous"
            },
            "elided": null
          },
          {
            "value": [
              1,
              2,
              2,
              3,
              12
            ],
            "elided": null
          },
          {
            "value": {
              "window": 5,
              "min_periods": 5,
              "tick_size": 0.01,
              "thresholds": {
                "tiny_max": 0.25,
                "small_max": 0.75,
                "long_min": 1.5
              }
            },
            "elided": null
          }
        ],
        "output": {
          "status": "ready",
          "body_class": "long",
          "body_score": 2,
          "raw_scale": 2,
          "effective_scale": 2,
          "scale_floor_applied": false,
          "history_count": 5,
          "body_to_current_range": 0.6666666666666666,
          "is_provisional": false
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: status, body_class, body_score, raw_scale, effective_scale, scale_floor_applied, history_count, body_to_current_range, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "body-scale-classification.svg",
            "url": "https://thefintechbuilder.com/content/d06-f01-a02/static/body-scale-classification.svg"
          },
          {
            "file": "mean-vs-median.svg",
            "url": "https://thefintechbuilder.com/content/d06-f01-a02/static/mean-vs-median.svg"
          }
        ],
        "mermaid": [
          {
            "file": "causal-window-lifecycle.md",
            "caption": "Causal window lifecycle",
            "source": "sequenceDiagram\n    participant Feed as Ordered candle feed\n    participant A01 as A01 anatomy\n    participant A02 as A02 classifier\n    participant H as Closed-body history\n\n    Feed->>A01: Closed candle t\n    A01->>A02: body and range\n    A02->>H: Read prior closed bodies only\n    H-->>A02: causal reference window\n    A02-->>Feed: classification for t\n    A02->>H: Append body t after classification\n\n    Feed->>A01: Open candle t+1 update\n    A01->>A02: provisional body and range\n    A02->>H: Read unchanged closed history\n    H-->>A02: same causal reference window\n    A02-->>Feed: provisional classification\n    Note over A02,H: Open body is not appended"
          },
          {
            "file": "classification-flow.md",
            "caption": "Classification flow",
            "source": "flowchart TD\n    A[\"Receive validated A01 body and range\"] --> B[\"Select last W prior closed bodies\"]\n    B --> C{\"History count at least M?\"}\n    C -->|\"No\"| D[\"Return warmup: scale, score, class = null\"]\n    C -->|\"Yes\"| E[\"Compute median raw scale S\"]\n    E --> F[\"Apply optional tick floor: E = max(S, tick)\"]\n    F --> G{\"Effective scale E greater than 0?\"}\n    G -->|\"No\"| H[\"Return zero_scale: score, class = null\"]\n    G -->|\"Yes\"| I[\"Compute q = current body / E\"]\n    I --> J{\"Threshold interval\"}\n    J -->|\"q <= 0.25\"| K[\"tiny\"]\n    J -->|\"0.25 < q <= 0.75\"| L[\"small\"]\n    J -->|\"0.75 < q < 1.50\"| M[\"normal\"]\n    J -->|\"q >= 1.50\"| N[\"long\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R01",
          "title": "Chart Types: Candlestick, Line, Bar",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/courses/technical-analysis/chart-types-candlestick-line-bar"
        },
        {
          "key": "R02",
          "title": "TA-Lib default candle settings",
          "author": "TA-Lib project",
          "url": "https://github.com/TA-Lib/ta-lib/blob/main/src/ta_common/ta_global.c"
        },
        {
          "key": "R03",
          "title": "TA-Lib candlestick utility macros",
          "author": "TA-Lib project",
          "url": "https://github.com/TA-Lib/ta-lib/blob/main/src/ta_func/ta_utility.h"
        },
        {
          "key": "R04",
          "title": "TA-Lib C/C++ Core API",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/"
        },
        {
          "key": "R05",
          "title": "Measures of Location",
          "author": "National Institute of Standards and Technology",
          "url": "https://itl.nist.gov/div898/handbook/eda/section3/eda351.htm"
        },
        {
          "key": "R06",
          "title": "Candle Anatomy package",
          "author": "The Fintech Builder",
          "url": null
        },
        {
          "key": "Evidence classification",
          "title": "Evidence classification",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/candle-foundations/scale-aware-body-classification/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/candle-foundations/scale-aware-body-classification/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F01-A03",
      "name": "Shadow-to-Body Ratio",
      "headline": null,
      "slug": "shadow-to-body-ratio",
      "path": "price-action-and-candlesticks/candle-foundations/shadow-to-body-ratio",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F01",
        "family": "Candle Foundations",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/candle-foundations/shadow-to-body-ratio",
        "entry": "shadowToBodyRatio",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "shadowToBodyRatio(inputs)"
      },
      "api": {
        "summary": "Decomposes one OHLC candle and reports raw and tick-stabilized shadow-to-body ratios without hiding the zero-body case.",
        "params": [
          {
            "name": "inputs",
            "type": "{ candle: { open: number; high: number; low: number; close: number }; tick_size: number }",
            "required": true,
            "description": "Record containing `candle` and positive `tick_size` fields as defined by the topic data contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, body, upper_shadow, lower_shadow, range, tick_size, effective_body, upper_to_body, lower_to_body, upper_to_effective_body, lower_to_effective_body, upper_to_range, lower_to_range, dominant_shadow, dominant_shadow_ratio }",
          "description": "One diagnostic record. `state` is `calculated` for a nonzero body and `zero-body` when raw body ratios are undefined; no positional series is returned."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the candle is invalid or tick_size is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "shadowToBodyRatio({\"candle\":{\"open\":100,\"high\":105,\"low\":97,\"close\":102},\"tick_size\":0.1})",
        "args": [
          {
            "value": {
              "candle": {
                "open": 100,
                "high": 105,
                "low": 97,
                "close": 102
              },
              "tick_size": 0.1
            },
            "elided": null
          }
        ],
        "output": {
          "state": "calculated",
          "body": 2,
          "upper_shadow": 3,
          "lower_shadow": 3,
          "range": 8,
          "tick_size": 0.1,
          "effective_body": 2,
          "upper_to_body": 1.5,
          "lower_to_body": 1.5,
          "upper_to_effective_body": 1.5,
          "lower_to_effective_body": 1.5,
          "upper_to_range": 0.375,
          "lower_to_range": 0.375,
          "dominant_shadow": "balanced"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 15
        },
        "outputShape": "object with 15 fields: state, body, upper_shadow, lower_shadow, range, tick_size, effective_body, upper_to_body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f01-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Chart Types: Candlestick, Line, Bar",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/courses/technical-analysis/chart-types-candlestick-line-bar"
        },
        {
          "key": "S2",
          "title": "Candlestick chart",
          "author": "Nasdaq",
          "url": "https://www.nasdaq.com/glossary/b/candlestick-chart"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/candle-foundations/shadow-to-body-ratio/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/candle-foundations/shadow-to-body-ratio/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F01-A04",
      "name": "Gap Classification",
      "headline": null,
      "slug": "gap-classification",
      "path": "price-action-and-candlesticks/candle-foundations/gap-classification",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F01",
        "family": "Candle Foundations",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/candle-foundations/gap-classification",
        "entry": "gapClassification",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "gapClassification(inputs)"
      },
      "api": {
        "summary": "Classifies full-range, body, or opening gaps in either direction using an explicit tick-scaled minimum distance.",
        "params": [
          {
            "name": "inputs",
            "type": "{ previous: { open: number; high: number; low: number; close: number }; current: { open: number; high: number; low: number; close: number }; tick_size: number; minimum_gap_ticks: number }",
            "required": true,
            "description": "Record containing `previous`, `current`, `tick_size`, and `minimum_gap_ticks` as defined by the topic data contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, gap_direction, gap_type, gap_distance, threshold_distance, open_gap_up, open_gap_down, body_gap_up, body_gap_down, full_range_gap_up, full_range_gap_down, signed_open_gap, previous_close, current_open }",
          "description": "One classification record with `state` equal to `gap` or `overlap`, plus all directional checks and measured distances."
        },
        "warmup": null,
        "errors": [
          {
            "when": "either candle is invalid, tick_size is not positive, or minimum_gap_ticks is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "gapClassification({\"previous\":{\"open\":100,\"high\":105,\"low\":99,\"close\":104},\"current\":{\"open\":106,\"high\":110,\"low\":106,\"close\":109},\"tick_size\":1,\"minimum_gap_ticks\":1})",
        "args": [
          {
            "value": {
              "previous": {
                "open": 100,
                "high": 105,
                "low": 99,
                "close": 104
              },
              "current": {
                "open": 106,
                "high": 110,
                "low": 106,
                "close": 109
              },
              "tick_size": 1,
              "minimum_gap_ticks": 1
            },
            "elided": null
          }
        ],
        "output": {
          "state": "gap",
          "gap_direction": "up",
          "gap_type": "full-range",
          "gap_distance": 1,
          "threshold_distance": 1,
          "open_gap_up": true,
          "open_gap_down": false,
          "body_gap_up": true,
          "body_gap_down": false,
          "full_range_gap_up": true,
          "full_range_gap_down": false,
          "signed_open_gap": 2,
          "previous_close": 104,
          "current_open": 106
        },
        "outputElided": null,
        "outputShape": "object with 14 fields: state, gap_direction, gap_type, gap_distance, threshold_distance, open_gap_up, open_gap_down, body_gap_up, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f01-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Chart Types: Candlestick, Line, Bar",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/courses/technical-analysis/chart-types-candlestick-line-bar"
        },
        {
          "key": "S2",
          "title": "Candlestick chart",
          "author": "Nasdaq",
          "url": "https://www.nasdaq.com/glossary/b/candlestick-chart"
        },
        {
          "key": "S3",
          "title": "TA-Lib Pattern Recognition Functions",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/candle-foundations/gap-classification/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/candle-foundations/gap-classification/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F01-A05",
      "name": "Trend-Context Filter",
      "headline": null,
      "slug": "trend-context-filter",
      "path": "price-action-and-candlesticks/candle-foundations/trend-context-filter",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F01",
        "family": "Candle Foundations",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/candle-foundations/trend-context-filter",
        "entry": "trendContextFilter",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "trendContextFilter(inputs)"
      },
      "api": {
        "summary": "Classifies prior closes as an uptrend, downtrend, or sideways context from normalized net movement and path efficiency.",
        "params": [
          {
            "name": "inputs",
            "type": "{ prior_closes: number[]; prior_ranges: number[]; lookback: number; minimum_efficiency: number; minimum_move_scale: number }",
            "required": true,
            "description": "Record containing aligned `prior_closes`, `prior_ranges`, `lookback`, `minimum_efficiency`, and `minimum_move_scale` fields.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, trend_context, history_count, net_move, path_move, efficiency, range_scale, normalized_move }",
          "description": "One readiness record. `state` is `warmup` until `lookback` observations exist, `zero-scale` when the range scale is zero, and `ready` otherwise; this is not a positional warmup series."
        },
        "warmup": {
          "count": "lookback prior observations",
          "value": "state: warmup",
          "note": "The function returns one readiness record until the configured lookback is available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "lookback is below 3, arrays are misaligned, or thresholds are outside their allowed ranges",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "trendContextFilter({\"prior_closes\":[100,99,98,97,96,95],\"prior_ranges\":[2,2,2,2,2,2],\"lookback\":8,\"minimum_efficiency\":0.6,\"minimum_move_scale\":2})",
        "args": [
          {
            "value": {
              "prior_closes": [
                100,
                99,
                98,
                97,
                96,
                95
              ],
              "prior_ranges": [
                2,
                2,
                2,
                2,
                2,
                2
              ],
              "lookback": 8,
              "minimum_efficiency": 0.6,
              "minimum_move_scale": 2
            },
            "elided": null
          }
        ],
        "output": {
          "state": "ready",
          "trend_context": "downtrend",
          "history_count": 8,
          "net_move": -7,
          "path_move": 7,
          "efficiency": 1,
          "range_scale": 2,
          "normalized_move": -3.5
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: state, trend_context, history_count, net_move, path_move, efficiency, range_scale, normalized_move"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f01-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "CMT Program Guide 2026",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/wp-content/uploads/2025/12/CMT-PROGRAM-GUIDE-2026-1.pdf"
        },
        {
          "key": "S2",
          "title": "Technical Insights — Candles in Market Context",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/technical_insights/technical-insights-november-2020/"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Chart Types: Candlestick, Line, Bar",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/courses/technical-analysis/chart-types-candlestick-line-bar"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/candle-foundations/trend-context-filter/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/candle-foundations/trend-context-filter/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F02-A01",
      "name": "Doji",
      "headline": null,
      "slug": "doji",
      "path": "price-action-and-candlesticks/single-candle-patterns/doji",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F02",
        "family": "Single-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/single-candle-patterns/doji",
        "entry": "doji",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "doji(inputs)"
      },
      "api": {
        "summary": "Evaluates one candle against the repository's explicit doji geometry and scale convention.",
        "params": [
          {
            "name": "inputs",
            "type": "{ current: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number }",
            "required": true,
            "description": "Record containing `current`, prior body/range history, `trend_context`, and `tick_size`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks }",
          "description": "One pattern record. `state` is `warmup` before five history observations, then `matched` or `not-matched`; this is not a positional series."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "OHLC, history, context, or tick-size input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "doji({\"current\":{\"open\":100,\"high\":103,\"low\":98,\"close\":100.5},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"sideways\",\"tick_size\":0.1})",
        "args": [
          {
            "value": {
              "current": {
                "open": 100,
                "high": 103,
                "low": 98,
                "close": 100.5
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "sideways",
              "tick_size": 0.1
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F02-A01",
          "pattern": "Doji",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "sideways",
          "required_context": null,
          "body": 0.5,
          "upper_shadow": 2.5,
          "lower_shadow": 2,
          "range": 5,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "CMT Program Guide 2026",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/wp-content/uploads/2025/12/CMT-PROGRAM-GUIDE-2026-1.pdf"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Doji recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdldoji"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/single-candle-patterns/doji/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/single-candle-patterns/doji/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F02-A02",
      "name": "Dragonfly Doji",
      "headline": null,
      "slug": "dragonfly-doji",
      "path": "price-action-and-candlesticks/single-candle-patterns/dragonfly-doji",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F02",
        "family": "Single-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/single-candle-patterns/dragonfly-doji",
        "entry": "dragonflyDoji",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "dragonflyDoji(inputs)"
      },
      "api": {
        "summary": "Evaluates one candle against the repository's explicit dragonfly-doji geometry and scale convention.",
        "params": [
          {
            "name": "inputs",
            "type": "{ current: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number }",
            "required": true,
            "description": "Record containing `current`, prior body/range history, `trend_context`, and `tick_size`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks }",
          "description": "One pattern record. `state` is `warmup` before five history observations, then `matched` or `not-matched`; this is not a positional series."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "OHLC, history, context, or tick-size input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "dragonflyDoji({\"current\":{\"open\":103,\"high\":103.4,\"low\":100,\"close\":103.2},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"sideways\",\"tick_size\":0.1})",
        "args": [
          {
            "value": {
              "current": {
                "open": 103,
                "high": 103.4,
                "low": 100,
                "close": 103.2
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "sideways",
              "tick_size": 0.1
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F02-A02",
          "pattern": "Dragonfly Doji",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "sideways",
          "required_context": null,
          "body": 0.20000000000000284,
          "upper_shadow": 0.20000000000000284,
          "lower_shadow": 3,
          "range": 3.4000000000000057,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "CMT Program Guide 2026",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/wp-content/uploads/2025/12/CMT-PROGRAM-GUIDE-2026-1.pdf"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Dragonfly Doji recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdldragonflydoji"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/single-candle-patterns/dragonfly-doji/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/single-candle-patterns/dragonfly-doji/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F02-A03",
      "name": "Gravestone Doji",
      "headline": null,
      "slug": "gravestone-doji",
      "path": "price-action-and-candlesticks/single-candle-patterns/gravestone-doji",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F02",
        "family": "Single-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/single-candle-patterns/gravestone-doji",
        "entry": "gravestoneDoji",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "gravestoneDoji(inputs)"
      },
      "api": {
        "summary": "Evaluates one candle against the repository's explicit gravestone-doji geometry and scale convention.",
        "params": [
          {
            "name": "inputs",
            "type": "{ current: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number }",
            "required": true,
            "description": "Record containing `current`, prior body/range history, `trend_context`, and `tick_size`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks }",
          "description": "One pattern record. `state` is `warmup` before five history observations, then `matched` or `not-matched`; this is not a positional series."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "OHLC, history, context, or tick-size input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "gravestoneDoji({\"current\":{\"open\":100,\"high\":103.2,\"low\":100,\"close\":100.2},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"sideways\",\"tick_size\":0.1})",
        "args": [
          {
            "value": {
              "current": {
                "open": 100,
                "high": 103.2,
                "low": 100,
                "close": 100.2
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "sideways",
              "tick_size": 0.1
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F02-A03",
          "pattern": "Gravestone Doji",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "sideways",
          "required_context": null,
          "body": 0.20000000000000284,
          "upper_shadow": 3,
          "lower_shadow": 0,
          "range": 3.200000000000003,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "CMT Program Guide 2026",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/wp-content/uploads/2025/12/CMT-PROGRAM-GUIDE-2026-1.pdf"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Gravestone Doji recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdlgravestonedoji"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/single-candle-patterns/gravestone-doji/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/single-candle-patterns/gravestone-doji/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F02-A04",
      "name": "Marubozu",
      "headline": null,
      "slug": "marubozu",
      "path": "price-action-and-candlesticks/single-candle-patterns/marubozu",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F02",
        "family": "Single-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/single-candle-patterns/marubozu",
        "entry": "marubozu",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "marubozu(inputs)"
      },
      "api": {
        "summary": "Evaluates one candle against the repository's explicit marubozu geometry and scale convention.",
        "params": [
          {
            "name": "inputs",
            "type": "{ current: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number }",
            "required": true,
            "description": "Record containing `current`, prior body/range history, `trend_context`, and `tick_size`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks }",
          "description": "One pattern record. `state` is `warmup` before five history observations, then `matched` or `not-matched`; this is not a positional series."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "OHLC, history, context, or tick-size input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "marubozu({\"current\":{\"open\":100,\"high\":102.6,\"low\":99.8,\"close\":102.4},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"sideways\",\"tick_size\":0.1})",
        "args": [
          {
            "value": {
              "current": {
                "open": 100,
                "high": 102.6,
                "low": 99.8,
                "close": 102.4
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "sideways",
              "tick_size": 0.1
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F02-A04",
          "pattern": "Marubozu",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "sideways",
          "required_context": null,
          "body": 2.4000000000000057,
          "upper_shadow": 0.19999999999998863,
          "lower_shadow": 0.20000000000000284,
          "range": 2.799999999999997,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "CMT Program Guide 2026",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/wp-content/uploads/2025/12/CMT-PROGRAM-GUIDE-2026-1.pdf"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Marubozu recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdlmarubozu"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/single-candle-patterns/marubozu/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/single-candle-patterns/marubozu/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F02-A05",
      "name": "Spinning Top",
      "headline": null,
      "slug": "spinning-top",
      "path": "price-action-and-candlesticks/single-candle-patterns/spinning-top",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F02",
        "family": "Single-Candle Patterns",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/single-candle-patterns/spinning-top",
        "entry": "spinningTop",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "spinningTop(inputs)"
      },
      "api": {
        "summary": "Evaluates one candle against the repository's explicit spinning-top geometry and scale convention.",
        "params": [
          {
            "name": "inputs",
            "type": "{ current: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number }",
            "required": true,
            "description": "Record containing `current`, prior body/range history, `trend_context`, and `tick_size`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks }",
          "description": "One pattern record. `state` is `warmup` before five history observations, then `matched` or `not-matched`; this is not a positional series."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "OHLC, history, context, or tick-size input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "spinningTop({\"current\":{\"open\":100,\"high\":102.4,\"low\":98.8,\"close\":101.2},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"sideways\",\"tick_size\":0.1})",
        "args": [
          {
            "value": {
              "current": {
                "open": 100,
                "high": 102.4,
                "low": 98.8,
                "close": 101.2
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "sideways",
              "tick_size": 0.1
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F02-A05",
          "pattern": "Spinning Top",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "sideways",
          "required_context": null,
          "body": 1.2000000000000028,
          "upper_shadow": 1.2000000000000028,
          "lower_shadow": 1.2000000000000028,
          "range": 3.6000000000000085,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "CMT Program Guide 2026",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/wp-content/uploads/2025/12/CMT-PROGRAM-GUIDE-2026-1.pdf"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Spinning Top recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdlspinningtop"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/single-candle-patterns/spinning-top/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/single-candle-patterns/spinning-top/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F02-A06",
      "name": "Hammer",
      "headline": null,
      "slug": "hammer",
      "path": "price-action-and-candlesticks/single-candle-patterns/hammer",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F02",
        "family": "Single-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/single-candle-patterns/hammer",
        "entry": "hammer",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "hammer(inputs)"
      },
      "api": {
        "summary": "Evaluates one candle against explicit hammer geometry, scale, and downtrend context conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ current: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number }",
            "required": true,
            "description": "Record containing `current`, prior body/range history, `trend_context`, and `tick_size`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks }",
          "description": "One pattern record. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; this is not a positional series."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "OHLC, history, context, or tick-size input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "hammer({\"current\":{\"open\":102,\"high\":103.2,\"low\":100,\"close\":103},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"downtrend\",\"tick_size\":0.1})",
        "args": [
          {
            "value": {
              "current": {
                "open": 102,
                "high": 103.2,
                "low": 100,
                "close": 103
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "downtrend",
              "tick_size": 0.1
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F02-A06",
          "pattern": "Hammer",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "downtrend",
          "required_context": "downtrend",
          "body": 1,
          "upper_shadow": 0.20000000000000284,
          "lower_shadow": 2,
          "range": 3.200000000000003,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a06/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "CMT Program Guide 2026",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/wp-content/uploads/2025/12/CMT-PROGRAM-GUIDE-2026-1.pdf"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Hammer recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdlhammer"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/single-candle-patterns/hammer/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/single-candle-patterns/hammer/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F02-A07",
      "name": "Hanging Man",
      "headline": null,
      "slug": "hanging-man",
      "path": "price-action-and-candlesticks/single-candle-patterns/hanging-man",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F02",
        "family": "Single-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/single-candle-patterns/hanging-man",
        "entry": "hangingMan",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "hangingMan(inputs)"
      },
      "api": {
        "summary": "Evaluates one candle against explicit hanging-man geometry, scale, and uptrend context conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ current: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number }",
            "required": true,
            "description": "Record containing `current`, prior body/range history, `trend_context`, and `tick_size`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks }",
          "description": "One pattern record. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; this is not a positional series."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "OHLC, history, context, or tick-size input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "hangingMan({\"current\":{\"open\":102,\"high\":103.2,\"low\":100,\"close\":103},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"uptrend\",\"tick_size\":0.1})",
        "args": [
          {
            "value": {
              "current": {
                "open": 102,
                "high": 103.2,
                "low": 100,
                "close": 103
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "uptrend",
              "tick_size": 0.1
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F02-A07",
          "pattern": "Hanging Man",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "uptrend",
          "required_context": "uptrend",
          "body": 1,
          "upper_shadow": 0.20000000000000284,
          "lower_shadow": 2,
          "range": 3.200000000000003,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a07/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "CMT Program Guide 2026",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/wp-content/uploads/2025/12/CMT-PROGRAM-GUIDE-2026-1.pdf"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Hanging Man recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdlhangingman"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/single-candle-patterns/hanging-man/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/single-candle-patterns/hanging-man/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F02-A08",
      "name": "Inverted Hammer",
      "headline": null,
      "slug": "inverted-hammer",
      "path": "price-action-and-candlesticks/single-candle-patterns/inverted-hammer",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F02",
        "family": "Single-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/single-candle-patterns/inverted-hammer",
        "entry": "invertedHammer",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "invertedHammer(inputs)"
      },
      "api": {
        "summary": "Evaluates one candle against explicit inverted-hammer geometry, scale, and downtrend context conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ current: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number }",
            "required": true,
            "description": "Record containing `current`, prior body/range history, `trend_context`, and `tick_size`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks }",
          "description": "One pattern record. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; this is not a positional series."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "OHLC, history, context, or tick-size input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "invertedHammer({\"current\":{\"open\":100,\"high\":103,\"low\":99.8,\"close\":101},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"downtrend\",\"tick_size\":0.1})",
        "args": [
          {
            "value": {
              "current": {
                "open": 100,
                "high": 103,
                "low": 99.8,
                "close": 101
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "downtrend",
              "tick_size": 0.1
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F02-A08",
          "pattern": "Inverted Hammer",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "downtrend",
          "required_context": "downtrend",
          "body": 1,
          "upper_shadow": 2,
          "lower_shadow": 0.20000000000000284,
          "range": 3.200000000000003,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a08/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "CMT Program Guide 2026",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/wp-content/uploads/2025/12/CMT-PROGRAM-GUIDE-2026-1.pdf"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Inverted Hammer recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdlinvertedhammer"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/single-candle-patterns/inverted-hammer/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/single-candle-patterns/inverted-hammer/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F02-A09",
      "name": "Shooting Star",
      "headline": null,
      "slug": "shooting-star",
      "path": "price-action-and-candlesticks/single-candle-patterns/shooting-star",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F02",
        "family": "Single-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/single-candle-patterns/shooting-star",
        "entry": "shootingStar",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "shootingStar(inputs)"
      },
      "api": {
        "summary": "Evaluates one candle against explicit shooting-star geometry, scale, and uptrend context conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ current: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number }",
            "required": true,
            "description": "Record containing `current`, prior body/range history, `trend_context`, and `tick_size`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks }",
          "description": "One pattern record. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; this is not a positional series."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "OHLC, history, context, or tick-size input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "shootingStar({\"current\":{\"open\":100,\"high\":103,\"low\":99.8,\"close\":101},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"uptrend\",\"tick_size\":0.1})",
        "args": [
          {
            "value": {
              "current": {
                "open": 100,
                "high": 103,
                "low": 99.8,
                "close": 101
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "uptrend",
              "tick_size": 0.1
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F02-A09",
          "pattern": "Shooting Star",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "uptrend",
          "required_context": "uptrend",
          "body": 1,
          "upper_shadow": 2,
          "lower_shadow": 0.20000000000000284,
          "range": 3.200000000000003,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f02-a09/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "CMT Program Guide 2026",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/wp-content/uploads/2025/12/CMT-PROGRAM-GUIDE-2026-1.pdf"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Shooting Star recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdlshootingstar"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/single-candle-patterns/shooting-star/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/single-candle-patterns/shooting-star/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F03-A01",
      "name": "Bullish Engulfing",
      "headline": null,
      "slug": "bullish-engulfing",
      "path": "price-action-and-candlesticks/two-candle-patterns/bullish-engulfing",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F03",
        "family": "Two-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/two-candle-patterns/bullish-engulfing",
        "entry": "bullishEngulfing",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "bullishEngulfing(inputs)"
      },
      "api": {
        "summary": "Evaluates two candles against explicit bullish-engulfing geometry, scale, and downtrend context conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ first: { open: number; high: number; low: number; close: number }; second: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number; price_tolerance_ticks: number }",
            "required": true,
            "description": "Record containing `first`, `second`, prior body/range history, context, tick size, and price tolerance.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks, first_direction, second_direction, first_body, second_body, first_body_low?, first_body_high?, second_body_low?, second_body_high?, first_high?, second_high?, first_low?, second_low?, midpoint?, price_tolerance }",
          "description": "One pattern record with causal geometry diagnostics. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; detailed price fields are absent during warmup."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "candle, history, context, tick-size, or tolerance input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "bullishEngulfing({\"first\":{\"open\":105,\"high\":105.5,\"low\":101.5,\"close\":102},\"second\":{\"open\":101.5,\"high\":106,\"low\":101,\"close\":105.5},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"downtrend\",\"tick_size\":0.1,\"price_tolerance_ticks\":2})",
        "args": [
          {
            "value": {
              "first": {
                "open": 105,
                "high": 105.5,
                "low": 101.5,
                "close": 102
              },
              "second": {
                "open": 101.5,
                "high": 106,
                "low": 101,
                "close": 105.5
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "downtrend",
              "tick_size": 0.1,
              "price_tolerance_ticks": 2
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F03-A01",
          "pattern": "Bullish Engulfing",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "downtrend",
          "required_context": "downtrend",
          "body": 4,
          "upper_shadow": 0.5,
          "lower_shadow": 0.5,
          "range": 5,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 31
        },
        "outputShape": "object with 31 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "Technical Insights — Candles in Market Context",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/technical_insights/technical-insights-november-2020/"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Bullish Engulfing recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdlengulfing"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/two-candle-patterns/bullish-engulfing/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/two-candle-patterns/bullish-engulfing/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F03-A02",
      "name": "Bearish Engulfing",
      "headline": null,
      "slug": "bearish-engulfing",
      "path": "price-action-and-candlesticks/two-candle-patterns/bearish-engulfing",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F03",
        "family": "Two-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/two-candle-patterns/bearish-engulfing",
        "entry": "bearishEngulfing",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "bearishEngulfing(inputs)"
      },
      "api": {
        "summary": "Evaluates two candles against explicit bearish-engulfing geometry, scale, and uptrend context conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ first: { open: number; high: number; low: number; close: number }; second: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number; price_tolerance_ticks: number }",
            "required": true,
            "description": "Record containing `first`, `second`, prior body/range history, context, tick size, and price tolerance.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks, first_direction, second_direction, first_body, second_body, first_body_low?, first_body_high?, second_body_low?, second_body_high?, first_high?, second_high?, first_low?, second_low?, midpoint?, price_tolerance }",
          "description": "One pattern record with causal geometry diagnostics. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; detailed price fields are absent during warmup."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "candle, history, context, tick-size, or tolerance input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "bearishEngulfing({\"first\":{\"open\":102,\"high\":105.5,\"low\":101.5,\"close\":105},\"second\":{\"open\":105.5,\"high\":106,\"low\":101,\"close\":101.5},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"uptrend\",\"tick_size\":0.1,\"price_tolerance_ticks\":2})",
        "args": [
          {
            "value": {
              "first": {
                "open": 102,
                "high": 105.5,
                "low": 101.5,
                "close": 105
              },
              "second": {
                "open": 105.5,
                "high": 106,
                "low": 101,
                "close": 101.5
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "uptrend",
              "tick_size": 0.1,
              "price_tolerance_ticks": 2
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F03-A02",
          "pattern": "Bearish Engulfing",
          "matched": true,
          "state": "matched",
          "direction": "bearish",
          "trend_context": "uptrend",
          "required_context": "uptrend",
          "body": 4,
          "upper_shadow": 0.5,
          "lower_shadow": 0.5,
          "range": 5,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 31
        },
        "outputShape": "object with 31 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "Technical Insights — Candles in Market Context",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/technical_insights/technical-insights-november-2020/"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Bearish Engulfing recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdlengulfing"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/two-candle-patterns/bearish-engulfing/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/two-candle-patterns/bearish-engulfing/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F03-A03",
      "name": "Bullish Harami",
      "headline": null,
      "slug": "bullish-harami",
      "path": "price-action-and-candlesticks/two-candle-patterns/bullish-harami",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F03",
        "family": "Two-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/two-candle-patterns/bullish-harami",
        "entry": "bullishHarami",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "bullishHarami(inputs)"
      },
      "api": {
        "summary": "Evaluates two candles against explicit bullish-harami containment, scale, and downtrend context conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ first: { open: number; high: number; low: number; close: number }; second: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number; price_tolerance_ticks: number }",
            "required": true,
            "description": "Record containing `first`, `second`, prior body/range history, context, tick size, and price tolerance.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks, first_direction, second_direction, first_body, second_body, first_body_low?, first_body_high?, second_body_low?, second_body_high?, first_high?, second_high?, first_low?, second_low?, midpoint?, price_tolerance }",
          "description": "One pattern record with causal geometry diagnostics. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; detailed price fields are absent during warmup."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "candle, history, context, tick-size, or tolerance input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "bullishHarami({\"first\":{\"open\":105,\"high\":105.5,\"low\":101.5,\"close\":102},\"second\":{\"open\":103,\"high\":104.2,\"low\":102.8,\"close\":104},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"downtrend\",\"tick_size\":0.1,\"price_tolerance_ticks\":2})",
        "args": [
          {
            "value": {
              "first": {
                "open": 105,
                "high": 105.5,
                "low": 101.5,
                "close": 102
              },
              "second": {
                "open": 103,
                "high": 104.2,
                "low": 102.8,
                "close": 104
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "downtrend",
              "tick_size": 0.1,
              "price_tolerance_ticks": 2
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F03-A03",
          "pattern": "Bullish Harami",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "downtrend",
          "required_context": "downtrend",
          "body": 1,
          "upper_shadow": 0.20000000000000284,
          "lower_shadow": 0.20000000000000284,
          "range": 1.4000000000000057,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 31
        },
        "outputShape": "object with 31 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "Technical Insights — Candles in Market Context",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/technical_insights/technical-insights-november-2020/"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Bullish Harami recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdlharami"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/two-candle-patterns/bullish-harami/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/two-candle-patterns/bullish-harami/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F03-A04",
      "name": "Bearish Harami",
      "headline": null,
      "slug": "bearish-harami",
      "path": "price-action-and-candlesticks/two-candle-patterns/bearish-harami",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F03",
        "family": "Two-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/two-candle-patterns/bearish-harami",
        "entry": "bearishHarami",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "bearishHarami(inputs)"
      },
      "api": {
        "summary": "Evaluates two candles against explicit bearish-harami containment, scale, and uptrend context conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ first: { open: number; high: number; low: number; close: number }; second: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number; price_tolerance_ticks: number }",
            "required": true,
            "description": "Record containing `first`, `second`, prior body/range history, context, tick size, and price tolerance.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks, first_direction, second_direction, first_body, second_body, first_body_low?, first_body_high?, second_body_low?, second_body_high?, first_high?, second_high?, first_low?, second_low?, midpoint?, price_tolerance }",
          "description": "One pattern record with causal geometry diagnostics. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; detailed price fields are absent during warmup."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "candle, history, context, tick-size, or tolerance input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "bearishHarami({\"first\":{\"open\":102,\"high\":105.5,\"low\":101.5,\"close\":105},\"second\":{\"open\":104,\"high\":104.2,\"low\":102.8,\"close\":103},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"uptrend\",\"tick_size\":0.1,\"price_tolerance_ticks\":2})",
        "args": [
          {
            "value": {
              "first": {
                "open": 102,
                "high": 105.5,
                "low": 101.5,
                "close": 105
              },
              "second": {
                "open": 104,
                "high": 104.2,
                "low": 102.8,
                "close": 103
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "uptrend",
              "tick_size": 0.1,
              "price_tolerance_ticks": 2
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F03-A04",
          "pattern": "Bearish Harami",
          "matched": true,
          "state": "matched",
          "direction": "bearish",
          "trend_context": "uptrend",
          "required_context": "uptrend",
          "body": 1,
          "upper_shadow": 0.20000000000000284,
          "lower_shadow": 0.20000000000000284,
          "range": 1.4000000000000057,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 31
        },
        "outputShape": "object with 31 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "Technical Insights — Candles in Market Context",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/technical_insights/technical-insights-november-2020/"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Bearish Harami recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdlharami"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/two-candle-patterns/bearish-harami/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/two-candle-patterns/bearish-harami/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F03-A05",
      "name": "Piercing Line",
      "headline": null,
      "slug": "piercing-line",
      "path": "price-action-and-candlesticks/two-candle-patterns/piercing-line",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F03",
        "family": "Two-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/two-candle-patterns/piercing-line",
        "entry": "piercingLine",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "piercingLine(inputs)"
      },
      "api": {
        "summary": "Evaluates two candles against explicit piercing-line gap, midpoint, scale, and downtrend conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ first: { open: number; high: number; low: number; close: number }; second: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number; price_tolerance_ticks: number }",
            "required": true,
            "description": "Record containing `first`, `second`, prior body/range history, context, tick size, and price tolerance.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks, first_direction, second_direction, first_body, second_body, first_body_low?, first_body_high?, second_body_low?, second_body_high?, first_high?, second_high?, first_low?, second_low?, midpoint?, price_tolerance }",
          "description": "One pattern record with causal geometry diagnostics. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; detailed price fields are absent during warmup."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "candle, history, context, tick-size, or tolerance input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "piercingLine({\"first\":{\"open\":105,\"high\":105.5,\"low\":101.5,\"close\":102},\"second\":{\"open\":101.4,\"high\":104,\"low\":101.2,\"close\":103.6},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"downtrend\",\"tick_size\":0.1,\"price_tolerance_ticks\":2})",
        "args": [
          {
            "value": {
              "first": {
                "open": 105,
                "high": 105.5,
                "low": 101.5,
                "close": 102
              },
              "second": {
                "open": 101.4,
                "high": 104,
                "low": 101.2,
                "close": 103.6
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "downtrend",
              "tick_size": 0.1,
              "price_tolerance_ticks": 2
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F03-A05",
          "pattern": "Piercing Line",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "downtrend",
          "required_context": "downtrend",
          "body": 2.1999999999999886,
          "upper_shadow": 0.4000000000000057,
          "lower_shadow": 0.20000000000000284,
          "range": 2.799999999999997,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 31
        },
        "outputShape": "object with 31 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "Technical Insights — Candles in Market Context",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/technical_insights/technical-insights-november-2020/"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Piercing Line recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdlpiercing"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/two-candle-patterns/piercing-line/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/two-candle-patterns/piercing-line/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F03-A06",
      "name": "Dark Cloud Cover",
      "headline": null,
      "slug": "dark-cloud-cover",
      "path": "price-action-and-candlesticks/two-candle-patterns/dark-cloud-cover",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F03",
        "family": "Two-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/two-candle-patterns/dark-cloud-cover",
        "entry": "darkCloudCover",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "darkCloudCover(inputs)"
      },
      "api": {
        "summary": "Evaluates two candles against explicit dark-cloud gap, midpoint, scale, and uptrend conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ first: { open: number; high: number; low: number; close: number }; second: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number; price_tolerance_ticks: number }",
            "required": true,
            "description": "Record containing `first`, `second`, prior body/range history, context, tick size, and price tolerance.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks, first_direction, second_direction, first_body, second_body, first_body_low?, first_body_high?, second_body_low?, second_body_high?, first_high?, second_high?, first_low?, second_low?, midpoint?, price_tolerance }",
          "description": "One pattern record with causal geometry diagnostics. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; detailed price fields are absent during warmup."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "candle, history, context, tick-size, or tolerance input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "darkCloudCover({\"first\":{\"open\":102,\"high\":105.5,\"low\":101.5,\"close\":105},\"second\":{\"open\":105.6,\"high\":105.8,\"low\":103,\"close\":103.4},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"uptrend\",\"tick_size\":0.1,\"price_tolerance_ticks\":2})",
        "args": [
          {
            "value": {
              "first": {
                "open": 102,
                "high": 105.5,
                "low": 101.5,
                "close": 105
              },
              "second": {
                "open": 105.6,
                "high": 105.8,
                "low": 103,
                "close": 103.4
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "uptrend",
              "tick_size": 0.1,
              "price_tolerance_ticks": 2
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F03-A06",
          "pattern": "Dark Cloud Cover",
          "matched": true,
          "state": "matched",
          "direction": "bearish",
          "trend_context": "uptrend",
          "required_context": "uptrend",
          "body": 2.1999999999999886,
          "upper_shadow": 0.20000000000000284,
          "lower_shadow": 0.4000000000000057,
          "range": 2.799999999999997,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 31
        },
        "outputShape": "object with 31 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a06/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "Technical Insights — Candles in Market Context",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/technical_insights/technical-insights-november-2020/"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Dark Cloud Cover recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdldarkcloudcover"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/two-candle-patterns/dark-cloud-cover/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/two-candle-patterns/dark-cloud-cover/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F03-A07",
      "name": "Tweezer Top",
      "headline": null,
      "slug": "tweezer-top",
      "path": "price-action-and-candlesticks/two-candle-patterns/tweezer-top",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F03",
        "family": "Two-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/two-candle-patterns/tweezer-top",
        "entry": "tweezerTop",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "tweezerTop(inputs)"
      },
      "api": {
        "summary": "Evaluates two candles against explicit tweezer-top tolerance, rejection, scale, and uptrend conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ first: { open: number; high: number; low: number; close: number }; second: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number; price_tolerance_ticks: number }",
            "required": true,
            "description": "Record containing `first`, `second`, prior body/range history, context, tick size, and price tolerance.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks, first_direction, second_direction, first_body, second_body, first_body_low?, first_body_high?, second_body_low?, second_body_high?, first_high?, second_high?, first_low?, second_low?, midpoint?, price_tolerance }",
          "description": "One pattern record with causal geometry diagnostics. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; detailed price fields are absent during warmup."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "candle, history, context, tick-size, or tolerance input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "tweezerTop({\"first\":{\"open\":100,\"high\":103,\"low\":99.8,\"close\":102},\"second\":{\"open\":102.1,\"high\":103.1,\"low\":100.3,\"close\":100.5},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"uptrend\",\"tick_size\":0.1,\"price_tolerance_ticks\":2})",
        "args": [
          {
            "value": {
              "first": {
                "open": 100,
                "high": 103,
                "low": 99.8,
                "close": 102
              },
              "second": {
                "open": 102.1,
                "high": 103.1,
                "low": 100.3,
                "close": 100.5
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "uptrend",
              "tick_size": 0.1,
              "price_tolerance_ticks": 2
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F03-A07",
          "pattern": "Tweezer Top",
          "matched": true,
          "state": "matched",
          "direction": "bearish",
          "trend_context": "uptrend",
          "required_context": "uptrend",
          "body": 1.5999999999999943,
          "upper_shadow": 1,
          "lower_shadow": 0.20000000000000284,
          "range": 2.799999999999997,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 31
        },
        "outputShape": "object with 31 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a07/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "Technical Insights — Candles in Market Context",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/technical_insights/technical-insights-november-2020/"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Tweezer Top recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/functions"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/two-candle-patterns/tweezer-top/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/two-candle-patterns/tweezer-top/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F03-A08",
      "name": "Tweezer Bottom",
      "headline": null,
      "slug": "tweezer-bottom",
      "path": "price-action-and-candlesticks/two-candle-patterns/tweezer-bottom",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F03",
        "family": "Two-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/two-candle-patterns/tweezer-bottom",
        "entry": "tweezerBottom",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "shadowToBodyRatio",
          "gapClassification",
          "trendContextFilter",
          "doji",
          "dragonflyDoji",
          "gravestoneDoji",
          "marubozu",
          "spinningTop",
          "hammer",
          "hangingMan",
          "invertedHammer",
          "shootingStar",
          "bullishEngulfing",
          "bearishEngulfing",
          "bullishHarami",
          "bearishHarami",
          "piercingLine",
          "darkCloudCover",
          "tweezerTop",
          "tweezerBottom"
        ],
        "archetype": "record-transform",
        "signature": "tweezerBottom(inputs)"
      },
      "api": {
        "summary": "Evaluates two candles against explicit tweezer-bottom tolerance, rejection, scale, and downtrend conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ first: { open: number; high: number; low: number; close: number }; second: { open: number; high: number; low: number; close: number }; prior_bodies: number[]; prior_ranges: number[]; trend_context: string; tick_size: number; price_tolerance_ticks: number }",
            "required": true,
            "description": "Record containing `first`, `second`, prior body/range history, context, tick size, and price tolerance.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, body, upper_shadow, lower_shadow, range, body_scale, range_scale, history_count, geometry_score, checks, failed_checks, first_direction, second_direction, first_body, second_body, first_body_low?, first_body_high?, second_body_low?, second_body_high?, first_high?, second_high?, first_low?, second_low?, midpoint?, price_tolerance }",
          "description": "One pattern record with causal geometry diagnostics. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; detailed price fields are absent during warmup."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "candle, history, context, tick-size, or tolerance input violates the data contract",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "tweezerBottom({\"first\":{\"open\":102,\"high\":102.2,\"low\":99,\"close\":100},\"second\":{\"open\":99.9,\"high\":101.7,\"low\":99.1,\"close\":101.5},\"prior_bodies\":[2,2.2,1.8,2.1,1.9,2],\"prior_ranges\":[5,5,5,5,5,5],\"trend_context\":\"downtrend\",\"tick_size\":0.1,\"price_tolerance_ticks\":2})",
        "args": [
          {
            "value": {
              "first": {
                "open": 102,
                "high": 102.2,
                "low": 99,
                "close": 100
              },
              "second": {
                "open": 99.9,
                "high": 101.7,
                "low": 99.1,
                "close": 101.5
              },
              "prior_bodies": [
                2,
                2.2,
                1.8,
                2.1,
                1.9,
                2
              ],
              "prior_ranges": [
                5,
                5,
                5,
                5,
                5,
                5
              ],
              "trend_context": "downtrend",
              "tick_size": 0.1,
              "price_tolerance_ticks": 2
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F03-A08",
          "pattern": "Tweezer Bottom",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "downtrend",
          "required_context": "downtrend",
          "body": 1.5999999999999943,
          "upper_shadow": 0.20000000000000284,
          "lower_shadow": 0.8000000000000114,
          "range": 2.6000000000000085,
          "body_scale": 2,
          "range_scale": 5,
          "history_count": 10
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 31
        },
        "outputShape": "object with 31 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, body, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f03-a08/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S2",
          "title": "Technical Insights — Candles in Market Context",
          "author": "CMT Association",
          "url": "https://cmtassociation.org/technical_insights/technical-insights-november-2020/"
        },
        {
          "key": "S3",
          "title": "Candlestick Settings",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/candle-settings/"
        },
        {
          "key": "S4",
          "title": "Tweezer Bottom recognizer",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/functions"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/two-candle-patterns/tweezer-bottom/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/two-candle-patterns/tweezer-bottom/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F04-A01",
      "name": "Morning Star",
      "headline": null,
      "slug": "morning-star",
      "path": "price-action-and-candlesticks/multi-candle-patterns/morning-star",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F04",
        "family": "Multi-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/multi-candle-patterns/morning-star",
        "entry": "morningStar",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "morningStar",
          "eveningStar",
          "threeWhiteSoldiers",
          "threeBlackCrows",
          "threeInsideUpDown",
          "threeOutsideUpDown",
          "abandonedBaby"
        ],
        "archetype": "record-transform",
        "signature": "morningStar(inputs)"
      },
      "api": {
        "summary": "Evaluates exactly three candles against explicit morning-star gap, penetration, scale, and downtrend conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ candles: { open: number; high: number; low: number; close: number }[]; trend_context: string; prior_bodies: number[]; prior_ranges: number[]; tick_size: number; penetration_fraction: number }",
            "required": true,
            "description": "Record containing three `candles`, trend context, prior body/range history, tick size, and optional penetration fraction.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, history_count, body_scale, range_scale, geometry_score, checks, failed_checks, reason, thresholds, candles }",
          "description": "One three-candle pattern record. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; readiness is record state, not positional output."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "the record does not contain exactly three valid candles or scale/context inputs are invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "morningStar({\"candles\":[{\"open\":105,\"high\":105.5,\"low\":100.5,\"close\":101},{\"open\":100.4,\"high\":101.2,\"low\":99.8,\"close\":100.8},{\"open\":100.7,\"high\":104.2,\"low\":100.6,\"close\":103.5}],\"trend_context\":\"downtrend\",\"prior_bodies\":[2,2.1,1.9,2.2,2,2.1],\"prior_ranges\":[3,3.2,2.9,3.1,3,3.3],\"tick_size\":0.1,\"penetration_fraction\":0.5})",
        "args": [
          {
            "value": {
              "candles": [
                {
                  "open": 105,
                  "high": 105.5,
                  "low": 100.5,
                  "close": 101
                },
                {
                  "open": 100.4,
                  "high": 101.2,
                  "low": 99.8,
                  "close": 100.8
                },
                {
                  "open": 100.7,
                  "high": 104.2,
                  "low": 100.6,
                  "close": 103.5
                }
              ],
              "trend_context": "downtrend",
              "prior_bodies": [
                2,
                2.1,
                1.9,
                2.2,
                2,
                2.1
              ],
              "prior_ranges": [
                3,
                3.2,
                2.9,
                3.1,
                3,
                3.3
              ],
              "tick_size": 0.1,
              "penetration_fraction": 0.5
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F04-A01",
          "pattern": "Morning Star",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "downtrend",
          "required_context": "downtrend",
          "history_count": 10,
          "body_scale": 2,
          "range_scale": 3,
          "geometry_score": 1,
          "checks": {
            "first_bearish": true,
            "first_long": true,
            "second_short": true,
            "body_gap_down": true,
            "third_bullish": true,
            "third_penetrates": true
          },
          "failed_checks": [],
          "reason": "all declared checks pass"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 16
        },
        "outputShape": "object with 16 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, history_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "CDLMORNINGSTAR function documentation",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdlmorningstar"
        },
        {
          "key": "S2",
          "title": "TA-Lib Pattern Recognition Functions",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison; Prentice Hall Press",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S4",
          "title": "Measures of Location: Mean and Median",
          "author": "NIST/SEMATECH",
          "url": "https://itl.nist.gov/div898/handbook/eda/section3/eda351.htm"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/multi-candle-patterns/morning-star/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/multi-candle-patterns/morning-star/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F04-A02",
      "name": "Evening Star",
      "headline": null,
      "slug": "evening-star",
      "path": "price-action-and-candlesticks/multi-candle-patterns/evening-star",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F04",
        "family": "Multi-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/multi-candle-patterns/evening-star",
        "entry": "eveningStar",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "morningStar",
          "eveningStar",
          "threeWhiteSoldiers",
          "threeBlackCrows",
          "threeInsideUpDown",
          "threeOutsideUpDown",
          "abandonedBaby"
        ],
        "archetype": "record-transform",
        "signature": "eveningStar(inputs)"
      },
      "api": {
        "summary": "Evaluates exactly three candles against explicit evening-star gap, penetration, scale, and uptrend conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ candles: { open: number; high: number; low: number; close: number }[]; trend_context: string; prior_bodies: number[]; prior_ranges: number[]; tick_size: number; penetration_fraction: number }",
            "required": true,
            "description": "Record containing three `candles`, trend context, prior body/range history, tick size, and optional penetration fraction.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, history_count, body_scale, range_scale, geometry_score, checks, failed_checks, reason, thresholds, candles }",
          "description": "One three-candle pattern record. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; readiness is record state, not positional output."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "the record does not contain exactly three valid candles or scale/context inputs are invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "eveningStar({\"candles\":[{\"open\":100,\"high\":104.5,\"low\":99.5,\"close\":104},{\"open\":104.6,\"high\":105.1,\"low\":103.9,\"close\":104.2},{\"open\":104.3,\"high\":104.4,\"low\":101.1,\"close\":101.5}],\"trend_context\":\"uptrend\",\"prior_bodies\":[2,2.1,1.9,2.2,2,2.1],\"prior_ranges\":[3,3.2,2.9,3.1,3,3.3],\"tick_size\":0.1,\"penetration_fraction\":0.5})",
        "args": [
          {
            "value": {
              "candles": [
                {
                  "open": 100,
                  "high": 104.5,
                  "low": 99.5,
                  "close": 104
                },
                {
                  "open": 104.6,
                  "high": 105.1,
                  "low": 103.9,
                  "close": 104.2
                },
                {
                  "open": 104.3,
                  "high": 104.4,
                  "low": 101.1,
                  "close": 101.5
                }
              ],
              "trend_context": "uptrend",
              "prior_bodies": [
                2,
                2.1,
                1.9,
                2.2,
                2,
                2.1
              ],
              "prior_ranges": [
                3,
                3.2,
                2.9,
                3.1,
                3,
                3.3
              ],
              "tick_size": 0.1,
              "penetration_fraction": 0.5
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F04-A02",
          "pattern": "Evening Star",
          "matched": true,
          "state": "matched",
          "direction": "bearish",
          "trend_context": "uptrend",
          "required_context": "uptrend",
          "history_count": 10,
          "body_scale": 2,
          "range_scale": 3,
          "geometry_score": 1,
          "checks": {
            "first_bullish": true,
            "first_long": true,
            "second_short": true,
            "body_gap_up": true,
            "third_bearish": true,
            "third_penetrates": true
          },
          "failed_checks": [],
          "reason": "all declared checks pass"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 16
        },
        "outputShape": "object with 16 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, history_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "CDLEVENINGSTAR function documentation",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdleveningstar"
        },
        {
          "key": "S2",
          "title": "TA-Lib Pattern Recognition Functions",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison; Prentice Hall Press",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S4",
          "title": "Measures of Location: Mean and Median",
          "author": "NIST/SEMATECH",
          "url": "https://itl.nist.gov/div898/handbook/eda/section3/eda351.htm"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/multi-candle-patterns/evening-star/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/multi-candle-patterns/evening-star/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F04-A03",
      "name": "Three White Soldiers",
      "headline": null,
      "slug": "three-white-soldiers",
      "path": "price-action-and-candlesticks/multi-candle-patterns/three-white-soldiers",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F04",
        "family": "Multi-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/multi-candle-patterns/three-white-soldiers",
        "entry": "threeWhiteSoldiers",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "morningStar",
          "eveningStar",
          "threeWhiteSoldiers",
          "threeBlackCrows",
          "threeInsideUpDown",
          "threeOutsideUpDown",
          "abandonedBaby"
        ],
        "archetype": "record-transform",
        "signature": "threeWhiteSoldiers(inputs)"
      },
      "api": {
        "summary": "Evaluates exactly three candles against explicit white-soldiers body, close, shadow, scale, and downtrend conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ candles: { open: number; high: number; low: number; close: number }[]; trend_context: string; prior_bodies: number[]; prior_ranges: number[]; tick_size: number; penetration_fraction: number }",
            "required": true,
            "description": "Record containing three `candles`, trend context, prior body/range history, tick size, and penetration fraction.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, history_count, body_scale, range_scale, geometry_score, checks, failed_checks, reason, thresholds, candles }",
          "description": "One three-candle pattern record. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; readiness is record state, not positional output."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "the record does not contain exactly three valid candles or scale/context inputs are invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "threeWhiteSoldiers({\"candles\":[{\"open\":100,\"high\":102.2,\"low\":99.8,\"close\":102},{\"open\":101.5,\"high\":103.7,\"low\":101.3,\"close\":103.5},{\"open\":103,\"high\":105.2,\"low\":102.8,\"close\":105}],\"trend_context\":\"downtrend\",\"prior_bodies\":[2,2.1,1.9,2.2,2,2.1],\"prior_ranges\":[3,3.2,2.9,3.1,3,3.3],\"tick_size\":0.1,\"penetration_fraction\":0.5})",
        "args": [
          {
            "value": {
              "candles": [
                {
                  "open": 100,
                  "high": 102.2,
                  "low": 99.8,
                  "close": 102
                },
                {
                  "open": 101.5,
                  "high": 103.7,
                  "low": 101.3,
                  "close": 103.5
                },
                {
                  "open": 103,
                  "high": 105.2,
                  "low": 102.8,
                  "close": 105
                }
              ],
              "trend_context": "downtrend",
              "prior_bodies": [
                2,
                2.1,
                1.9,
                2.2,
                2,
                2.1
              ],
              "prior_ranges": [
                3,
                3.2,
                2.9,
                3.1,
                3,
                3.3
              ],
              "tick_size": 0.1,
              "penetration_fraction": 0.5
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F04-A03",
          "pattern": "Three White Soldiers",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "downtrend",
          "required_context": "downtrend",
          "history_count": 10,
          "body_scale": 2,
          "range_scale": 3,
          "geometry_score": 1,
          "checks": {
            "three_bullish": true,
            "material_bodies": true,
            "rising_closes": true,
            "second_opens_in_prior_body": true,
            "third_opens_in_prior_body": true,
            "short_upper_shadows": true
          },
          "failed_checks": [],
          "reason": "all declared checks pass"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 16
        },
        "outputShape": "object with 16 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, history_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "CDL3WHITESOLDIERS function documentation",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdl3whitesoldiers"
        },
        {
          "key": "S2",
          "title": "TA-Lib Pattern Recognition Functions",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison; Prentice Hall Press",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S4",
          "title": "Measures of Location: Mean and Median",
          "author": "NIST/SEMATECH",
          "url": "https://itl.nist.gov/div898/handbook/eda/section3/eda351.htm"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/multi-candle-patterns/three-white-soldiers/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/multi-candle-patterns/three-white-soldiers/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F04-A04",
      "name": "Three Black Crows",
      "headline": null,
      "slug": "three-black-crows",
      "path": "price-action-and-candlesticks/multi-candle-patterns/three-black-crows",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F04",
        "family": "Multi-Candle Patterns",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/multi-candle-patterns/three-black-crows",
        "entry": "threeBlackCrows",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "morningStar",
          "eveningStar",
          "threeWhiteSoldiers",
          "threeBlackCrows",
          "threeInsideUpDown",
          "threeOutsideUpDown",
          "abandonedBaby"
        ],
        "archetype": "record-transform",
        "signature": "threeBlackCrows(inputs)"
      },
      "api": {
        "summary": "Evaluates exactly three candles against explicit black-crows body, close, shadow, scale, and uptrend conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ candles: { open: number; high: number; low: number; close: number }[]; trend_context: string; prior_bodies: number[]; prior_ranges: number[]; tick_size: number; penetration_fraction: number }",
            "required": true,
            "description": "Record containing three `candles`, trend context, prior body/range history, tick size, and penetration fraction.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, history_count, body_scale, range_scale, geometry_score, checks, failed_checks, reason, thresholds, candles }",
          "description": "One three-candle pattern record. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; readiness is record state, not positional output."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "the record does not contain exactly three valid candles or scale/context inputs are invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "threeBlackCrows({\"candles\":[{\"open\":105,\"high\":105.2,\"low\":102.8,\"close\":103},{\"open\":103.5,\"high\":103.7,\"low\":101.3,\"close\":101.5},{\"open\":102,\"high\":102.2,\"low\":99.8,\"close\":100}],\"trend_context\":\"uptrend\",\"prior_bodies\":[2,2.1,1.9,2.2,2,2.1],\"prior_ranges\":[3,3.2,2.9,3.1,3,3.3],\"tick_size\":0.1,\"penetration_fraction\":0.5})",
        "args": [
          {
            "value": {
              "candles": [
                {
                  "open": 105,
                  "high": 105.2,
                  "low": 102.8,
                  "close": 103
                },
                {
                  "open": 103.5,
                  "high": 103.7,
                  "low": 101.3,
                  "close": 101.5
                },
                {
                  "open": 102,
                  "high": 102.2,
                  "low": 99.8,
                  "close": 100
                }
              ],
              "trend_context": "uptrend",
              "prior_bodies": [
                2,
                2.1,
                1.9,
                2.2,
                2,
                2.1
              ],
              "prior_ranges": [
                3,
                3.2,
                2.9,
                3.1,
                3,
                3.3
              ],
              "tick_size": 0.1,
              "penetration_fraction": 0.5
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F04-A04",
          "pattern": "Three Black Crows",
          "matched": true,
          "state": "matched",
          "direction": "bearish",
          "trend_context": "uptrend",
          "required_context": "uptrend",
          "history_count": 10,
          "body_scale": 2,
          "range_scale": 3,
          "geometry_score": 1,
          "checks": {
            "three_bearish": true,
            "material_bodies": true,
            "falling_closes": true,
            "second_opens_in_prior_body": true,
            "third_opens_in_prior_body": true,
            "short_lower_shadows": true
          },
          "failed_checks": [],
          "reason": "all declared checks pass"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 16
        },
        "outputShape": "object with 16 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, history_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "CDL3BLACKCROWS function documentation",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdl3blackcrows"
        },
        {
          "key": "S2",
          "title": "TA-Lib Pattern Recognition Functions",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison; Prentice Hall Press",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S4",
          "title": "Measures of Location: Mean and Median",
          "author": "NIST/SEMATECH",
          "url": "https://itl.nist.gov/div898/handbook/eda/section3/eda351.htm"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/multi-candle-patterns/three-black-crows/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/multi-candle-patterns/three-black-crows/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F04-A05",
      "name": "Three Inside Up/Down",
      "headline": null,
      "slug": "three-inside-up-down",
      "path": "price-action-and-candlesticks/multi-candle-patterns/three-inside-up-down",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F04",
        "family": "Multi-Candle Patterns",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/multi-candle-patterns/three-inside-up-down",
        "entry": "threeInsideUpDown",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "morningStar",
          "eveningStar",
          "threeWhiteSoldiers",
          "threeBlackCrows",
          "threeInsideUpDown",
          "threeOutsideUpDown",
          "abandonedBaby"
        ],
        "archetype": "record-transform",
        "signature": "threeInsideUpDown(inputs)"
      },
      "api": {
        "summary": "Evaluates exactly three candles against explicit inside-pair containment, confirmation, scale, and trend-context conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ candles: { open: number; high: number; low: number; close: number }[]; trend_context: string; prior_bodies: number[]; prior_ranges: number[]; tick_size: number; penetration_fraction: number }",
            "required": true,
            "description": "Record containing three `candles`, trend context, prior body/range history, tick size, and penetration fraction.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, history_count, body_scale, range_scale, geometry_score, checks, failed_checks, reason, thresholds, candles }",
          "description": "One three-candle pattern record. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; readiness is record state, not positional output."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "the record does not contain exactly three valid candles or scale/context inputs are invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "threeInsideUpDown({\"candles\":[{\"open\":105,\"high\":105.4,\"low\":100.6,\"close\":101},{\"open\":102,\"high\":103.2,\"low\":101.8,\"close\":103},{\"open\":102.8,\"high\":105.5,\"low\":102.6,\"close\":105.3}],\"trend_context\":\"downtrend\",\"prior_bodies\":[2,2.1,1.9,2.2,2,2.1],\"prior_ranges\":[3,3.2,2.9,3.1,3,3.3],\"tick_size\":0.1,\"penetration_fraction\":0.5})",
        "args": [
          {
            "value": {
              "candles": [
                {
                  "open": 105,
                  "high": 105.4,
                  "low": 100.6,
                  "close": 101
                },
                {
                  "open": 102,
                  "high": 103.2,
                  "low": 101.8,
                  "close": 103
                },
                {
                  "open": 102.8,
                  "high": 105.5,
                  "low": 102.6,
                  "close": 105.3
                }
              ],
              "trend_context": "downtrend",
              "prior_bodies": [
                2,
                2.1,
                1.9,
                2.2,
                2,
                2.1
              ],
              "prior_ranges": [
                3,
                3.2,
                2.9,
                3.1,
                3,
                3.3
              ],
              "tick_size": 0.1,
              "penetration_fraction": 0.5
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F04-A05",
          "pattern": "Three Inside Up/Down",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "downtrend",
          "required_context": "downtrend",
          "history_count": 10,
          "body_scale": 2,
          "range_scale": 3,
          "geometry_score": 1,
          "checks": {
            "opposite_first_pair": true,
            "first_long": true,
            "second_short": true,
            "second_body_inside": true,
            "third_confirms_past_first_open": true
          },
          "failed_checks": [],
          "reason": "all declared checks pass"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 16
        },
        "outputShape": "object with 16 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, history_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "CDL3INSIDE function documentation",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdl3inside"
        },
        {
          "key": "S2",
          "title": "TA-Lib Pattern Recognition Functions",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison; Prentice Hall Press",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S4",
          "title": "Measures of Location: Mean and Median",
          "author": "NIST/SEMATECH",
          "url": "https://itl.nist.gov/div898/handbook/eda/section3/eda351.htm"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/multi-candle-patterns/three-inside-up-down/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/multi-candle-patterns/three-inside-up-down/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F04-A06",
      "name": "Three Outside Up/Down",
      "headline": null,
      "slug": "three-outside-up-down",
      "path": "price-action-and-candlesticks/multi-candle-patterns/three-outside-up-down",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F04",
        "family": "Multi-Candle Patterns",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/multi-candle-patterns/three-outside-up-down",
        "entry": "threeOutsideUpDown",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "morningStar",
          "eveningStar",
          "threeWhiteSoldiers",
          "threeBlackCrows",
          "threeInsideUpDown",
          "threeOutsideUpDown",
          "abandonedBaby"
        ],
        "archetype": "record-transform",
        "signature": "threeOutsideUpDown(inputs)"
      },
      "api": {
        "summary": "Evaluates exactly three candles against explicit outside-pair engulfing, confirmation, scale, and trend-context conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ candles: { open: number; high: number; low: number; close: number }[]; trend_context: string; prior_bodies: number[]; prior_ranges: number[]; tick_size: number; penetration_fraction: number }",
            "required": true,
            "description": "Record containing three `candles`, trend context, prior body/range history, tick size, and penetration fraction.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, history_count, body_scale, range_scale, geometry_score, checks, failed_checks, reason, thresholds, candles }",
          "description": "One three-candle pattern record. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; readiness is record state, not positional output."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "the record does not contain exactly three valid candles or scale/context inputs are invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "threeOutsideUpDown({\"candles\":[{\"open\":103,\"high\":103.3,\"low\":100.7,\"close\":101},{\"open\":100.5,\"high\":103.8,\"low\":100.3,\"close\":103.5},{\"open\":103,\"high\":104.7,\"low\":102.8,\"close\":104.5}],\"trend_context\":\"downtrend\",\"prior_bodies\":[2,2.1,1.9,2.2,2,2.1],\"prior_ranges\":[3,3.2,2.9,3.1,3,3.3],\"tick_size\":0.1,\"penetration_fraction\":0.5})",
        "args": [
          {
            "value": {
              "candles": [
                {
                  "open": 103,
                  "high": 103.3,
                  "low": 100.7,
                  "close": 101
                },
                {
                  "open": 100.5,
                  "high": 103.8,
                  "low": 100.3,
                  "close": 103.5
                },
                {
                  "open": 103,
                  "high": 104.7,
                  "low": 102.8,
                  "close": 104.5
                }
              ],
              "trend_context": "downtrend",
              "prior_bodies": [
                2,
                2.1,
                1.9,
                2.2,
                2,
                2.1
              ],
              "prior_ranges": [
                3,
                3.2,
                2.9,
                3.1,
                3,
                3.3
              ],
              "tick_size": 0.1,
              "penetration_fraction": 0.5
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F04-A06",
          "pattern": "Three Outside Up/Down",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "downtrend",
          "required_context": "downtrend",
          "history_count": 10,
          "body_scale": 2,
          "range_scale": 3,
          "geometry_score": 1,
          "checks": {
            "opposite_first_pair": true,
            "second_body_engulfs": true,
            "third_confirms_beyond_second_close": true
          },
          "failed_checks": [],
          "reason": "all declared checks pass"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 16
        },
        "outputShape": "object with 16 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, history_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a06/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "CDL3OUTSIDE function documentation",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdl3outside"
        },
        {
          "key": "S2",
          "title": "TA-Lib Pattern Recognition Functions",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison; Prentice Hall Press",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S4",
          "title": "Measures of Location: Mean and Median",
          "author": "NIST/SEMATECH",
          "url": "https://itl.nist.gov/div898/handbook/eda/section3/eda351.htm"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/multi-candle-patterns/three-outside-up-down/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/multi-candle-patterns/three-outside-up-down/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F04-A07",
      "name": "Abandoned Baby",
      "headline": null,
      "slug": "abandoned-baby",
      "path": "price-action-and-candlesticks/multi-candle-patterns/abandoned-baby",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F04",
        "family": "Multi-Candle Patterns",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/multi-candle-patterns/abandoned-baby",
        "entry": "abandonedBaby",
        "params": [
          "inputs"
        ],
        "exports": [
          "calculate",
          "morningStar",
          "eveningStar",
          "threeWhiteSoldiers",
          "threeBlackCrows",
          "threeInsideUpDown",
          "threeOutsideUpDown",
          "abandonedBaby"
        ],
        "archetype": "record-transform",
        "signature": "abandonedBaby(inputs)"
      },
      "api": {
        "summary": "Evaluates exactly three candles against explicit abandoned-baby isolation, doji, penetration, scale, and context conventions.",
        "params": [
          {
            "name": "inputs",
            "type": "{ candles: { open: number; high: number; low: number; close: number }[]; trend_context: string; prior_bodies: number[]; prior_ranges: number[]; tick_size: number; penetration_fraction: number }",
            "required": true,
            "description": "Record containing three `candles`, trend context, prior body/range history, tick size, and penetration fraction.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, pattern, matched, state, direction, trend_context, required_context, history_count, body_scale, range_scale, geometry_score, checks, failed_checks, reason, thresholds, candles }",
          "description": "One three-candle pattern record. `state` is `warmup`, `wrong-context`, `matched`, or `not-matched`; readiness is record state, not positional output."
        },
        "warmup": {
          "count": "5 prior observations",
          "value": "state: warmup",
          "note": "The detector returns one readiness record before five prior body/range observations are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "the record does not contain exactly three valid candles or scale/context inputs are invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "abandonedBaby({\"candles\":[{\"open\":105,\"high\":105.5,\"low\":100.5,\"close\":101},{\"open\":99.8,\"high\":100.3,\"low\":99.4,\"close\":99.85},{\"open\":100.7,\"high\":103.7,\"low\":100.5,\"close\":103.4}],\"trend_context\":\"downtrend\",\"prior_bodies\":[2,2.1,1.9,2.2,2,2.1],\"prior_ranges\":[3,3.2,2.9,3.1,3,3.3],\"tick_size\":0.1,\"penetration_fraction\":0.5})",
        "args": [
          {
            "value": {
              "candles": [
                {
                  "open": 105,
                  "high": 105.5,
                  "low": 100.5,
                  "close": 101
                },
                {
                  "open": 99.8,
                  "high": 100.3,
                  "low": 99.4,
                  "close": 99.85
                },
                {
                  "open": 100.7,
                  "high": 103.7,
                  "low": 100.5,
                  "close": 103.4
                }
              ],
              "trend_context": "downtrend",
              "prior_bodies": [
                2,
                2.1,
                1.9,
                2.2,
                2,
                2.1
              ],
              "prior_ranges": [
                3,
                3.2,
                2.9,
                3.1,
                3,
                3.3
              ],
              "tick_size": 0.1,
              "penetration_fraction": 0.5
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D06-F04-A07",
          "pattern": "Abandoned Baby",
          "matched": true,
          "state": "matched",
          "direction": "bullish",
          "trend_context": "downtrend",
          "required_context": "downtrend",
          "history_count": 10,
          "body_scale": 2,
          "range_scale": 3,
          "geometry_score": 1,
          "checks": {
            "opposite_outer_candles": true,
            "first_long": true,
            "middle_doji": true,
            "full_range_isolation": true,
            "third_penetrates": true
          },
          "failed_checks": [],
          "reason": "all declared checks pass"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 16
        },
        "outputShape": "object with 16 fields: topic_id, pattern, matched, state, direction, trend_context, required_context, history_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d06-f04-a07/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "CDLABANDONEDBABY function documentation",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/cdlabandonedbaby"
        },
        {
          "key": "S2",
          "title": "TA-Lib Pattern Recognition Functions",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S3",
          "title": "Japanese Candlestick Charting Techniques, Second Edition",
          "author": "Steve Nison; Prentice Hall Press",
          "url": "https://www.penguinrandomhouse.com/books/350650/japanese-candlestick-charting-techniques-by-steve-nison/"
        },
        {
          "key": "S4",
          "title": "Measures of Location: Mean and Median",
          "author": "NIST/SEMATECH",
          "url": "https://itl.nist.gov/div898/handbook/eda/section3/eda351.htm"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/multi-candle-patterns/abandoned-baby/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/multi-candle-patterns/abandoned-baby/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F05-A01",
      "name": "Unified Candlestick Pattern Registry",
      "headline": null,
      "slug": "unified-candlestick-pattern-registry",
      "path": "price-action-and-candlesticks/candlestick-scanning-and-context/unified-candlestick-pattern-registry",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F05",
        "family": "Candlestick Scanning and Context",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/candlestick-scanning-and-context/unified-candlestick-pattern-registry",
        "entry": "buildRegistry",
        "params": [
          "data"
        ],
        "exports": [
          "buildRegistry"
        ],
        "archetype": "record-transform",
        "signature": "buildRegistry(data)"
      },
      "api": {
        "summary": "construct a deterministic, versioned registry that rejects duplicate identities and ambiguous detector metadata.",
        "params": [
          {
            "name": "data",
            "type": "{ patterns: { pattern_id: string; name: string; direction: string; window: number; detector: string; version: string; enabled: boolean; priority: number }[] }",
            "required": true,
            "description": "Topic input record; the required fields are fixed by this topic data-contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, registry_id, pattern_count, enabled_count, max_window, patterns }",
          "description": "One `ready` registry record with stable catalog ordering, a versioned registry identity, aggregate counts, maximum detector window, and the validated pattern specifications."
        },
        "warmup": null,
        "errors": [],
        "complexity": {
          "time": "O(n log n) worst case; see README for topic-specific n",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D06-F05-A01.json",
        "call": "buildRegistry({\"patterns\":[{\"pattern_id\":\"D06-F03-A01\",\"name\":\"Bullish Engulfing\",\"direction\":\"bullish\",\"window\":2,\"detector\":\"bullish_engulfing\",\"version\":\"v1\",\"enabled\":true,\"priority\":2},{\"pattern_id\":\"D06-F02-A01\",\"name\":\"Doji\",\"direction\":\"neutral\",\"window\":1,\"detector\":\"doji\",\"version\":\"v1\",\"enabled\":false,\"priority\":1}]})",
        "args": [
          {
            "value": {
              "patterns": [
                {
                  "pattern_id": "D06-F03-A01",
                  "name": "Bullish Engulfing",
                  "direction": "bullish",
                  "window": 2,
                  "detector": "bullish_engulfing",
                  "version": "v1",
                  "enabled": true,
                  "priority": 2
                },
                {
                  "pattern_id": "D06-F02-A01",
                  "name": "Doji",
                  "direction": "neutral",
                  "window": 1,
                  "detector": "doji",
                  "version": "v1",
                  "enabled": false,
                  "priority": 1
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "ready",
          "pattern_count": 2,
          "enabled_count": 1,
          "max_window": 2,
          "registry_id": "D06-F02-A01@v1;D06-F03-A01@v1"
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: state, pattern_count, enabled_count, max_window, registry_id"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision.svg",
            "url": "https://thefintechbuilder.com/content/d06-f05-a01/static/decision.svg"
          }
        ],
        "mermaid": [
          {
            "file": "decision-flow.md",
            "caption": "Decision flow",
            "source": "flowchart LR\n    A[\"Validated point-in-time input\"] --> B[\"Validate each specification\"]\n    B --> C[\"Reject duplicate ID or name\"]\n    C --> D{\"Boundary satisfied?\"}\n    D -->|\"Yes\"| E[\"Reason-coded ready output\"]\n    D -->|\"No\"| F[\"Explicit rejected or unavailable state\"]"
          }
        ]
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "TA-Lib function catalog and pattern-recognition group",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "SRC-02",
          "title": "TA-Lib C/C++ Core API",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/"
        },
        {
          "key": "SRC-03",
          "title": "Binance Spot kline/candlestick stream",
          "author": "Binance",
          "url": "https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#klinecandlestick-streams-for-utc"
        },
        {
          "key": "SRC-04",
          "title": "CME Group chart types and support/resistance lessons",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/courses/technical-analysis/chart-types-candlestick-line-bar"
        },
        {
          "key": "SRC-05",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://doi.org/10.3386/w7613"
        },
        {
          "key": "Evidence and licensing boundary",
          "title": "Evidence and licensing boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/candlestick-scanning-and-context/unified-candlestick-pattern-registry/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/candlestick-scanning-and-context/unified-candlestick-pattern-registry/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F05-A02",
      "name": "Candlestick Pattern Occurrence Contract",
      "headline": null,
      "slug": "candlestick-pattern-occurrence-contract",
      "path": "price-action-and-candlesticks/candlestick-scanning-and-context/candlestick-pattern-occurrence-contract",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F05",
        "family": "Candlestick Scanning and Context",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/candlestick-scanning-and-context/candlestick-pattern-occurrence-contract",
        "entry": "makeOccurrence",
        "params": [
          "data"
        ],
        "exports": [
          "makeOccurrence"
        ],
        "archetype": "record-transform",
        "signature": "makeOccurrence(data)"
      },
      "api": {
        "summary": "normalize detector hits into reproducible occurrences with stable identity, causal timestamps, version, geometry score, and reason codes.",
        "params": [
          {
            "name": "data",
            "type": "{ instrument_id: string; interval: string; price_basis: string; session: string; pattern_id: string; pattern_name: string; direction: string; start_index: number; end_index: number; start_time: string; end_time: string; detected_at: string; available_at: string; bar_closed: boolean; detector_version: string; geometry_score: number; reason_codes: string[] }",
            "required": true,
            "description": "Topic input record; the required fields are fixed by this topic data-contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ occurrence_id, instrument_id, interval, price_basis, session, pattern_id, pattern_name, direction, start_index, end_index, start_time, end_time, detected_at, available_at, bar_closed, detector_version, geometry_score, reason_codes }",
          "description": "One normalized closed-bar occurrence with a deterministic identity, causal timestamps, detector version, bounded geometry score, and explicit reason codes."
        },
        "warmup": null,
        "errors": [],
        "complexity": {
          "time": "O(n log n) worst case; see README for topic-specific n",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D06-F05-A02.json",
        "call": "makeOccurrence({\"instrument_id\":\"SYNTH:AAA\",\"interval\":\"5m\",\"price_basis\":\"raw-trades\",\"session\":\"synthetic-utc\",\"pattern_id\":\"D06-F03-A01\",\"pattern_name\":\"Bullish Engulfing\",\"direction\":\"bullish\",\"start_index\":10,\"end_index\":11,\"start_time\":\"2026-01-05T10:00:00Z\",\"end_time\":\"2026-01-05T10:05:00Z\",\"detected_at\":\"2026-01-05T10:05:01Z\",\"available_at\":\"2026-01-05T10:05:01Z\",\"bar_closed\":true})",
        "args": [
          {
            "value": {
              "instrument_id": "SYNTH:AAA",
              "interval": "5m",
              "price_basis": "raw-trades",
              "session": "synthetic-utc",
              "pattern_id": "D06-F03-A01",
              "pattern_name": "Bullish Engulfing",
              "direction": "bullish",
              "start_index": 10,
              "end_index": 11,
              "start_time": "2026-01-05T10:00:00Z",
              "end_time": "2026-01-05T10:05:00Z",
              "detected_at": "2026-01-05T10:05:01Z",
              "available_at": "2026-01-05T10:05:01Z",
              "bar_closed": true
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 17
            }
          }
        ],
        "output": {
          "occurrence_id": "SYNTH:AAA|5m|2026-01-05T10:05:00Z|D06-F03-A01|10:11|v1",
          "bar_closed": true,
          "geometry_score": 0.9
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: occurrence_id, bar_closed, geometry_score"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision.svg",
            "url": "https://thefintechbuilder.com/content/d06-f05-a02/static/decision.svg"
          }
        ],
        "mermaid": [
          {
            "file": "decision-flow.md",
            "caption": "Decision flow",
            "source": "flowchart LR\n    A[\"Validated point-in-time input\"] --> B[\"Validate identity and clocks\"]\n    B --> C[\"Require a closed terminal bar\"]\n    C --> D{\"Boundary satisfied?\"}\n    D -->|\"Yes\"| E[\"Reason-coded ready output\"]\n    D -->|\"No\"| F[\"Explicit rejected or unavailable state\"]"
          }
        ]
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "TA-Lib function catalog and pattern-recognition group",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "SRC-02",
          "title": "TA-Lib C/C++ Core API",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/"
        },
        {
          "key": "SRC-03",
          "title": "Binance Spot kline/candlestick stream",
          "author": "Binance",
          "url": "https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#klinecandlestick-streams-for-utc"
        },
        {
          "key": "SRC-04",
          "title": "CME Group chart types and support/resistance lessons",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/courses/technical-analysis/chart-types-candlestick-line-bar"
        },
        {
          "key": "SRC-05",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://doi.org/10.3386/w7613"
        },
        {
          "key": "Evidence and licensing boundary",
          "title": "Evidence and licensing boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/candlestick-scanning-and-context/candlestick-pattern-occurrence-contract/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/candlestick-scanning-and-context/candlestick-pattern-occurrence-contract/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F05-A03",
      "name": "Market-Wide Candlestick Pattern Scanner",
      "headline": null,
      "slug": "market-wide-candlestick-pattern-scanner",
      "path": "price-action-and-candlesticks/candlestick-scanning-and-context/market-wide-candlestick-pattern-scanner",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F05",
        "family": "Candlestick Scanning and Context",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/candlestick-scanning-and-context/market-wide-candlestick-pattern-scanner",
        "entry": "scanMarket",
        "params": [
          "data"
        ],
        "exports": [
          "scanMarket"
        ],
        "archetype": "record-transform",
        "signature": "scanMarket(data)"
      },
      "api": {
        "summary": "dispatch a frozen registry across injected detector candidates and emit only causal occurrence records with explicit rejection reasons.",
        "params": [
          {
            "name": "data",
            "type": "{ as_of: string; minimum_geometry_score: number; registry: { pattern_id: string; name: string; direction: string; window: number; detector: string; version: string; enabled: boolean; priority: number }[]; candidates: { instrument_id: string; interval: string; price_basis: string; session: string; pattern_id: string; pattern_name: string; direction: string; start_index: number; end_index: number; start_time: string; end_time: string; detected_at: string; available_at: string; bar_closed: boolean; detector_version: string; geometry_score: number; reason_codes: string[] }[] }",
            "required": true,
            "description": "Topic input record; the required fields are fixed by this topic data-contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, as_of, candidate_count, occurrence_count, skipped_count, occurrences, skipped }",
          "description": "One `ready` scan record containing deterministically ordered causal occurrences and reason-coded skipped candidates, with counts for both."
        },
        "warmup": null,
        "errors": [],
        "complexity": {
          "time": "O(n log n) worst case; see README for topic-specific n",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D06-F05-A03.json",
        "call": "scanMarket({\"as_of\":\"2026-01-05T10:06:00Z\",\"minimum_geometry_score\":0.8,\"registry\":[{\"pattern_id\":\"D06-F03-A01\",\"name\":\"Bullish Engulfing\",\"direction\":\"bullish\",\"window\":2,\"detector\":\"bullish_engulfing\",\"version\":\"v1\",\"enabled\":true,\"priority\":2}],\"candidates\":[{\"instrument_id\":\"SYNTH:AAA\",\"interval\":\"5m\",\"price_basis\":\"raw-trades\",\"session\":\"synthetic-utc\",\"pattern_id\":\"D06-F03-A01\",\"pattern_name\":\"Bullish Engulfing\",\"direction\":\"bullish\",\"start_index\":10,\"end_index\":11,\"start_time\":\"2026-01-05T10:00:00Z\",\"end_time\":\"2026-01-05T10:05:00Z\",\"detected_at\":\"2026-01-05T10:05:01Z\",\"available_at\":\"2026-01-05T10:05:01Z\",\"bar_closed\":true},{\"instrument_id\":\"SYNTH:LIVE\",\"interval\":\"5m\",\"price_basis\":\"raw-trades\",\"session\":\"synthetic-utc\",\"pattern_id\":\"D06-F03-A01\",\"pattern_name\":\"Bullish Engulfing\",\"direction\":\"bullish\",\"start_index\":10,\"end_index\":11,\"start_time\":\"2026-01-05T10:00:00Z\",\"end_time\":\"2026-01-05T10:05:00Z\",\"detected_at\":\"2026-01-05T10:05:01Z\",\"available_at\":\"2026-01-05T10:05:01Z\",\"bar_closed\":false},{\"instrument_id\":\"SYNTH:WEAK\",\"interval\":\"5m\",\"price_basis\":\"raw-trades\",\"session\":\"synthetic-utc\",\"pattern_id\":\"D06-F03-A01\",\"pattern_name\":\"Bullish Engulfing\",\"direction\":\"bullish\",\"start_index\":10,\"end_index\":11,\"start_time\":\"2026-01-05T10:00:00Z\",\"end_time\":\"2026-01-05T10:05:00Z\",\"detected_at\":\"2026-01-05T10:05:01Z\",\"available_at\":\"2026-01-05T10:05:01Z\",\"bar_closed\":true}]})",
        "args": [
          {
            "value": {
              "as_of": "2026-01-05T10:06:00Z",
              "minimum_geometry_score": 0.8,
              "registry": [
                {
                  "pattern_id": "D06-F03-A01",
                  "name": "Bullish Engulfing",
                  "direction": "bullish",
                  "window": 2,
                  "detector": "bullish_engulfing",
                  "version": "v1",
                  "enabled": true,
                  "priority": 2
                }
              ],
              "candidates": [
                {
                  "instrument_id": "SYNTH:AAA",
                  "interval": "5m",
                  "price_basis": "raw-trades",
                  "session": "synthetic-utc",
                  "pattern_id": "D06-F03-A01",
                  "pattern_name": "Bullish Engulfing",
                  "direction": "bullish",
                  "start_index": 10,
                  "end_index": 11,
                  "start_time": "2026-01-05T10:00:00Z",
                  "end_time": "2026-01-05T10:05:00Z",
                  "detected_at": "2026-01-05T10:05:01Z",
                  "available_at": "2026-01-05T10:05:01Z",
                  "bar_closed": true
                },
                {
                  "instrument_id": "SYNTH:LIVE",
                  "interval": "5m",
                  "price_basis": "raw-trades",
                  "session": "synthetic-utc",
                  "pattern_id": "D06-F03-A01",
                  "pattern_name": "Bullish Engulfing",
                  "direction": "bullish",
                  "start_index": 10,
                  "end_index": 11,
                  "start_time": "2026-01-05T10:00:00Z",
                  "end_time": "2026-01-05T10:05:00Z",
                  "detected_at": "2026-01-05T10:05:01Z",
                  "available_at": "2026-01-05T10:05:01Z",
                  "bar_closed": false
                },
                {
                  "instrument_id": "SYNTH:WEAK",
                  "interval": "5m",
                  "price_basis": "raw-trades",
                  "session": "synthetic-utc",
                  "pattern_id": "D06-F03-A01",
                  "pattern_name": "Bullish Engulfing",
                  "direction": "bullish",
                  "start_index": 10,
                  "end_index": 11,
                  "start_time": "2026-01-05T10:00:00Z",
                  "end_time": "2026-01-05T10:05:00Z",
                  "detected_at": "2026-01-05T10:05:01Z",
                  "available_at": "2026-01-05T10:05:01Z",
                  "bar_closed": true
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "ready",
          "candidate_count": 3,
          "occurrence_count": 1,
          "skipped_count": 2
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: state, candidate_count, occurrence_count, skipped_count"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision.svg",
            "url": "https://thefintechbuilder.com/content/d06-f05-a03/static/decision.svg"
          }
        ],
        "mermaid": [
          {
            "file": "decision-flow.md",
            "caption": "Decision flow",
            "source": "flowchart LR\n    A[\"Validated point-in-time input\"] --> B[\"Freeze scan cut-off\"]\n    B --> C[\"Resolve enabled detector\"]\n    C --> D{\"Boundary satisfied?\"}\n    D -->|\"Yes\"| E[\"Reason-coded ready output\"]\n    D -->|\"No\"| F[\"Explicit rejected or unavailable state\"]"
          }
        ]
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "TA-Lib function catalog and pattern-recognition group",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "SRC-02",
          "title": "TA-Lib C/C++ Core API",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/"
        },
        {
          "key": "SRC-03",
          "title": "Binance Spot kline/candlestick stream",
          "author": "Binance",
          "url": "https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#klinecandlestick-streams-for-utc"
        },
        {
          "key": "SRC-04",
          "title": "CME Group chart types and support/resistance lessons",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/courses/technical-analysis/chart-types-candlestick-line-bar"
        },
        {
          "key": "SRC-05",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://doi.org/10.3386/w7613"
        },
        {
          "key": "Evidence and licensing boundary",
          "title": "Evidence and licensing boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/candlestick-scanning-and-context/market-wide-candlestick-pattern-scanner/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/candlestick-scanning-and-context/market-wide-candlestick-pattern-scanner/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F05-A04",
      "name": "Contextual Candlestick Confidence Score",
      "headline": null,
      "slug": "contextual-candlestick-confidence-score",
      "path": "price-action-and-candlesticks/candlestick-scanning-and-context/contextual-candlestick-confidence-score",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F05",
        "family": "Candlestick Scanning and Context",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/candlestick-scanning-and-context/contextual-candlestick-confidence-score",
        "entry": "scoreContext",
        "params": [
          "data"
        ],
        "exports": [
          "scoreContext"
        ],
        "archetype": "record-transform",
        "signature": "scoreContext(data)"
      },
      "api": {
        "summary": "combine available, direction-aligned evidence with explicit weights and a minimum evidence-coverage gate.",
        "params": [
          {
            "name": "data",
            "type": "{ features: { geometry: number; support_resistance: number; trend: number; volatility: number; volume: number; confirmation: number }; minimum_coverage: number }",
            "required": true,
            "description": "Topic input record; the required fields are fixed by this topic data-contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, score, evidence_coverage, minimum_coverage, contributions, interpretation }",
          "description": "One context-fit record. `state` is `ready` with a 0-100 score when the minimum evidence coverage is met, otherwise `insufficient-evidence` with a null score; this is not a probability."
        },
        "warmup": null,
        "errors": [],
        "complexity": {
          "time": "O(n log n) worst case; see README for topic-specific n",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D06-F05-A04.json",
        "call": "scoreContext({\"features\":{\"geometry\":0.9,\"support_resistance\":0.8,\"trend\":0.6,\"volatility\":0.7,\"volume\":1,\"confirmation\":0.5},\"minimum_coverage\":0.7})",
        "args": [
          {
            "value": {
              "features": {
                "geometry": 0.9,
                "support_resistance": 0.8,
                "trend": 0.6,
                "volatility": 0.7,
                "volume": 1,
                "confirmation": 0.5
              },
              "minimum_coverage": 0.7
            },
            "elided": null
          }
        ],
        "output": {
          "state": "ready",
          "score": 76.49999999999999,
          "evidence_coverage": 1,
          "interpretation": "context-fit-index-not-probability"
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: state, score, evidence_coverage, interpretation"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision.svg",
            "url": "https://thefintechbuilder.com/content/d06-f05-a04/static/decision.svg"
          }
        ],
        "mermaid": [
          {
            "file": "decision-flow.md",
            "caption": "Decision flow",
            "source": "flowchart LR\n    A[\"Validated point-in-time input\"] --> B[\"Validate aligned features\"]\n    B --> C[\"Exclude missing evidence\"]\n    C --> D{\"Boundary satisfied?\"}\n    D -->|\"Yes\"| E[\"Reason-coded ready output\"]\n    D -->|\"No\"| F[\"Explicit rejected or unavailable state\"]"
          }
        ]
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "TA-Lib function catalog and pattern-recognition group",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "SRC-02",
          "title": "TA-Lib C/C++ Core API",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/"
        },
        {
          "key": "SRC-03",
          "title": "Binance Spot kline/candlestick stream",
          "author": "Binance",
          "url": "https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#klinecandlestick-streams-for-utc"
        },
        {
          "key": "SRC-04",
          "title": "CME Group chart types and support/resistance lessons",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/courses/technical-analysis/chart-types-candlestick-line-bar"
        },
        {
          "key": "SRC-05",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://doi.org/10.3386/w7613"
        },
        {
          "key": "Evidence and licensing boundary",
          "title": "Evidence and licensing boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/candlestick-scanning-and-context/contextual-candlestick-confidence-score/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/candlestick-scanning-and-context/contextual-candlestick-confidence-score/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F05-A05",
      "name": "Support/Resistance Pattern Context",
      "headline": null,
      "slug": "support-resistance-pattern-context",
      "path": "price-action-and-candlesticks/candlestick-scanning-and-context/support-resistance-pattern-context",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F05",
        "family": "Candlestick Scanning and Context",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/candlestick-scanning-and-context/support-resistance-pattern-context",
        "entry": "supportResistanceContext",
        "params": [
          "data"
        ],
        "exports": [
          "supportResistanceContext"
        ],
        "archetype": "record-transform",
        "signature": "supportResistanceContext(data)"
      },
      "api": {
        "summary": "select the nearest causally confirmed directional level and turn ATR-normalized distance into a transparent [0,1] context feature.",
        "params": [
          {
            "name": "data",
            "type": "{ pattern_price: number; atr: number; direction: string; occurrence_index: number; max_distance_atr: number; levels: { price: number; kind: string; strength: number; confirmed_index: number }[] }",
            "required": true,
            "description": "Topic input record; the required fields are fixed by this topic data-contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, context_score, matched_level, target_kind?, distance_atr? }",
          "description": "One directional context record. `state` is `ready`, `no-causal-level`, or `unsupported-direction`; score and distance are present only when their evidence exists."
        },
        "warmup": null,
        "errors": [],
        "complexity": {
          "time": "O(n log n) worst case; see README for topic-specific n",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D06-F05-A05.json",
        "call": "supportResistanceContext({\"pattern_price\":100,\"atr\":2,\"direction\":\"bullish\",\"occurrence_index\":10,\"max_distance_atr\":2,\"levels\":[{\"price\":99,\"kind\":\"support\",\"strength\":0.8,\"confirmed_index\":9},{\"price\":101,\"kind\":\"resistance\",\"strength\":0.9,\"confirmed_index\":8},{\"price\":100.2,\"kind\":\"support\",\"strength\":1,\"confirmed_index\":11}]})",
        "args": [
          {
            "value": {
              "pattern_price": 100,
              "atr": 2,
              "direction": "bullish",
              "occurrence_index": 10,
              "max_distance_atr": 2,
              "levels": [
                {
                  "price": 99,
                  "kind": "support",
                  "strength": 0.8,
                  "confirmed_index": 9
                },
                {
                  "price": 101,
                  "kind": "resistance",
                  "strength": 0.9,
                  "confirmed_index": 8
                },
                {
                  "price": 100.2,
                  "kind": "support",
                  "strength": 1,
                  "confirmed_index": 11
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "ready",
          "target_kind": "support",
          "distance_atr": 0.5,
          "context_score": 0.75
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: state, target_kind, distance_atr, context_score"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision.svg",
            "url": "https://thefintechbuilder.com/content/d06-f05-a05/static/decision.svg"
          }
        ],
        "mermaid": [
          {
            "file": "decision-flow.md",
            "caption": "Decision flow",
            "source": "flowchart LR\n    A[\"Validated point-in-time input\"] --> B[\"Choose direction-relevant level kind\"]\n    B --> C[\"Remove future-confirmed levels\"]\n    C --> D{\"Boundary satisfied?\"}\n    D -->|\"Yes\"| E[\"Reason-coded ready output\"]\n    D -->|\"No\"| F[\"Explicit rejected or unavailable state\"]"
          }
        ]
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "TA-Lib function catalog and pattern-recognition group",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "SRC-02",
          "title": "TA-Lib C/C++ Core API",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/"
        },
        {
          "key": "SRC-03",
          "title": "Binance Spot kline/candlestick stream",
          "author": "Binance",
          "url": "https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#klinecandlestick-streams-for-utc"
        },
        {
          "key": "SRC-04",
          "title": "CME Group chart types and support/resistance lessons",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/courses/technical-analysis/chart-types-candlestick-line-bar"
        },
        {
          "key": "SRC-05",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://doi.org/10.3386/w7613"
        },
        {
          "key": "Evidence and licensing boundary",
          "title": "Evidence and licensing boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/candlestick-scanning-and-context/support-resistance-pattern-context/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/candlestick-scanning-and-context/support-resistance-pattern-context/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F05-A06",
      "name": "Trend, Volatility, and Volume Pattern Context",
      "headline": null,
      "slug": "trend-volatility-and-volume-pattern-context",
      "path": "price-action-and-candlesticks/candlestick-scanning-and-context/trend-volatility-and-volume-pattern-context",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F05",
        "family": "Candlestick Scanning and Context",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/candlestick-scanning-and-context/trend-volatility-and-volume-pattern-context",
        "entry": "trendVolatilityVolumeContext",
        "params": [
          "data"
        ],
        "exports": [
          "trendVolatilityVolumeContext"
        ],
        "archetype": "record-transform",
        "signature": "trendVolatilityVolumeContext(data)"
      },
      "api": {
        "summary": "derive three separately auditable context features from prior closes, ranges, and volumes plus the current closed bar.",
        "params": [
          {
            "name": "data",
            "type": "{ prior_closes: number[]; prior_ranges: number[]; prior_volumes: number[]; lookback: number; expected_prior_trend: string; current_range: number; current_volume: number; target_volume_ratio: number }",
            "required": true,
            "description": "Topic input record; the required fields are fixed by this topic data-contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, history_count?, range_scale?, volume_scale?, normalized_slope?, trend_score?, volatility_ratio?, volatility_score?, volume_ratio?, volume_score? }",
          "description": "One readiness record. `state` is `warmup` until `lookback` aligned observations exist, `zero-scale` for unusable range or volume scales, and `ready` with the three component scores otherwise; no positional series is returned."
        },
        "warmup": {
          "count": "lookback aligned observations",
          "value": "state: warmup",
          "note": "The function returns one readiness record until aligned close, range, and volume histories reach lookback; it does not emit a positional null prefix."
        },
        "errors": [],
        "complexity": {
          "time": "O(n log n) worst case; see README for topic-specific n",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D06-F05-A06.json",
        "call": "trendVolatilityVolumeContext({\"prior_closes\":[105,104,103,102,101],\"prior_ranges\":[2,2,2,2,2],\"prior_volumes\":[100,100,100,100,100],\"lookback\":5,\"expected_prior_trend\":\"downtrend\",\"current_range\":3,\"current_volume\":150,\"target_volume_ratio\":1.5})",
        "args": [
          {
            "value": {
              "prior_closes": [
                105,
                104,
                103,
                102,
                101
              ],
              "prior_ranges": [
                2,
                2,
                2,
                2,
                2
              ],
              "prior_volumes": [
                100,
                100,
                100,
                100,
                100
              ],
              "lookback": 5,
              "expected_prior_trend": "downtrend",
              "current_range": 3,
              "current_volume": 150,
              "target_volume_ratio": 1.5
            },
            "elided": null
          }
        ],
        "output": {
          "state": "ready",
          "normalized_slope": -0.5,
          "trend_score": 0.5,
          "volatility_ratio": 1.5,
          "volatility_score": 0.75,
          "volume_ratio": 1.5,
          "volume_score": 1
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: state, normalized_slope, trend_score, volatility_ratio, volatility_score, volume_ratio, volume_score"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision.svg",
            "url": "https://thefintechbuilder.com/content/d06-f05-a06/static/decision.svg"
          }
        ],
        "mermaid": [
          {
            "file": "decision-flow.md",
            "caption": "Decision flow",
            "source": "flowchart LR\n    A[\"Validated point-in-time input\"] --> B[\"Require causal warm-up\"]\n    B --> C[\"Compute robust prior scales\"]\n    C --> D{\"Boundary satisfied?\"}\n    D -->|\"Yes\"| E[\"Reason-coded ready output\"]\n    D -->|\"No\"| F[\"Explicit rejected or unavailable state\"]"
          }
        ]
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "TA-Lib function catalog and pattern-recognition group",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "SRC-02",
          "title": "TA-Lib C/C++ Core API",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/"
        },
        {
          "key": "SRC-03",
          "title": "Binance Spot kline/candlestick stream",
          "author": "Binance",
          "url": "https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#klinecandlestick-streams-for-utc"
        },
        {
          "key": "SRC-04",
          "title": "CME Group chart types and support/resistance lessons",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/courses/technical-analysis/chart-types-candlestick-line-bar"
        },
        {
          "key": "SRC-05",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://doi.org/10.3386/w7613"
        },
        {
          "key": "Evidence and licensing boundary",
          "title": "Evidence and licensing boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/candlestick-scanning-and-context/trend-volatility-and-volume-pattern-context/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/candlestick-scanning-and-context/trend-volatility-and-volume-pattern-context/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F05-A07",
      "name": "Overlapping-Pattern Conflict Resolver",
      "headline": null,
      "slug": "overlapping-pattern-conflict-resolver",
      "path": "price-action-and-candlesticks/candlestick-scanning-and-context/overlapping-pattern-conflict-resolver",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F05",
        "family": "Candlestick Scanning and Context",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/candlestick-scanning-and-context/overlapping-pattern-conflict-resolver",
        "entry": "resolveConflicts",
        "params": [
          "data"
        ],
        "exports": [
          "resolveConflicts"
        ],
        "archetype": "row-classify",
        "signature": "resolveConflicts(data)"
      },
      "api": {
        "summary": "form connected overlap components and choose one reproducible winner using declared precedence and stable tie-breaks.",
        "params": [
          {
            "name": "data",
            "type": "{ occurrences: { occurrence_id: string; instrument_id: string; interval: string; pattern_id: string; direction: string; start_index: number; end_index: number; priority: number; confidence: number; geometry_score: number }[] }",
            "required": true,
            "description": "Topic input record; the required fields are fixed by this topic data-contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, winner_count, suppressed_count, winners, suppressed }",
          "description": "One `ready` conflict-resolution record containing the deterministic winners and reason-coded suppressed occurrences with aggregate counts."
        },
        "warmup": null,
        "errors": [],
        "complexity": {
          "time": "O(n log n) worst case; see README for topic-specific n",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D06-F05-A07.json",
        "call": "resolveConflicts({\"occurrences\":[{\"occurrence_id\":\"A\",\"instrument_id\":\"SYNTH:AAA\",\"interval\":\"5m\",\"pattern_id\":\"D06-F02-A01\",\"direction\":\"neutral\",\"start_index\":10,\"end_index\":10,\"priority\":1,\"confidence\":90,\"geometry_score\":0.95},{\"occurrence_id\":\"B\",\"instrument_id\":\"SYNTH:AAA\",\"interval\":\"5m\",\"pattern_id\":\"D06-F03-A01\",\"direction\":\"bullish\",\"start_index\":10,\"end_index\":11,\"priority\":2,\"confidence\":70,\"geometry_score\":0.85},{\"occurrence_id\":\"C\",\"instrument_id\":\"SYNTH:AAA\",\"interval\":\"5m\",\"pattern_id\":\"D06-F02-A04\",\"direction\":\"bullish\",\"start_index\":15,\"end_index\":15,\"priority\":1,\"confidence\":80,\"geometry_score\":0.9}]})",
        "args": [
          {
            "value": {
              "occurrences": [
                {
                  "occurrence_id": "A",
                  "instrument_id": "SYNTH:AAA",
                  "interval": "5m",
                  "pattern_id": "D06-F02-A01",
                  "direction": "neutral",
                  "start_index": 10,
                  "end_index": 10,
                  "priority": 1,
                  "confidence": 90,
                  "geometry_score": 0.95
                },
                {
                  "occurrence_id": "B",
                  "instrument_id": "SYNTH:AAA",
                  "interval": "5m",
                  "pattern_id": "D06-F03-A01",
                  "direction": "bullish",
                  "start_index": 10,
                  "end_index": 11,
                  "priority": 2,
                  "confidence": 70,
                  "geometry_score": 0.85
                },
                {
                  "occurrence_id": "C",
                  "instrument_id": "SYNTH:AAA",
                  "interval": "5m",
                  "pattern_id": "D06-F02-A04",
                  "direction": "bullish",
                  "start_index": 15,
                  "end_index": 15,
                  "priority": 1,
                  "confidence": 80,
                  "geometry_score": 0.9
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "ready",
          "winner_count": 2,
          "suppressed_count": 1
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: state, winner_count, suppressed_count"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision.svg",
            "url": "https://thefintechbuilder.com/content/d06-f05-a07/static/decision.svg"
          }
        ],
        "mermaid": [
          {
            "file": "decision-flow.md",
            "caption": "Decision flow",
            "source": "flowchart LR\n    A[\"Validated point-in-time input\"] --> B[\"Partition by instrument and interval\"]\n    B --> C[\"Sort inclusive spans\"]\n    C --> D{\"Boundary satisfied?\"}\n    D -->|\"Yes\"| E[\"Reason-coded ready output\"]\n    D -->|\"No\"| F[\"Explicit rejected or unavailable state\"]"
          }
        ]
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "TA-Lib function catalog and pattern-recognition group",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "SRC-02",
          "title": "TA-Lib C/C++ Core API",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/"
        },
        {
          "key": "SRC-03",
          "title": "Binance Spot kline/candlestick stream",
          "author": "Binance",
          "url": "https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#klinecandlestick-streams-for-utc"
        },
        {
          "key": "SRC-04",
          "title": "CME Group chart types and support/resistance lessons",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/courses/technical-analysis/chart-types-candlestick-line-bar"
        },
        {
          "key": "SRC-05",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://doi.org/10.3386/w7613"
        },
        {
          "key": "Evidence and licensing boundary",
          "title": "Evidence and licensing boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/candlestick-scanning-and-context/overlapping-pattern-conflict-resolver/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/candlestick-scanning-and-context/overlapping-pattern-conflict-resolver/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F05-A08",
      "name": "Candlestick Confirmation and Invalidation State Machine",
      "headline": null,
      "slug": "candlestick-confirmation-and-invalidation-state-machine",
      "path": "price-action-and-candlesticks/candlestick-scanning-and-context/candlestick-confirmation-and-invalidation-state-machine",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F05",
        "family": "Candlestick Scanning and Context",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/candlestick-scanning-and-context/candlestick-confirmation-and-invalidation-state-machine",
        "entry": "runConfirmationStateMachine",
        "params": [
          "data"
        ],
        "exports": [
          "runConfirmationStateMachine"
        ],
        "archetype": "record-transform",
        "signature": "runConfirmationStateMachine(data)"
      },
      "api": {
        "summary": "advance directional candidates through closed-bar transitions with ordered levels, finite expiry, and complete reason-coded history.",
        "params": [
          {
            "name": "data",
            "type": "{ detection_index: number; direction: string; confirmation_level: number; invalidation_level: number; expires_after_bars: number; events: { bar_index: number; bar_closed: boolean; close: number }[] }",
            "required": true,
            "description": "Topic input record; the required fields are fixed by this topic data-contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, direction, confirmation_level, invalidation_level, transitions, terminal }",
          "description": "One lifecycle record. `state` progresses from `awaiting-confirmation` to `confirmed`, `invalidated`, or `expired`; `terminal` identifies those final states and `transitions` preserves the full reason-coded trace."
        },
        "warmup": null,
        "errors": [],
        "complexity": {
          "time": "O(n log n) worst case; see README for topic-specific n",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D06-F05-A08.json",
        "call": "runConfirmationStateMachine({\"detection_index\":10,\"direction\":\"bullish\",\"confirmation_level\":105,\"invalidation_level\":95,\"expires_after_bars\":3,\"events\":[{\"bar_index\":11,\"bar_closed\":true,\"close\":102},{\"bar_index\":12,\"bar_closed\":true,\"close\":106}]})",
        "args": [
          {
            "value": {
              "detection_index": 10,
              "direction": "bullish",
              "confirmation_level": 105,
              "invalidation_level": 95,
              "expires_after_bars": 3,
              "events": [
                {
                  "bar_index": 11,
                  "bar_closed": true,
                  "close": 102
                },
                {
                  "bar_index": 12,
                  "bar_closed": true,
                  "close": 106
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "confirmed",
          "terminal": true,
          "confirmation_level": 105,
          "invalidation_level": 95
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: state, terminal, confirmation_level, invalidation_level"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision.svg",
            "url": "https://thefintechbuilder.com/content/d06-f05-a08/static/decision.svg"
          }
        ],
        "mermaid": [
          {
            "file": "decision-flow.md",
            "caption": "Decision flow",
            "source": "flowchart LR\n    A[\"Validated point-in-time input\"] --> B[\"Detect geometry\"]\n    B --> C[\"Arm ordered levels\"]\n    C --> D{\"Boundary satisfied?\"}\n    D -->|\"Yes\"| E[\"Reason-coded ready output\"]\n    D -->|\"No\"| F[\"Explicit rejected or unavailable state\"]"
          }
        ]
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "TA-Lib function catalog and pattern-recognition group",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "SRC-02",
          "title": "TA-Lib C/C++ Core API",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/"
        },
        {
          "key": "SRC-03",
          "title": "Binance Spot kline/candlestick stream",
          "author": "Binance",
          "url": "https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#klinecandlestick-streams-for-utc"
        },
        {
          "key": "SRC-04",
          "title": "CME Group chart types and support/resistance lessons",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/courses/technical-analysis/chart-types-candlestick-line-bar"
        },
        {
          "key": "SRC-05",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://doi.org/10.3386/w7613"
        },
        {
          "key": "Evidence and licensing boundary",
          "title": "Evidence and licensing boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/candlestick-scanning-and-context/candlestick-confirmation-and-invalidation-state-machine/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/candlestick-scanning-and-context/candlestick-confirmation-and-invalidation-state-machine/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D06-F05-A09",
      "name": "Candlestick Scanner Ranking and Deduplication",
      "headline": null,
      "slug": "candlestick-scanner-ranking-and-deduplication",
      "path": "price-action-and-candlesticks/candlestick-scanning-and-context/candlestick-scanner-ranking-and-deduplication",
      "taxonomy": {
        "domainId": "D06",
        "domain": "Price Action and Candlesticks",
        "familyId": "D06-F05",
        "family": "Candlestick Scanning and Context",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/price-action-and-candlesticks/candlestick-scanning-and-context/candlestick-scanner-ranking-and-deduplication",
        "entry": "rankAndDeduplicate",
        "params": [
          "data"
        ],
        "exports": [
          "rankAndDeduplicate"
        ],
        "archetype": "record-transform",
        "signature": "rankAndDeduplicate(data)"
      },
      "api": {
        "summary": "calculate a traceable composite rank, keep deterministic order, and deduplicate only within an explicit identity key and bar window.",
        "params": [
          {
            "name": "data",
            "type": "{ recency_half_life_bars: number; dedup_window_bars: number; occurrences: { occurrence_id: string; instrument_id: string; interval: string; pattern_id: string; direction: string; end_index: number; confidence: number; age_bars: number; liquidity_score: number; priority_score: number }[] }",
            "required": true,
            "description": "Topic input record; the required fields are fixed by this topic data-contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, ranked_count, suppressed_count, ranked, suppressed }",
          "description": "One `ready` ranking record containing stable ranks and component traces for kept occurrences plus reason-coded duplicates and both counts."
        },
        "warmup": null,
        "errors": [],
        "complexity": {
          "time": "O(n log n) worst case; see README for topic-specific n",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D06-F05-A09.json",
        "call": "rankAndDeduplicate({\"recency_half_life_bars\":5,\"dedup_window_bars\":2,\"occurrences\":[{\"occurrence_id\":\"A\",\"instrument_id\":\"SYNTH:AAA\",\"interval\":\"5m\",\"pattern_id\":\"D06-F03-A01\",\"direction\":\"bullish\",\"end_index\":10,\"confidence\":90,\"age_bars\":1,\"liquidity_score\":0.8,\"priority_score\":0.8},{\"occurrence_id\":\"B\",\"instrument_id\":\"SYNTH:AAA\",\"interval\":\"5m\",\"pattern_id\":\"D06-F03-A01\",\"direction\":\"bullish\",\"end_index\":11,\"confidence\":85,\"age_bars\":0,\"liquidity_score\":0.9,\"priority_score\":0.9},{\"occurrence_id\":\"C\",\"instrument_id\":\"SYNTH:BBB\",\"interval\":\"5m\",\"pattern_id\":\"D06-F02-A06\",\"direction\":\"bullish\",\"end_index\":11,\"confidence\":70,\"age_bars\":2,\"liquidity_score\":1,\"priority_score\":0.5}]})",
        "args": [
          {
            "value": {
              "recency_half_life_bars": 5,
              "dedup_window_bars": 2,
              "occurrences": [
                {
                  "occurrence_id": "A",
                  "instrument_id": "SYNTH:AAA",
                  "interval": "5m",
                  "pattern_id": "D06-F03-A01",
                  "direction": "bullish",
                  "end_index": 10,
                  "confidence": 90,
                  "age_bars": 1,
                  "liquidity_score": 0.8,
                  "priority_score": 0.8
                },
                {
                  "occurrence_id": "B",
                  "instrument_id": "SYNTH:AAA",
                  "interval": "5m",
                  "pattern_id": "D06-F03-A01",
                  "direction": "bullish",
                  "end_index": 11,
                  "confidence": 85,
                  "age_bars": 0,
                  "liquidity_score": 0.9,
                  "priority_score": 0.9
                },
                {
                  "occurrence_id": "C",
                  "instrument_id": "SYNTH:BBB",
                  "interval": "5m",
                  "pattern_id": "D06-F02-A06",
                  "direction": "bullish",
                  "end_index": 11,
                  "confidence": 70,
                  "age_bars": 2,
                  "liquidity_score": 1,
                  "priority_score": 0.5
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "ready",
          "ranked_count": 2,
          "suppressed_count": 1
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: state, ranked_count, suppressed_count"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "decision.svg",
            "url": "https://thefintechbuilder.com/content/d06-f05-a09/static/decision.svg"
          }
        ],
        "mermaid": [
          {
            "file": "decision-flow.md",
            "caption": "Decision flow",
            "source": "flowchart LR\n    A[\"Validated point-in-time input\"] --> B[\"Normalize rank components\"]\n    B --> C[\"Apply declared weights\"]\n    C --> D{\"Boundary satisfied?\"}\n    D -->|\"Yes\"| E[\"Reason-coded ready output\"]\n    D -->|\"No\"| F[\"Explicit rejected or unavailable state\"]"
          }
        ]
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "TA-Lib function catalog and pattern-recognition group",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "SRC-02",
          "title": "TA-Lib C/C++ Core API",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/"
        },
        {
          "key": "SRC-03",
          "title": "Binance Spot kline/candlestick stream",
          "author": "Binance",
          "url": "https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#klinecandlestick-streams-for-utc"
        },
        {
          "key": "SRC-04",
          "title": "CME Group chart types and support/resistance lessons",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/courses/technical-analysis/chart-types-candlestick-line-bar"
        },
        {
          "key": "SRC-05",
          "title": "Foundations of Technical Analysis",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://doi.org/10.3386/w7613"
        },
        {
          "key": "Evidence and licensing boundary",
          "title": "Evidence and licensing boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/price-action-and-candlesticks/candlestick-scanning-and-context/candlestick-scanner-ranking-and-deduplication/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/price-action-and-candlesticks/candlestick-scanning-and-context/candlestick-scanner-ranking-and-deduplication/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A01",
      "name": "Simple Moving Average (SMA)",
      "headline": "Define the Window Before the Mean",
      "slug": "sma",
      "path": "technical-indicators/trend-smoothing/sma",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/sma",
        "entry": "calculateSma",
        "params": [
          "values",
          "window"
        ],
        "exports": [
          "calculateSma",
          "calculateSmaSeries"
        ],
        "archetype": "series-transform",
        "signature": "calculateSma(values, window)"
      },
      "api": {
        "summary": "Arithmetic mean of the last `window` observations, emitted at every position where a complete window is available.",
        "params": [
          {
            "name": "values",
            "type": "(number | null)[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": "propagate",
            "default": null
          },
          {
            "name": "window",
            "type": "number",
            "required": true,
            "description": "Number of observations in the mean.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "(number | null)[]",
          "length": "same-as-input",
          "description": "Index `i` holds the mean of observations `i - window + 1` through `i`."
        },
        "warmup": {
          "count": "window - 1",
          "value": "null",
          "note": "Warm-up positions are null rather than a partial result, so a consumer never mistakes an incomplete window for a real value."
        },
        "errors": [
          {
            "when": "window < 1 or is not an integer",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D07-F01-A01.json",
        "call": "calculateSma([10,13,12,15,14,18], 3)",
        "args": [
          {
            "value": [
              10,
              13,
              12,
              15,
              14,
              18
            ],
            "elided": null
          },
          {
            "value": 3,
            "elided": null
          }
        ],
        "output": [
          null,
          null,
          11.666666666666666,
          13.333333333333334,
          13.666666666666666,
          15.666666666666666
        ],
        "outputElided": null,
        "outputShape": "array of 6 nulls"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "sma-path.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a01/static/sma-path.svg"
          },
          {
            "file": "sma-window-update.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a01/static/sma-window-update.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "SMA calculation flow",
            "source": "flowchart TD\n    A[\"Receive ordered observation x_t\"] --> B{\"Window is a positive integer and x_t is finite?\"}\n    B -- \"No\" --> X[\"Reject input\"]\n    B -- \"Yes\" --> C[\"Add x_t to rolling sum\"]\n    C --> D{\"More than n observations?\"}\n    D -- \"Yes\" --> E[\"Subtract outgoing x_(t-n)\"]\n    D -- \"No\" --> F{\"At least n observations?\"}\n    E --> F\n    F -- \"No\" --> G[\"Emit null · warming\"]\n    F -- \"Yes\" --> H[\"Emit rolling_sum / n · ready\"]"
          }
        ]
      },
      "references": [
        {
          "key": "NIST-01",
          "title": "Single Moving Average",
          "author": "NIST/SEMATECH",
          "url": "https://www.itl.nist.gov/div898/handbook/pmc/section4/pmc421.htm"
        },
        {
          "key": "NIST-02",
          "title": "Averaging Methods",
          "author": "NIST/SEMATECH",
          "url": "https://www.itl.nist.gov/div898/handbook/pmc/section4/pmc42.htm"
        },
        {
          "key": "NIST-03",
          "title": "Centered Moving Average",
          "author": "NIST/SEMATECH",
          "url": "https://www.itl.nist.gov/div898/handbook/pmc/section4/pmc422.htm"
        },
        {
          "key": "NIST-04",
          "title": "Common Approaches to Univariate Time Series",
          "author": "NIST/SEMATECH",
          "url": "https://www.itl.nist.gov/div898/handbook/pmc/section4/pmc444.htm"
        },
        {
          "key": "PANDAS-01",
          "title": "`DataFrame.rolling`",
          "author": "pandas project",
          "url": "https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.rolling.html"
        },
        {
          "key": "PANDAS-02",
          "title": "`Rolling.mean`",
          "author": "pandas project",
          "url": "https://pandas.pydata.org/docs/reference/api/pandas.core.window.rolling.Rolling.mean.html"
        },
        {
          "key": "NYFED-01",
          "title": "Secured Overnight Financing Rate Data",
          "author": "Federal Reserve Bank of New York",
          "url": "https://www.newyorkfed.org/markets/reference-rates/sofr"
        },
        {
          "key": "NYFED-02",
          "title": "Markets Data APIs",
          "author": "Federal Reserve Bank of New York",
          "url": "https://markets.newyorkfed.org/static/docs/markets-api.html"
        },
        {
          "key": "NYFED-03",
          "title": "Additional Information about Reference Rates",
          "author": "Federal Reserve Bank of New York",
          "url": "https://www.newyorkfed.org/markets/reference-rates/additional-information-about-reference-rates"
        },
        {
          "key": "Source-to-claim map",
          "title": "Source-to-claim map",
          "author": null,
          "url": null
        },
        {
          "key": "Reproducibility boundary",
          "title": "Reproducibility boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/sma/",
        "repo": "https://github.com/IslamBaraka90/Fintech-SMA-Simple-Moving-Average-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/sma/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A02",
      "name": "Exponential Moving Average (EMA)",
      "headline": null,
      "slug": "ema",
      "path": "technical-indicators/trend-smoothing/ema",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/ema",
        "entry": "calculateEma",
        "params": [
          "values",
          "span"
        ],
        "exports": [
          "alphaFromSpan",
          "calculateEma",
          "calculateAdjustedEma",
          "calculateTimeAwareEma"
        ],
        "archetype": "series-transform",
        "signature": "calculateEma(values, span)"
      },
      "api": {
        "summary": "Exponentially weighted mean seeded with the simple mean of the first `span` observations, so the series is reproducible rather than dependent on where the data starts.",
        "params": [
          {
            "name": "values",
            "type": "(number | null)[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": "propagate",
            "default": null
          },
          {
            "name": "span",
            "type": "number",
            "required": true,
            "description": "Smoothing span; the decay factor is 2 / (span + 1).",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "(number | null)[]",
          "length": "same-as-input",
          "description": "Smoothed series, `null` until the seed window closes."
        },
        "warmup": {
          "count": "span - 1",
          "value": "null",
          "note": "Warm-up positions are null rather than a partial result, so a consumer never mistakes an incomplete window for a real value."
        },
        "errors": [
          {
            "when": "span < 1 or is not an integer",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D07-F01-A02.json",
        "call": "calculateEma([10,13,12,15,14,18], 3)",
        "args": [
          {
            "value": [
              10,
              13,
              12,
              15,
              14,
              18
            ],
            "elided": null
          },
          {
            "value": 3,
            "elided": null
          }
        ],
        "output": [
          null,
          null,
          11.666666666666666,
          13.333333333333334,
          13.666666666666666,
          15.833333333333334
        ],
        "outputElided": null,
        "outputShape": "array of 6 nulls"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "ema-path.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a02/static/ema-path.svg"
          },
          {
            "file": "ema-step.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a02/static/ema-step.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "EMA calculation flow",
            "source": "flowchart LR\n    A[\"Ordered finite observation\"] --> B{\"Contract and series identity valid?\"}\n    B -- \"No\" --> C[\"Reject without updating state\"]\n    B -- \"Yes\" --> D{\"EMA seeded?\"}\n    D -- \"No\" --> E[\"Collect valid values\"]\n    E --> F{\"Count equals span?\"}\n    F -- \"No\" --> G[\"Emit warm-up point with null EMA\"]\n    F -- \"Yes\" --> H[\"Seed EMA with simple average\"]\n    D -- \"Yes\" --> I[\"EMA = prior EMA + alpha × current gap\"]\n    H --> J[\"Emit ready EMA and provenance\"]\n    I --> J"
          }
        ]
      },
      "references": [
        {
          "key": "EMA-01",
          "title": "NIST single exponential smoothing",
          "author": "National Institute of Standards and Technology",
          "url": null
        },
        {
          "key": "EMA-02",
          "title": "NIST Dataplot exponential smoothing",
          "author": "National Institute of Standards and Technology",
          "url": null
        },
        {
          "key": "EMA-03",
          "title": "pandas exponentially weighted calculations",
          "author": "pandas project",
          "url": null
        },
        {
          "key": "EMA-04",
          "title": "StockCharts moving-average methodology",
          "author": "StockCharts.com",
          "url": null
        },
        {
          "key": "EMA-05",
          "title": "McClellan EMA calculation",
          "author": "McClellan Financial Publications",
          "url": null
        },
        {
          "key": "Evidence and design reconciliation",
          "title": "Evidence and design reconciliation",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/ema/",
        "repo": "https://github.com/IslamBaraka90/Fintech-EMA-Exponential-Moving-Average-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/ema/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A03",
      "name": "Weighted Moving Average (WMA)",
      "headline": "Newest-Heavy Linear Smoothing",
      "slug": "wma",
      "path": "technical-indicators/trend-smoothing/wma",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/wma",
        "entry": "calculateWma",
        "params": [
          "values",
          "window"
        ],
        "exports": [
          "calculateWma"
        ],
        "archetype": "series-transform",
        "signature": "calculateWma(values, window)"
      },
      "api": {
        "summary": "Linearly weighted mean over `window` observations: the most recent observation carries weight `window`, the oldest weight 1.",
        "params": [
          {
            "name": "values",
            "type": "(number | null)[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": "propagate",
            "default": null
          },
          {
            "name": "window",
            "type": "number",
            "required": true,
            "description": "Number of observations in the weighted mean.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "(number | null)[]",
          "length": "same-as-input",
          "description": "Weighted mean per position, `null` during warm-up."
        },
        "warmup": {
          "count": "window - 1",
          "value": "null",
          "note": "Warm-up positions are null rather than a partial result, so a consumer never mistakes an incomplete window for a real value."
        },
        "errors": [
          {
            "when": "window < 1 or is not an integer",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D07-F01-A03.json",
        "call": "calculateWma([10,13,12,15,14,18], 3)",
        "args": [
          {
            "value": [
              10,
              13,
              12,
              15,
              14,
              18
            ],
            "elided": null
          },
          {
            "value": 3,
            "elided": null
          }
        ],
        "output": [
          null,
          null,
          12,
          13.666666666666666,
          14,
          16.166666666666668
        ],
        "outputElided": null,
        "outputShape": "array of 6 nulls"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "wma-vs-sma.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a03/static/wma-vs-sma.svg"
          },
          {
            "file": "wma-weight-ladder.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a03/static/wma-weight-ladder.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "WMA calculation flow",
            "source": "flowchart TD\n    A[\"Accept ordered finite observation\"] --> B{\"At least n observations?\"}\n    B -- \"No\" --> C[\"Emit null · warming\"]\n    B -- \"Yes, first window\" --> D[\"Build U and L with weights 1 through n\"]\n    B -- \"Yes, later window\" --> E[\"Update L = prior L - prior U + n × incoming\"]\n    E --> F[\"Update U = prior U + incoming - outgoing\"]\n    D --> G[\"Divide L by n(n+1)/2\"]\n    F --> G\n    G --> H[\"Emit WMA · ready\"]"
          }
        ]
      },
      "references": [
        {
          "key": "S01",
          "title": "NIST Dataplot Weighted Mean",
          "author": null,
          "url": null
        },
        {
          "key": "S02",
          "title": "NumPy `average`",
          "author": null,
          "url": null
        },
        {
          "key": "S03",
          "title": "TradingView Moving Averages",
          "author": null,
          "url": null
        },
        {
          "key": "S04",
          "title": "TradingView Pine Script `ta.wma` reference",
          "author": null,
          "url": null
        },
        {
          "key": "S05",
          "title": "TA-Lib Functions",
          "author": null,
          "url": null
        },
        {
          "key": "S06",
          "title": "TA-Lib Generic Moving Average",
          "author": null,
          "url": null
        },
        {
          "key": "S07",
          "title": "TradingView Hull Moving Average",
          "author": null,
          "url": null
        },
        {
          "key": "S08",
          "title": "New York Fed Effective Federal Funds Rate data and API observation",
          "author": null,
          "url": null
        },
        {
          "key": "Claim map and implementation choices",
          "title": "Claim map and implementation choices",
          "author": null,
          "url": null
        },
        {
          "key": "Reproducibility notes",
          "title": "Reproducibility notes",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/wma/",
        "repo": "https://github.com/IslamBaraka90/Fintech-WMA-Weighted-Moving-Average-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/wma/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A04",
      "name": "Wilder RMA",
      "headline": "SMA-Seeded Alpha 1/n Smoothing",
      "slug": "wilder-rma",
      "path": "technical-indicators/trend-smoothing/wilder-rma",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/wilder-rma",
        "entry": "calculateRma",
        "params": [
          "values",
          "period"
        ],
        "exports": [
          "calculateRma"
        ],
        "archetype": "series-transform",
        "signature": "calculateRma(values, period)"
      },
      "api": {
        "summary": "Wilder's smoothing — an exponential mean with decay 1 / period rather than 2 / (period + 1). This is the smoother RSI, ATR and ADX are defined against, and substituting a standard EMA changes their published values.",
        "params": [
          {
            "name": "values",
            "type": "(number | null)[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": "propagate",
            "default": null
          },
          {
            "name": "period",
            "type": "number",
            "required": true,
            "description": "Wilder period; the decay factor is 1 / period.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "(number | null)[]",
          "length": "same-as-input",
          "description": "Smoothed series, `null` until the seed window closes."
        },
        "warmup": {
          "count": "period - 1",
          "value": "null",
          "note": "Warm-up positions are null rather than a partial result, so a consumer never mistakes an incomplete window for a real value."
        },
        "errors": [
          {
            "when": "period < 1 or is not an integer",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D07-F01-A04.json",
        "call": "calculateRma([10,13,12,15,14,18], 3)",
        "args": [
          {
            "value": [
              10,
              13,
              12,
              15,
              14,
              18
            ],
            "elided": null
          },
          {
            "value": 3,
            "elided": null
          }
        ],
        "output": [
          null,
          null,
          11.666666666666666,
          12.777777777777779,
          13.185185185185185,
          14.790123456790123
        ],
        "outputElided": null,
        "outputShape": "array of 6 nulls"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "nasdaq-composite-rma-example.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a04/static/nasdaq-composite-rma-example.svg"
          },
          {
            "file": "rma-step.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a04/static/rma-step.svg"
          },
          {
            "file": "rma-vs-ema.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a04/static/rma-vs-ema.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Wilder RMA calculation flow",
            "source": "flowchart LR\n    A[\"Validate ordered finite value\"] --> B{\"Count below period?\"}\n    B -- \"Yes\" --> C[\"Add to seed sum\"]\n    C --> D[\"Emit null: warming\"]\n    B -- \"No\" --> E{\"Count equals period?\"}\n    E -- \"Yes\" --> F[\"Seed = sum / period\"]\n    E -- \"No\" --> G[\"RMA = prior + (value - prior) / period\"]\n    F --> H[\"Emit full-precision RMA\"]\n    G --> H\n    H --> I[\"Persist state and provenance\"]"
          }
        ]
      },
      "references": [
        {
          "key": "RMA-01",
          "title": "New Concepts in Technical Trading Systems",
          "author": "J. Welles Wilder",
          "url": null
        },
        {
          "key": "RMA-02",
          "title": "TA-Lib classic RSI implementation",
          "author": "TA-Lib project; initial implementation credited to Mario Fortier",
          "url": null
        },
        {
          "key": "RMA-03",
          "title": "TC2000 RSI and Wilder's RSI methodology",
          "author": "TC2000 Software Company",
          "url": null
        },
        {
          "key": "RMA-04",
          "title": "TC2000 Average True Range methodology",
          "author": "TC2000 Software Company",
          "url": null
        },
        {
          "key": "RMA-05",
          "title": "TradingView Pine Script RMA reference",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "RMA-06",
          "title": "Nasdaq Trader Daily Market Files",
          "author": "Nasdaq, Inc.; Nasdaq Trader",
          "url": null
        },
        {
          "key": "Evidence and design reconciliation",
          "title": "Evidence and design reconciliation",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/wilder-rma/",
        "repo": "https://github.com/IslamBaraka90/Fintech-Wilder-RMA-Smoothing-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/wilder-rma/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A05",
      "name": "Double Exponential Moving Average (DEMA)",
      "headline": "Reduced Lag and Overshoot",
      "slug": "dema",
      "path": "technical-indicators/trend-smoothing/dema",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/dema",
        "entry": "calculateDemaComponents",
        "params": [
          "values",
          "span"
        ],
        "exports": [
          "calculateDemaComponents",
          "calculateDema",
          "demaSteadyStateWeights"
        ],
        "archetype": "series-transform",
        "signature": "calculateDemaComponents(values, span)"
      },
      "api": {
        "summary": "Double exponential moving average: `2 × EMA − EMA(EMA)`. Subtracting the second smoothing pass cancels most of the lag a single EMA introduces, at the cost of overshooting sharp reversals.",
        "params": [
          {
            "name": "values",
            "type": "(number | null)[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": "propagate",
            "default": null
          },
          {
            "name": "span",
            "type": "number",
            "required": true,
            "description": "Smoothing span used for both EMA passes; the decay factor is 2 / (span + 1).",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ema1, ema2, dema }[]",
          "length": "same-as-input",
          "description": "One record per position carrying both intermediate EMAs alongside the result, so the cancellation can be checked rather than taken on trust."
        },
        "warmup": {
          "count": "2 × (span − 1)",
          "value": "null",
          "note": "Both passes must fill before the difference is defined."
        },
        "errors": [
          {
            "when": "span < 1 or is not an integer",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D07-F01-A05.json",
        "call": "calculateDemaComponents([10,13,12,15,14,18], 3)",
        "args": [
          {
            "value": [
              10,
              13,
              12,
              15,
              14,
              18
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 8
            }
          },
          {
            "value": 3,
            "elided": null
          }
        ],
        "output": {
          "4": {
            "dema": 14.444444444444445,
            "status": "ready"
          },
          "5": {
            "dema": 17.305555555555557,
            "status": "ready"
          },
          "6": {
            "dema": 17.444444444444443,
            "status": "ready"
          },
          "7": {
            "dema": 19.618055555555557,
            "status": "ready"
          }
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: 4, 5, 6, 7"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "dema-components.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a05/static/dema-components.svg"
          },
          {
            "file": "dema-path.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a05/static/dema-path.svg"
          },
          {
            "file": "dema-signed-weights.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a05/static/dema-signed-weights.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "DEMA calculation flow",
            "source": "flowchart LR\n    A[\"Validate ordered finite value\"] --> B[\"Update or seed EMA1\"]\n    B --> C{\"EMA1 ready?\"}\n    C -- \"No\" --> D[\"Emit warming EMA1\"]\n    C -- \"Yes\" --> E[\"Feed EMA1 into EMA2\"]\n    E --> F{\"EMA2 ready?\"}\n    F -- \"No\" --> G[\"Emit warming EMA2\"]\n    F -- \"Yes\" --> H[\"Calculate 2 × EMA1 − EMA2\"]\n    H --> I[\"Emit ready DEMA and component states\"]"
          }
        ]
      },
      "references": [
        {
          "key": "DEMA-01",
          "title": "Smoothing Data With Faster Moving Averages",
          "author": "Patrick G. Mulloy; *Technical Analysis of Stocks & Commodities*",
          "url": null
        },
        {
          "key": "DEMA-02",
          "title": "TA-Lib DEMA definition",
          "author": "TA-Lib project",
          "url": null
        },
        {
          "key": "DEMA-03",
          "title": "Follow-up discussion of equivalent period",
          "author": "Letter published by *Technical Analysis of Stocks & Commodities*",
          "url": null
        },
        {
          "key": "DEMA-04",
          "title": "EMA foundation package",
          "author": "The Fintech Builder",
          "url": null
        },
        {
          "key": "Evidence and design reconciliation",
          "title": "Evidence and design reconciliation",
          "author": null,
          "url": null
        },
        {
          "key": "Historical-case publication boundary",
          "title": "Historical-case publication boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/dema/",
        "repo": "https://github.com/IslamBaraka90/Fintech-DEMA-Double-Exponential-Moving-Average-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/dema/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A06",
      "name": "Triple Exponential Moving Average (TEMA)",
      "headline": "Layered Warm-Up and Signed Weights",
      "slug": "tema",
      "path": "technical-indicators/trend-smoothing/tema",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/tema",
        "entry": "calculateTemaComponents",
        "params": [
          "values",
          "span"
        ],
        "exports": [
          "calculateTemaComponents",
          "calculateTema",
          "temaSteadyStateWeight"
        ],
        "archetype": "series-transform",
        "signature": "calculateTemaComponents(values, span)"
      },
      "api": {
        "summary": "Triple exponential moving average: `3 × EMA − 3 × EMA(EMA) + EMA(EMA(EMA))`. More lag cancellation than DEMA, and correspondingly more overshoot.",
        "params": [
          {
            "name": "values",
            "type": "(number | null)[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": "propagate",
            "default": null
          },
          {
            "name": "span",
            "type": "number",
            "required": true,
            "description": "Smoothing span used for all three EMA passes; the decay factor is 2 / (span + 1).",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ema1, ema2, ema3, tema }[]",
          "length": "same-as-input",
          "description": "One record per position carrying all three intermediate EMAs alongside the result."
        },
        "warmup": {
          "count": "3 × (span − 1)",
          "value": "null",
          "note": "All three passes must fill before the combination is defined."
        },
        "errors": [
          {
            "when": "span < 1 or is not an integer",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D07-F01-A06.json",
        "call": "calculateTemaComponents([10,13,12,15,14,18], 3)",
        "args": [
          {
            "value": [
              10,
              13,
              12,
              15,
              14,
              18
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 10
            }
          },
          {
            "value": 3,
            "elided": null
          }
        ],
        "output": {
          "6": {
            "ema1": 16.416666666666664,
            "ema2": 15.388888888888888,
            "ema3": 14.212962962962962,
            "tema": 17.29629629629629,
            "status": "ready"
          },
          "7": {
            "tema": 19.73495370370371,
            "status": "ready"
          },
          "8": {
            "tema": 19.311921296296298,
            "status": "ready"
          },
          "9": {
            "tema": 21.703703703703713,
            "status": "ready"
          }
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: 6, 7, 8, 9"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "tema-components.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a06/static/tema-components.svg"
          },
          {
            "file": "tema-effective-weights.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a06/static/tema-effective-weights.svg"
          },
          {
            "file": "tema-path.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a06/static/tema-path.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "TEMA calculation flow",
            "source": "flowchart LR\n    A[\"Validate ordered finite value\"] --> B[\"Seed or update EMA1\"]\n    B --> C{\"EMA1 ready?\"}\n    C -- \"No\" --> D[\"Emit warming EMA1\"]\n    C -- \"Yes\" --> E[\"Feed EMA1 into EMA2\"]\n    E --> F[\"Seed or update EMA2\"]\n    F --> G{\"EMA2 ready?\"}\n    G -- \"No\" --> H[\"Emit warming EMA2\"]\n    G -- \"Yes\" --> I[\"Feed EMA2 into EMA3\"]\n    I --> J[\"Seed or update EMA3\"]\n    J --> K{\"EMA3 ready?\"}\n    K -- \"No\" --> L[\"Emit warming EMA3\"]\n    K -- \"Yes\" --> M[\"Calculate EMA3 + 3 × (EMA1 − EMA2)\"]\n    M --> N[\"Emit ready components and TEMA\"]"
          }
        ]
      },
      "references": [
        {
          "key": "TEMA-01",
          "title": "Smoothing Data With Faster Moving Averages",
          "author": "Patrick G. Mulloy; *Technical Analysis of Stocks & Commodities*",
          "url": null
        },
        {
          "key": "TEMA-02",
          "title": "Smoothing Data With Less Lag",
          "author": "Patrick G. Mulloy; *Technical Analysis of Stocks & Commodities*",
          "url": null
        },
        {
          "key": "TEMA-03",
          "title": "TA-Lib TEMA definition and reference implementation",
          "author": "TA-Lib project",
          "url": null
        },
        {
          "key": "TEMA-04",
          "title": "TC2000 TEMA methodology",
          "author": "Worden / TC2000",
          "url": null
        },
        {
          "key": "TEMA-05",
          "title": "Local EMA and DEMA foundation",
          "author": "The Fintech Builder",
          "url": null
        },
        {
          "key": "Evidence and design reconciliation",
          "title": "Evidence and design reconciliation",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/tema/",
        "repo": "https://github.com/IslamBaraka90/Fintech-TEMA-Triple-Exponential-Moving-Average-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/tema/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A07",
      "name": "Hull MA",
      "headline": null,
      "slug": "hull-ma",
      "path": "technical-indicators/trend-smoothing/hull-ma",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/hull-ma",
        "entry": "calculateHullMa",
        "params": [
          "values",
          "window"
        ],
        "exports": [
          "calculateHullMa"
        ],
        "archetype": "series-transform",
        "signature": "calculateHullMa(values, window)"
      },
      "api": {
        "summary": "Hull moving average: a weighted combination of two WMAs de-lagged against each other, then re-smoothed over sqrt(window). Far more responsive than an SMA of the same length, at the cost of overshoot.",
        "params": [
          {
            "name": "values",
            "type": "(number | null)[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": "propagate",
            "default": null
          },
          {
            "name": "window",
            "type": "number",
            "required": true,
            "description": "Base window; the internal halved window and the sqrt(window) smoothing window derive from it.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "(number | null)[]",
          "length": "same-as-input",
          "description": "Smoothed series, `null` during the combined warm-up of all three stages."
        },
        "warmup": {
          "count": "window + ceil(sqrt(window)) - 2",
          "value": "null",
          "note": "Warm-up positions are null rather than a partial result, so a consumer never mistakes an incomplete window for a real value."
        },
        "errors": [
          {
            "when": "window < 1 or is not an integer",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculateHullMa([10,13,12,15,14,18], 5)",
        "args": [
          {
            "value": [
              10,
              13,
              12,
              15,
              14,
              18
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 10
            }
          },
          {
            "value": 5,
            "elided": null
          }
        ],
        "output": {
          "halfLength": 2,
          "rootLength": 2,
          "shortWma": [
            null,
            12,
            12.333333333333334,
            14,
            14.333333333333334,
            16.666666666666668
          ],
          "longWma": [
            null,
            null,
            null,
            null,
            13.466666666666667,
            15.2
          ],
          "rawHull": [
            null,
            null,
            null,
            null,
            15.200000000000001,
            18.133333333333336
          ],
          "hullMa": [
            null,
            null,
            null,
            null,
            null,
            17.15555555555556
          ]
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: halfLength, rootLength, shortWma, longWma, rawHull, hullMa"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "hull-pipeline.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a07/static/hull-pipeline.svg"
          },
          {
            "file": "hull-response.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a07/static/hull-response.svg"
          },
          {
            "file": "hull-signed-weights.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a07/static/hull-signed-weights.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Hull MA calculation flow",
            "source": "flowchart TD\n    A[\"Validated ordered source x(t)\"] --> B[\"Short WMA: h = floor(n / 2)\"]\n    A --> C[\"Long WMA: n observations\"]\n    B --> D{\"Both WMAs ready?\"}\n    C --> D\n    D -- \"No\" --> E[\"Emit aligned null raw value\"]\n    D -- \"Yes\" --> F[\"Raw Hull: R(t) = 2 × short − long\"]\n    F --> G[\"Collect r = floor(sqrt(n)) consecutive raw values\"]\n    G --> H{\"Final WMA window ready?\"}\n    H -- \"No\" --> I[\"Emit aligned null HMA\"]\n    H -- \"Yes\" --> J[\"HMA(t) = WMA(r) of raw Hull\"]\n    J --> K[\"Publish components, lengths, policy, and provenance\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Primary definition",
          "title": "Primary definition",
          "author": null,
          "url": null
        },
        {
          "key": "Independent confirmations",
          "title": "Independent confirmations",
          "author": null,
          "url": null
        },
        {
          "key": "Canonical decisions",
          "title": "Canonical decisions",
          "author": null,
          "url": null
        },
        {
          "key": "Independent derivations",
          "title": "Independent derivations",
          "author": null,
          "url": null
        },
        {
          "key": "Historical-example evidence gate",
          "title": "Historical-example evidence gate",
          "author": null,
          "url": null
        },
        {
          "key": "Non-claims",
          "title": "Non-claims",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/hull-ma/",
        "repo": "https://github.com/IslamBaraka90/Fintech-HMA-Hull-Moving-Average-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/hull-ma/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A08",
      "name": "Kaufman Adaptive Moving Average (KAMA)",
      "headline": null,
      "slug": "kama",
      "path": "technical-indicators/trend-smoothing/kama",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/kama",
        "entry": "calculateKama",
        "params": [
          "values",
          "efficiencyPeriod",
          "fastPeriod",
          "slowPeriod"
        ],
        "exports": [
          "calculateKama"
        ],
        "archetype": "series-transform",
        "signature": "calculateKama(values, efficiencyPeriod, fastPeriod, slowPeriod)"
      },
      "api": {
        "summary": "Kaufman adaptive moving average. The smoothing constant moves between a fast and a slow bound according to an efficiency ratio — directional travel divided by total travel — so the average tightens in a trend and loosens in noise.",
        "params": [
          {
            "name": "values",
            "type": "(number | null)[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": "propagate",
            "default": null
          },
          {
            "name": "efficiencyPeriod",
            "type": "number",
            "required": true,
            "description": "Lookback over which the efficiency ratio is measured.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "fastPeriod",
            "type": "number",
            "required": true,
            "description": "Period defining the fast bound of the smoothing constant; reached when the series is perfectly directional.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "slowPeriod",
            "type": "number",
            "required": true,
            "description": "Period defining the slow bound; reached when the series is pure noise.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `efficiencyRatio`, `blendedAlpha`, `smoothingConstant` and `kama`, so the adaptation itself is inspectable rather than hidden inside the result."
        },
        "warmup": {
          "count": "efficiencyPeriod",
          "value": "null",
          "note": "The efficiency ratio needs a full lookback before the constant is defined."
        },
        "errors": [
          {
            "when": "any period is < 1, is not an integer, or fastPeriod ≥ slowPeriod",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculateKama([100,101,102,103,104,103], 10, 2, 30)",
        "args": [
          {
            "value": [
              100,
              101,
              102,
              103,
              104,
              103
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 16
            }
          },
          {
            "value": 10,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          },
          {
            "value": 30,
            "elided": null
          }
        ],
        "output": {
          "efficiencyRatio": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "blendedAlpha": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "smoothingConstant": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "kama": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: efficiencyRatio, blendedAlpha, smoothingConstant, kama"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "adaptive-smoother-choice.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a08/static/adaptive-smoother-choice.svg"
          },
          {
            "file": "article-hero.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a08/static/article-hero.svg"
          },
          {
            "file": "calculation-pipeline.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a08/static/calculation-pipeline.svg"
          },
          {
            "file": "data-integrity.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a08/static/data-integrity.svg"
          },
          {
            "file": "path-efficiency.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a08/static/path-efficiency.svg"
          },
          {
            "file": "regime-dashboard.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a08/static/regime-dashboard.svg"
          },
          {
            "file": "response-curve.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a08/static/response-curve.svg"
          },
          {
            "file": "seed-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a08/static/seed-timeline.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "KAMA calculation flow",
            "source": "flowchart LR\n    A[\"Validated, ordered prices\"] --> B{\"At least E + 1 observations?\"}\n    B -- \"No\" --> C[\"Return not ready\"]\n    B -- \"Yes\" --> D[\"Change: absolute E-bar displacement\"]\n    D --> E[\"Path length: sum of absolute one-bar moves\"]\n    E --> F{\"Path length is zero?\"}\n    F -- \"Yes\" --> G[\"Efficiency ratio = 1\"]\n    F -- \"No\" --> H[\"Efficiency ratio = change / path\"]\n    G --> I[\"Blend fast and slow alpha\"]\n    H --> I\n    I --> J[\"Square alpha to obtain SC\"]\n    J --> K[\"Update from previous KAMA toward current price\"]\n    K --> L[\"Publish ER, SC, and KAMA\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R01",
          "title": "Smarter Trading: Improving Performance in Changing Markets",
          "author": "Perry J. Kaufman; McGraw-Hill Professional",
          "url": "https://books.google.com/books/about/Smarter_Trading.html?id=ndq_21wRJjEC"
        },
        {
          "key": "R02",
          "title": "Adaptive Techniques",
          "author": "Perry J. Kaufman; Wiley",
          "url": "https://doi.org/10.1002/9781119202561.ch17"
        },
        {
          "key": "R03",
          "title": "TradingView official KAMA documentation",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000773012-kaufman-s-adaptive-moving-average-kama/"
        },
        {
          "key": "R04",
          "title": "TA-Lib official KAMA function page",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/kama.html"
        },
        {
          "key": "R05",
          "title": "TA-Lib pinned KAMA C implementation",
          "author": "TA-Lib project",
          "url": "https://raw.githubusercontent.com/TA-Lib/ta-lib/e203f7c436a9c21fd08246661971cfcb7ee37517/src/ta_func/ta_KAMA.c"
        },
        {
          "key": "R06",
          "title": "QuantConnect LEAN pinned KAMA implementation",
          "author": "QuantConnect",
          "url": "https://raw.githubusercontent.com/QuantConnect/Lean/cd52034ddf55c0c9aa57264d2a148e563924100f/Indicators/KaufmanAdaptiveMovingAverage.cs"
        },
        {
          "key": "R07",
          "title": "QuantConnect LEAN pinned Efficiency Ratio implementation",
          "author": "QuantConnect",
          "url": "https://raw.githubusercontent.com/QuantConnect/Lean/cd52034ddf55c0c9aa57264d2a148e563924100f/Indicators/KaufmanEfficiencyRatio.cs"
        },
        {
          "key": "R08",
          "title": "Tulip Indicators pinned KAMA implementation",
          "author": "Tulip Charts / Tulip Indicators",
          "url": "https://raw.githubusercontent.com/TulipCharts/tulipindicators/be18abb13e075ba866898dcc7cb52399603302a6/indicators/kama.c"
        },
        {
          "key": "R09",
          "title": "Canonical package calculations",
          "author": "The Fintech Builder",
          "url": null
        },
        {
          "key": "R10",
          "title": "Playground scenario dataset",
          "author": "The Fintech Builder",
          "url": null
        },
        {
          "key": "Historical-example evidence gate",
          "title": "Historical-example evidence gate",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/kama/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/kama/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F01-A09",
      "name": "MESA Adaptive Moving Average (MAMA)",
      "headline": null,
      "slug": "mama",
      "path": "technical-indicators/trend-smoothing/mama",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F01",
        "family": "Trend Smoothing",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-smoothing/mama",
        "entry": "mama",
        "params": [
          "values",
          "fastLimit",
          "slowLimit"
        ],
        "exports": [
          "mama"
        ],
        "archetype": "series-transform",
        "signature": "mama(values, fastLimit, slowLimit)"
      },
      "api": {
        "summary": "MESA adaptive moving average. A Hilbert transform estimates the dominant cycle period of the series, and the smoothing rate follows the rate of phase change — so the average adapts to cycle length rather than to a fixed window.",
        "params": [
          {
            "name": "values",
            "type": "(number | null)[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": "propagate",
            "default": null
          },
          {
            "name": "fastLimit",
            "type": "number",
            "required": false,
            "description": "Upper bound on the adaptive smoothing factor.",
            "constraints": {
              "min": 0,
              "max": 1
            },
            "nulls": null,
            "default": 0.5
          },
          {
            "name": "slowLimit",
            "type": "number",
            "required": false,
            "description": "Lower bound on the adaptive smoothing factor.",
            "constraints": {
              "min": 0,
              "max": 1
            },
            "nulls": null,
            "default": 0.05
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Every stage of the transform as a parallel series — `smooth`, `detrender`, the in-phase and quadrature components, `period`, `phase`, `mama` and `fama` — because the intermediate values are the only way to diagnose a suspicious result."
        },
        "warmup": {
          "count": "6",
          "value": "null",
          "note": "The Hilbert transform needs six bars of history before its output is meaningful."
        },
        "errors": [
          {
            "when": "fastLimit or slowLimit falls outside 0…1, or slowLimit > fastLimit",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "mama([100,100.517638,101,101.414214,101.732051,101.931852])",
        "args": [
          {
            "value": [
              100,
              100.517638,
              101,
              101.414214,
              101.732051,
              101.931852
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 144
            }
          }
        ],
        "output": {
          "smooth": [
            null,
            null,
            null,
            100.96921320000001,
            101.3688484,
            101.67519890000001
          ],
          "detrender": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "i1": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "q1": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "i2": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "q2": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "re": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "im": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "period": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "phase": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "deltaPhase": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "alpha": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "mama": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "fama": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 14 fields: smooth, detrender, i1, q1, i2, q2, re, im, …"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "adaptive-smoother-choice.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a09/static/adaptive-smoother-choice.svg"
          },
          {
            "file": "mama-alpha-transfer.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a09/static/mama-alpha-transfer.svg"
          },
          {
            "file": "mama-phase-wrap.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a09/static/mama-phase-wrap.svg"
          },
          {
            "file": "mama-ratchet-trace.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a09/static/mama-ratchet-trace.svg"
          },
          {
            "file": "mama-signal-pipeline.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a09/static/mama-signal-pipeline.svg"
          },
          {
            "file": "mama-warmup-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d07-f01-a09/static/mama-warmup-timeline.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "MAMA state flow",
            "source": "flowchart LR\n    P[\"Declared price source\"] --> W[\"4-bar weighted smoother\"]\n    W --> H[\"Hilbert FIR states\"]\n    H --> IQ[\"I1 and Q1\"]\n    IQ --> PH[\"Signed phase change\"]\n    PH --> A[\"Bounded adaptive alpha\"]\n    P --> M[\"MAMA: alpha on price\"]\n    A --> M\n    M --> F[\"FAMA: alpha / 2 on MAMA\"]\n    IQ --> D[\"I2/Q2 homodyne discriminator\"]\n    D --> R[\"Bounded period state\"]\n    R --> H"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "MESA Adaptive Moving Averages",
          "author": "John F. Ehlers; *Technical Analysis of Stocks &",
          "url": "https://traders.com/documentation/feedbk_docs/2001/09/Abstracts_new/Ehlers/ehlers.html"
        },
        {
          "key": "R2",
          "title": "MAMA: The Mother of Adaptive Moving Averages",
          "author": "John F. Ehlers",
          "url": "https://c.mql5.com/forextsd/forum/157/mesa_adaptive_moving_average_mama.pdf"
        },
        {
          "key": "R3",
          "title": "Pinned TA-Lib MAMA source of truth",
          "author": "TA-Lib project",
          "url": "https://github.com/TA-Lib/ta-lib/blob/65093f3dc37a62e176c38329b550d5aab5775133/ta_codegen/input/mama/mama.c"
        },
        {
          "key": "R4",
          "title": "Official TA-Lib MAMA function page",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/functions/mama"
        },
        {
          "key": "R5",
          "title": "TA-Lib MAMA metadata",
          "author": "TA-Lib project",
          "url": "https://github.com/TA-Lib/ta-lib/blob/main/ta_codegen/input/mama/mama.yaml"
        },
        {
          "key": "R6",
          "title": "Rocket Science for Traders",
          "author": "John F. Ehlers; John Wiley & Sons",
          "url": "https://books.google.com/books/about/Rocket_Science_for_Traders.html?id=_KjOT1b9bfUC"
        },
        {
          "key": "R7",
          "title": "TA-Lib API: unstable periods",
          "author": "TA-Lib project",
          "url": "https://ta-lib.org/api/?h=unstable"
        },
        {
          "key": "R8",
          "title": "QuantConnect MESA Adaptive Moving Average documentation",
          "author": "QuantConnect",
          "url": "https://www.quantconnect.com/docs/v2/writing-algorithms/indicators/supported-indicators/mesa-adaptive-moving-average"
        },
        {
          "key": "R9",
          "title": "Canonical package calculations",
          "author": "The Fintech Builder topic package",
          "url": null
        },
        {
          "key": "Source and derived boundary",
          "title": "Source and derived boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-smoothing/mama/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-smoothing/mama/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A01",
      "name": "MACD",
      "headline": "Read the Spreads Before You Read the Signals",
      "slug": "macd",
      "path": "technical-indicators/trend-systems/macd",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/macd",
        "entry": "macd",
        "params": [
          "values",
          "fastSpan",
          "slowSpan",
          "signalSpan"
        ],
        "exports": [
          "macd"
        ],
        "archetype": "series-transform",
        "signature": "macd(values, fastSpan, slowSpan, signalSpan)"
      },
      "api": {
        "summary": "Moving average convergence/divergence: the gap between a fast and a slow EMA, its own EMA as a signal line, and the difference between them as a histogram.",
        "params": [
          {
            "name": "values",
            "type": "(number | null)[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": "propagate",
            "default": null
          },
          {
            "name": "fastSpan",
            "type": "number",
            "required": true,
            "description": "Span of the fast EMA.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "slowSpan",
            "type": "number",
            "required": true,
            "description": "Span of the slow EMA; must exceed the fast span.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "signalSpan",
            "type": "number",
            "required": true,
            "description": "Span of the EMA taken over the MACD line itself.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ fast_ema, slow_ema, macd, signal, histogram }[]",
          "length": "same-as-input",
          "description": "One record per position carrying both EMAs alongside the three published series."
        },
        "warmup": {
          "count": "slowSpan − 1 for the MACD line, and slowSpan + signalSpan − 2 for the signal and histogram",
          "value": "null",
          "note": "The signal line is an average *of* the MACD line, so it is defined strictly later — plotting the two without allowing for that misaligns them."
        },
        "errors": [
          {
            "when": "any span is < 1, is not an integer, or fastSpan ≥ slowSpan",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D07-F02-A01.json",
        "call": "macd([10,11,12,13,14,15], 3, 5, 3)",
        "args": [
          {
            "value": [
              10,
              11,
              12,
              13,
              14,
              15
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 14
            }
          },
          {
            "value": 3,
            "elided": null
          },
          {
            "value": 5,
            "elided": null
          },
          {
            "value": 3,
            "elided": null
          }
        ],
        "output": {
          "4": {
            "fastEma": 13,
            "slowEma": 12,
            "macd": 1,
            "signal": null,
            "histogram": null,
            "status": "warming_signal"
          },
          "6": {
            "fastEma": 15,
            "slowEma": 14,
            "macd": 1,
            "signal": 1,
            "histogram": 0,
            "status": "ready"
          },
          "7": {
            "fastEma": 15,
            "slowEma": 14.333333333333334,
            "macd": 0.6666666666666661,
            "signal": 0.833333333333333,
            "histogram": -0.16666666666666696,
            "status": "ready"
          },
          "9": {
            "macd": -0.06481481481481488,
            "signal": 0.24537037037037002,
            "histogram": -0.3101851851851849,
            "status": "ready"
          },
          "12": {
            "macd": 0.2088048696844993,
            "signal": 0.04260973936899856,
            "histogram": 0.16619513031550073,
            "status": "ready"
          }
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: 4, 6, 7, 9, 12"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "ema-gap.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a01/static/ema-gap.svg"
          },
          {
            "file": "macd-machine.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a01/static/macd-machine.svg"
          },
          {
            "file": "scale-trap.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a01/static/scale-trap.svg"
          },
          {
            "file": "signal-cross.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a01/static/signal-cross.svg"
          },
          {
            "file": "three-panel-path.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a01/static/three-panel-path.svg"
          },
          {
            "file": "warmup-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a01/static/warmup-timeline.svg"
          },
          {
            "file": "whipsaw-range.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a01/static/whipsaw-range.svg"
          },
          {
            "file": "zero-cross.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a01/static/zero-cross.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Calculation flow",
            "source": "flowchart LR\n    X[\"Ordered finite source values\"] --> F[\"Fast SMA-seeded EMA\"]\n    X --> S[\"Slow SMA-seeded EMA\"]\n    F --> D{\"Both EMAs ready?\"}\n    S --> D\n    D -->|No| W[\"MACD unavailable\"]\n    D -->|Yes| M[\"MACD = fast EMA - slow EMA\"]\n    M --> G[\"Signal = SMA-seeded EMA of MACD\"]\n    M --> H[\"Histogram = MACD - signal\"]\n    G --> H\n    H --> O[\"Aligned component row\"]"
          },
          {
            "file": "state-lifecycle.md",
            "caption": "State lifecycle",
            "source": "stateDiagram-v2\n    [*] --> WarmingPriceEMAs\n    WarmingPriceEMAs --> WarmingSignal: \"slow_span observations\"\n    WarmingSignal --> Ready: \"signal_span MACD values\"\n    Ready --> Ready: \"append one finalized observation\"\n    Ready --> RecomputedSuffix: \"revise a historical observation\"\n    RecomputedSuffix --> Ready: \"replace affected suffix\""
          }
        ]
      },
      "references": [
        {
          "key": "Primary and authoritative sources",
          "title": "Primary and authoritative sources",
          "author": null,
          "url": null
        },
        {
          "key": "Claims derived algebraically in this package",
          "title": "Claims derived algebraically in this package",
          "author": null,
          "url": null
        },
        {
          "key": "Historical and interpretive caution",
          "title": "Historical and interpretive caution",
          "author": null,
          "url": null
        },
        {
          "key": "Reproducibility",
          "title": "Reproducibility",
          "author": null,
          "url": null
        },
        {
          "key": "Historical example decision",
          "title": "Historical example decision",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/macd/",
        "repo": "https://github.com/IslamBaraka90/Fintech-MACD-Moving-Average-Convergence-Divergence-algorithm",
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/macd/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A02",
      "name": "Percentage Price Oscillator (PPO)",
      "headline": "Normalize the MACD Spread",
      "slug": "percentage-price-oscillator",
      "path": "technical-indicators/trend-systems/percentage-price-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/percentage-price-oscillator",
        "entry": "ppo",
        "params": [
          "values",
          "fastSpan",
          "slowSpan",
          "signalSpan"
        ],
        "exports": [
          "ppo"
        ],
        "archetype": "series-transform",
        "signature": "ppo(values, fastSpan, slowSpan, signalSpan)"
      },
      "api": {
        "summary": "MACD expressed as a percentage of the slow EMA rather than in price units, which makes readings comparable across instruments and across time in a way MACD is not.",
        "params": [
          {
            "name": "values",
            "type": "(number | null)[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": "propagate",
            "default": null
          },
          {
            "name": "fastSpan",
            "type": "number",
            "required": true,
            "description": "Span of the fast EMA.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "slowSpan",
            "type": "number",
            "required": true,
            "description": "Span of the slow EMA; must exceed the fast span.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "signalSpan",
            "type": "number",
            "required": true,
            "description": "Span of the EMA taken over the PPO line itself.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `fast_ema`, `slow_ema`, `ppo`, `signal` and `histogram`."
        },
        "warmup": {
          "count": "slowSpan − 1 for the PPO line, and slowSpan + signalSpan − 2 for the signal and histogram",
          "value": "null",
          "note": "As with MACD, the signal line is defined later than the line it smooths."
        },
        "errors": [
          {
            "when": "any span is < 1, is not an integer, or fastSpan ≥ slowSpan",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "ppo([96.42,96.948156,97.568602,98.255035,98.973258,99.68459], 12, 26, 9)",
        "args": [
          {
            "value": [
              96.42,
              96.948156,
              97.568602,
              98.255035,
              98.973258,
              99.68459
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 180
            }
          },
          {
            "value": 12,
            "elided": null
          },
          {
            "value": 26,
            "elided": null
          },
          {
            "value": 9,
            "elided": null
          }
        ],
        "output": {
          "fast_ema": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "slow_ema": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "ppo": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "signal": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "histogram": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: fast_ema, slow_ema, ppo, signal, histogram"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "canonical-trace.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a02/static/canonical-trace.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a02/static/failure-boundary.svg"
          },
          {
            "file": "mechanism-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a02/static/mechanism-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Percentage Price Oscillator calculation flow",
            "source": "flowchart LR\n    A[\"Validated finalized bar\"] --> B[\"Causal window or recursive state\"]\n    B --> C[\"Explicit seed and boundary rule\"]\n    C --> D[\"Aligned Percentage Price Oscillator output\"]\n    D --> E[\"Diagnostics and audit evidence\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "Gerald Appel's MACD/PPO work",
          "author": "Gerald Appel's MACD/PPO work",
          "url": "https://search.worldcat.org/search?q=au%3AAppel%2C+Gerald"
        },
        {
          "key": "R2",
          "title": "TA-Lib PPO",
          "author": "TA-Lib project or TradingView, as identified by the linked page",
          "url": "https://ta-lib.org/functions/ppo"
        },
        {
          "key": "R3",
          "title": "Pinned TA-Lib ta_PPO.c implementation",
          "author": "TA-Lib project or TradingView",
          "url": "https://github.com/TA-Lib/ta-lib/blob/e203f7c436a9c21fd08246661971cfcb7ee37517/src/ta_func/ta_PPO.c"
        },
        {
          "key": "R4",
          "title": "Canonical synthetic fixture and independent arithmetic",
          "author": "The Fintech Builder",
          "url": null
        },
        {
          "key": "R5 â€” TA-Lib MACD function documentation",
          "title": "R5 â€” TA-Lib MACD function documentation",
          "author": "TA-Lib project or TradingView",
          "url": "https://ta-lib.org/functions/macd"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/percentage-price-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/percentage-price-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A03",
      "name": "Aroon Up, Down, and Oscillator",
      "headline": "Measure Extreme Recency",
      "slug": "aroon",
      "path": "technical-indicators/trend-systems/aroon",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/aroon",
        "entry": "aroon",
        "params": [
          "high",
          "low",
          "period"
        ],
        "exports": [
          "aroon"
        ],
        "archetype": "series-transform",
        "signature": "aroon(high, low, period)"
      },
      "api": {
        "summary": "Measures how recently the highest high and lowest low occurred within the lookback, expressed as 0–100. Unlike most trend indicators it reads *elapsed time* rather than price distance.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "period",
            "type": "number",
            "required": true,
            "description": "Lookback in bars for the extreme search.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `aroon_up`, `aroon_down`, and the `oscillator` difference between them."
        },
        "warmup": {
          "count": "period",
          "value": "null",
          "note": "A full lookback is required before an extreme can be located."
        },
        "errors": [
          {
            "when": "period < 1 or is not an integer",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "aroon([101.415,102.06264,102.772785,103.494002,104.181554,104.803509], [99.3245,99.468834,99.976055,100.625352,101.389232,102.216086], 25)",
        "args": [
          {
            "value": [
              101.415,
              102.06264,
              102.772785,
              103.494002,
              104.181554,
              104.803509
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 180
            }
          },
          {
            "value": [
              99.3245,
              99.468834,
              99.976055,
              100.625352,
              101.389232,
              102.216086
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 180
            }
          },
          {
            "value": 25,
            "elided": null
          }
        ],
        "output": {
          "aroon_up": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "aroon_down": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "oscillator": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: aroon_up, aroon_down, oscillator"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "canonical-trace.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a03/static/canonical-trace.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a03/static/failure-boundary.svg"
          },
          {
            "file": "mechanism-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a03/static/mechanism-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Aroon calculation flow",
            "source": "flowchart LR\n    A[\"Validated finalized bar\"] --> B[\"Causal window or recursive state\"]\n    B --> C[\"Explicit seed and boundary rule\"]\n    C --> D[\"Aligned Aroon output\"]\n    D --> E[\"Diagnostics and audit evidence\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "Tushar Chande's 1995 Aroon article",
          "author": "Tushar Chande's 1995 Aroon article",
          "url": "https://traders.com/documentation/feedbk_docs/1995/09/Abstracts_new/Chande/Chande.html"
        },
        {
          "key": "R2",
          "title": "TA-Lib AROON",
          "author": "TA-Lib project or TradingView, as identified by the linked page",
          "url": "https://ta-lib.org/functions/aroon"
        },
        {
          "key": "R3",
          "title": "Pinned TA-Lib ta_AROON.c implementation",
          "author": "TA-Lib project or TradingView",
          "url": "https://github.com/TA-Lib/ta-lib/blob/e203f7c436a9c21fd08246661971cfcb7ee37517/src/ta_func/ta_AROON.c"
        },
        {
          "key": "R4",
          "title": "Canonical synthetic fixture and independent arithmetic",
          "author": "The Fintech Builder",
          "url": null
        },
        {
          "key": "R5 â€” TA-Lib AROONOSC function documentation",
          "title": "R5 â€” TA-Lib AROONOSC function documentation",
          "author": "TA-Lib project or TradingView",
          "url": "https://ta-lib.org/functions/aroonosc"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/aroon/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/aroon/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A04",
      "name": "Directional Movement",
      "headline": "From True Range to +DI, −DI, and DX",
      "slug": "directional-movement",
      "path": "technical-indicators/trend-systems/directional-movement",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/directional-movement",
        "entry": "directionalMovement",
        "params": [
          "high",
          "low",
          "close",
          "period"
        ],
        "exports": [
          "directionalMovement"
        ],
        "archetype": "series-transform",
        "signature": "directionalMovement(high, low, close, period)"
      },
      "api": {
        "summary": "The components beneath ADX: directional movement in each direction, Wilder-smoothed, divided by the average true range to give +DI and −DI.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "period",
            "type": "number",
            "required": true,
            "description": "Wilder smoothing period.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Every intermediate as a parallel series — `true_range`, `plus_dm`, `minus_dm`, their smoothed forms, `atr`, `plus_di`, `minus_di` and `dx`."
        },
        "warmup": {
          "count": "period",
          "value": "null",
          "note": "Wilder smoothing seeds on the first full window."
        },
        "errors": [
          {
            "when": "period < 1 or is not an integer",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "directionalMovement([105.45,106.10084,106.816229,107.542653,108.232784,108.852128], [103.293,103.437436,103.948153,104.603166,105.372863,106.203002], [104.42,104.954567,105.585587,106.282695,107.006608,107.713561], 14)",
        "args": [
          {
            "value": [
              105.45,
              106.10084,
              106.816229,
              107.542653,
              108.232784,
              108.852128
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 180
            }
          },
          {
            "value": [
              103.293,
              103.437436,
              103.948153,
              104.603166,
              105.372863,
              106.203002
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 180
            }
          },
          {
            "value": [
              104.42,
              104.954567,
              105.585587,
              106.282695,
              107.006608,
              107.713561
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 180
            }
          },
          {
            "value": 14,
            "elided": null
          }
        ],
        "output": {
          "true_range": [
            2.1569999999999965,
            2.663404,
            2.868076000000002,
            2.9394869999999997,
            2.859921,
            2.6491259999999954
          ],
          "plus_dm": [
            0,
            0.6508400000000023,
            0.7153890000000018,
            0.7264239999999944,
            0.6901309999999938,
            0.6193439999999981
          ],
          "minus_dm": [
            0,
            0,
            0,
            0,
            0,
            0
          ],
          "smoothed_tr": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "smoothed_plus_dm": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "smoothed_minus_dm": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "atr": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "plus_di": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "minus_di": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "dx": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: true_range, plus_dm, minus_dm, smoothed_tr, smoothed_plus_dm, smoothed_minus_dm, atr, plus_di, …"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "canonical-trace.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a04/static/canonical-trace.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a04/static/failure-boundary.svg"
          },
          {
            "file": "mechanism-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a04/static/mechanism-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Directional Movement calculation flow",
            "source": "flowchart LR\n    A[\"Validated finalized bar\"] --> B[\"Causal window or recursive state\"]\n    B --> C[\"Explicit seed and boundary rule\"]\n    C --> D[\"Aligned Directional Movement output\"]\n    D --> E[\"Diagnostics and audit evidence\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "J. Welles Wilder, New Concepts in Technical Trading Systems",
          "author": "J. Welles Wilder",
          "url": "https://books.google.com/books?vid=ISBN0894590278"
        },
        {
          "key": "R2",
          "title": "TA-Lib DX",
          "author": "TA-Lib project or TradingView, as identified by the linked page",
          "url": "https://ta-lib.org/functions/dx"
        },
        {
          "key": "R3",
          "title": "Pinned TA-Lib ta_DX.c implementation",
          "author": "TA-Lib project or TradingView",
          "url": "https://github.com/TA-Lib/ta-lib/blob/e203f7c436a9c21fd08246661971cfcb7ee37517/src/ta_func/ta_DX.c"
        },
        {
          "key": "R4",
          "title": "Canonical synthetic fixture and independent arithmetic",
          "author": "The Fintech Builder",
          "url": null
        },
        {
          "key": "R5 â€” TA-Lib TRANGE function documentation",
          "title": "R5 â€” TA-Lib TRANGE function documentation",
          "author": "TA-Lib project or TradingView",
          "url": "https://ta-lib.org/functions/trange"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/directional-movement/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/directional-movement/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A05",
      "name": "Average Directional Index (ADX)",
      "headline": "Smooth DX Without Inventing Direction",
      "slug": "adx",
      "path": "technical-indicators/trend-systems/adx",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/adx",
        "entry": "adx",
        "params": [
          "high",
          "low",
          "close",
          "period"
        ],
        "exports": [
          "adx"
        ],
        "archetype": "series-transform",
        "signature": "adx(high, low, close, period)"
      },
      "api": {
        "summary": "Average directional index: the smoothed magnitude of the gap between +DI and −DI. It measures whether a trend exists at all, and says nothing about its direction — which is why it is used as a filter rather than a signal.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "period",
            "type": "number",
            "required": true,
            "description": "Wilder smoothing period, applied twice: once to the DI components and once to DX.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `plus_di`, `minus_di`, `dx` and `adx`."
        },
        "warmup": {
          "count": "2 × period − 1",
          "value": "null",
          "note": "ADX is a smoothing of DX, which is itself computed from smoothed components."
        },
        "errors": [
          {
            "when": "period < 1 or is not an integer",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "adx([109.485,110.139028,110.859574,111.590939,112.283113,112.89901], [107.2615,107.406037,107.92024,108.58088,109.35613,110.189018], [108.42,108.957755,109.593932,110.295981,111.021937,111.725443], 14)",
        "args": [
          {
            "value": [
              109.485,
              110.139028,
              110.859574,
              111.590939,
              112.283113,
              112.89901
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 180
            }
          },
          {
            "value": [
              107.2615,
              107.406037,
              107.92024,
              108.58088,
              109.35613,
              110.189018
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 180
            }
          },
          {
            "value": [
              108.42,
              108.957755,
              109.593932,
              110.295981,
              111.021937,
              111.725443
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 180
            }
          },
          {
            "value": 14,
            "elided": null
          }
        ],
        "output": {
          "plus_di": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "minus_di": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "dx": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "adx": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: plus_di, minus_di, dx, adx"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "canonical-trace.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a05/static/canonical-trace.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a05/static/failure-boundary.svg"
          },
          {
            "file": "mechanism-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a05/static/mechanism-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "ADX calculation flow",
            "source": "flowchart LR\n    A[\"Validated finalized bar\"] --> B[\"Causal window or recursive state\"]\n    B --> C[\"Explicit seed and boundary rule\"]\n    C --> D[\"Aligned ADX output\"]\n    D --> E[\"Diagnostics and audit evidence\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "J. Welles Wilder, New Concepts in Technical Trading Systems",
          "author": "J. Welles Wilder",
          "url": "https://books.google.com/books?vid=ISBN0894590278"
        },
        {
          "key": "R2",
          "title": "TA-Lib ADX",
          "author": "TA-Lib project or TradingView, as identified by the linked page",
          "url": "https://ta-lib.org/functions/adx.html"
        },
        {
          "key": "R3",
          "title": "Pinned TA-Lib ta_ADX.c implementation",
          "author": "TA-Lib project or TradingView",
          "url": "https://github.com/TA-Lib/ta-lib/blob/e203f7c436a9c21fd08246661971cfcb7ee37517/src/ta_func/ta_ADX.c"
        },
        {
          "key": "R4",
          "title": "Canonical synthetic fixture and independent arithmetic",
          "author": "The Fintech Builder",
          "url": null
        },
        {
          "key": "R5 â€” TA-Lib DX function documentation",
          "title": "R5 â€” TA-Lib DX function documentation",
          "author": "TA-Lib project or TradingView",
          "url": "https://ta-lib.org/functions/dx"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/adx/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/adx/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A06",
      "name": "Ichimoku Cloud",
      "headline": "Separate Range Midpoints from Plot-Time Displacement",
      "slug": "ichimoku-cloud",
      "path": "technical-indicators/trend-systems/ichimoku-cloud",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/ichimoku-cloud",
        "entry": "ichimoku",
        "params": [
          "high",
          "low",
          "close",
          "conversionPeriod",
          "basePeriod",
          "spanBPeriod",
          "displacement"
        ],
        "exports": [
          "ichimoku"
        ],
        "archetype": "series-transform",
        "signature": "ichimoku(high, low, close, conversionPeriod, basePeriod, spanBPeriod, displacement)"
      },
      "api": {
        "summary": "The five Ichimoku lines. Two of them are plotted shifted forward and one shifted backward, so the series a chart draws is not the series computed at that index.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "conversionPeriod",
            "type": "number",
            "required": true,
            "description": "Lookback for the conversion line (Tenkan-sen).",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "basePeriod",
            "type": "number",
            "required": true,
            "description": "Lookback for the base line (Kijun-sen).",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "spanBPeriod",
            "type": "number",
            "required": true,
            "description": "Lookback for leading span B.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "displacement",
            "type": "number",
            "required": true,
            "description": "Bars by which the leading spans are pushed forward and the lagging span pulled back.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Both the values at their origin index (`span_a_origin`, `span_b_origin`) and the displaced series a chart plots (`span_a_plot`, `span_b_plot`, `lagging_plot`). Using the origin series for plotting is the classic Ichimoku error."
        },
        "warmup": {
          "count": "max(conversionPeriod, basePeriod, spanBPeriod) − 1, plus the displacement on the plotted spans",
          "value": "null"
        },
        "errors": [
          {
            "when": "any period is < 1 or is not an integer",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n × period)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "ichimoku([113.52,114.177204,114.902817,115.638854,116.332532,116.944154], [111.23,111.374639,111.892314,112.558492,113.339025,114.174124], [112.42,112.960931,113.602175,114.308896,115.036356,115.735587], 9, 26, 52, 26)",
        "args": [
          {
            "value": [
              113.52,
              114.177204,
              114.902817,
              115.638854,
              116.332532,
              116.944154
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 220
            }
          },
          {
            "value": [
              111.23,
              111.374639,
              111.892314,
              112.558492,
              113.339025,
              114.174124
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 220
            }
          },
          {
            "value": [
              112.42,
              112.960931,
              113.602175,
              114.308896,
              115.036356,
              115.735587
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 220
            }
          },
          {
            "value": 9,
            "elided": null
          },
          {
            "value": 26,
            "elided": null
          },
          {
            "value": 52,
            "elided": null
          },
          {
            "value": 26,
            "elided": null
          }
        ],
        "output": {
          "conversion": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "base": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "span_a_origin": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "span_b_origin": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "span_a_plot": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "span_b_plot": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "lagging_plot": [
            120.589736,
            120.670539,
            120.683594,
            120.665739,
            120.660508,
            120.712142
          ]
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: conversion, base, span_a_origin, span_b_origin, span_a_plot, span_b_plot, lagging_plot"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "canonical-trace.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a06/static/canonical-trace.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a06/static/failure-boundary.svg"
          },
          {
            "file": "mechanism-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a06/static/mechanism-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Ichimoku Cloud calculation flow",
            "source": "flowchart LR\n    A[\"Validated finalized bar\"] --> B[\"Causal window or recursive state\"]\n    B --> C[\"Explicit seed and boundary rule\"]\n    C --> D[\"Aligned Ichimoku Cloud output\"]\n    D --> E[\"Diagnostics and audit evidence\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "Goichi Hosoda's Ichimoku Kinko Hyo",
          "author": "Goichi Hosoda's Ichimoku Kinko Hyo",
          "url": "https://search.worldcat.org/search?q=au%3AHosoda%2C+Goichi+Ichimoku"
        },
        {
          "key": "R2",
          "title": "TradingView Ichimoku Cloud",
          "author": "TA-Lib project or TradingView, as identified by the linked page",
          "url": "https://www.tradingview.com/support/solutions/43000589152-ichimoku-cloud/"
        },
        {
          "key": "R3",
          "title": "TradingView maintained Ichimoku calculation guide",
          "author": "TA-Lib project or TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000589152-ichimoku-cloud/"
        },
        {
          "key": "R4",
          "title": "Canonical synthetic fixture and independent arithmetic",
          "author": "The Fintech Builder",
          "url": null
        },
        {
          "key": "R5 â€” TradingView Pine Script built-ins documentation",
          "title": "R5 â€” TradingView Pine Script built-ins documentation",
          "author": "TA-Lib project or TradingView",
          "url": "https://www.tradingview.com/pine-script-docs/language/built-ins/"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/ichimoku-cloud/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/ichimoku-cloud/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A07",
      "name": "Parabolic SAR",
      "headline": "Audit the Stop, Extreme Point, and Acceleration Factor",
      "slug": "parabolic-sar",
      "path": "technical-indicators/trend-systems/parabolic-sar",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/parabolic-sar",
        "entry": "parabolicSar",
        "params": [
          "high",
          "low",
          "initialDirection",
          "accelerationStep",
          "accelerationMax"
        ],
        "exports": [
          "parabolicSar"
        ],
        "archetype": "series-transform",
        "signature": "parabolicSar(high, low, initialDirection, accelerationStep, accelerationMax)"
      },
      "api": {
        "summary": "Stop-and-reverse: a trailing stop that accelerates toward price while a trend persists and flips side when price crosses it. Path-dependent — the whole series follows from the initial direction.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "initialDirection",
            "type": "\"long\" | \"short\"",
            "required": true,
            "description": "Trend direction assumed at the first bar. Because the calculation is recursive, this choice propagates through the entire series.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "accelerationStep",
            "type": "number",
            "required": true,
            "description": "Increment added to the acceleration factor each time a new extreme is made.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "accelerationMax",
            "type": "number",
            "required": true,
            "description": "Ceiling on the acceleration factor.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `sar`, `trend`, `extreme_point`, `acceleration_factor` and a `reversal` flag marking the bars where the stop flipped."
        },
        "warmup": {
          "count": "1",
          "value": "null",
          "note": "The first bar establishes the state; the first SAR value applies from the second."
        },
        "errors": [
          {
            "when": "accelerationStep or accelerationMax is negative, or accelerationStep > accelerationMax",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "parabolicSar([117.555,118.215368,118.945956,119.686391,120.381031,120.987562], [115.1985,115.34324,115.864377,116.536001,117.321542,118.15831], \"long\", 0.02, 0.2)",
        "args": [
          {
            "value": [
              117.555,
              118.215368,
              118.945956,
              119.686391,
              120.381031,
              120.987562
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 180
            }
          },
          {
            "value": [
              115.1985,
              115.34324,
              115.864377,
              116.536001,
              117.321542,
              118.15831
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 180
            }
          },
          {
            "value": "long",
            "elided": null
          },
          {
            "value": 0.02,
            "elided": null
          },
          {
            "value": 0.2,
            "elided": null
          }
        ],
        "output": {
          "sar": [
            null,
            115.1985,
            115.1985,
            115.34324,
            115.60382906,
            115.9860052152
          ],
          "trend": [
            null,
            "long",
            "long",
            "long",
            "long",
            "long"
          ],
          "extreme_point": [
            null,
            118.215368,
            118.945956,
            119.686391,
            120.381031,
            120.987562
          ],
          "acceleration_factor": [
            null,
            0.02,
            0.04,
            0.06,
            0.08,
            0.1
          ],
          "reversal": [
            null,
            false,
            false,
            false,
            false,
            false
          ]
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: sar, trend, extreme_point, acceleration_factor, reversal"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "canonical-trace.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a07/static/canonical-trace.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a07/static/failure-boundary.svg"
          },
          {
            "file": "mechanism-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a07/static/mechanism-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Parabolic SAR calculation flow",
            "source": "flowchart LR\n    A[\"Validated finalized bar\"] --> B[\"Causal window or recursive state\"]\n    B --> C[\"Explicit seed and boundary rule\"]\n    C --> D[\"Aligned Parabolic SAR output\"]\n    D --> E[\"Diagnostics and audit evidence\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "J. Welles Wilder, New Concepts in Technical Trading Systems",
          "author": "J. Welles Wilder",
          "url": "https://books.google.com/books?vid=ISBN0894590278"
        },
        {
          "key": "R2",
          "title": "TA-Lib SAR",
          "author": "TA-Lib project or TradingView, as identified by the linked page",
          "url": "https://ta-lib.org/functions/sar"
        },
        {
          "key": "R3",
          "title": "Pinned TA-Lib ta_SAR.c implementation",
          "author": "TA-Lib project or TradingView",
          "url": "https://github.com/TA-Lib/ta-lib/blob/e203f7c436a9c21fd08246661971cfcb7ee37517/src/ta_func/ta_SAR.c"
        },
        {
          "key": "R4",
          "title": "Canonical synthetic fixture and independent arithmetic",
          "author": "The Fintech Builder",
          "url": null
        },
        {
          "key": "R5 â€” TA-Lib SAREXT function documentation",
          "title": "R5 â€” TA-Lib SAREXT function documentation",
          "author": "TA-Lib project or TradingView",
          "url": "https://ta-lib.org/functions/sarext"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/parabolic-sar/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/parabolic-sar/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F02-A08",
      "name": "Supertrend",
      "headline": "Trace ATR Bands, Ratchets, and Direction Flips",
      "slug": "supertrend",
      "path": "technical-indicators/trend-systems/supertrend",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F02",
        "family": "Trend Systems",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/trend-systems/supertrend",
        "entry": "supertrend",
        "params": [
          "high",
          "low",
          "close",
          "period",
          "multiplier"
        ],
        "exports": [
          "supertrend"
        ],
        "archetype": "series-transform",
        "signature": "supertrend(high, low, close, period, multiplier)"
      },
      "api": {
        "summary": "An ATR-scaled band around the median price that ratchets in the direction of the trend and only flips when close crosses it. The band never loosens while the trend holds.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "period",
            "type": "number",
            "required": true,
            "description": "ATR lookback.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "multiplier",
            "type": "number",
            "required": true,
            "description": "Number of ATRs the band sits away from the median price.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `atr`, `upper_band`, `lower_band`, `supertrend` and `trend`."
        },
        "warmup": {
          "count": "period",
          "value": "null",
          "note": "The band cannot be placed until ATR is defined."
        },
        "errors": [
          {
            "when": "period < 1, is not an integer, or multiplier is negative",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "supertrend([121.59,122.253519,122.988989,123.733544,124.428602,125.029237], [119.167,119.311841,119.836426,120.513403,121.303676,122.141567], [120.42,120.967246,121.618347,122.333586,123.062426,123.75067], 10, 3)",
        "args": [
          {
            "value": [
              121.59,
              122.253519,
              122.988989,
              123.733544,
              124.428602,
              125.029237
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 180
            }
          },
          {
            "value": [
              119.167,
              119.311841,
              119.836426,
              120.513403,
              121.303676,
              122.141567
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 180
            }
          },
          {
            "value": [
              120.42,
              120.967246,
              121.618347,
              122.333586,
              123.062426,
              123.75067
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 180
            }
          },
          {
            "value": 10,
            "elided": null
          },
          {
            "value": 3,
            "elided": null
          }
        ],
        "output": {
          "true_range": [
            2.423000000000002,
            2.941677999999996,
            3.1525630000000007,
            3.220140999999998,
            3.124926000000002,
            2.88767
          ],
          "atr": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "basic_upper": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "basic_lower": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "final_upper": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "final_lower": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "supertrend": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "direction": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "reversal": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: true_range, atr, basic_upper, basic_lower, final_upper, final_lower, supertrend, direction, …"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "canonical-trace.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a08/static/canonical-trace.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a08/static/failure-boundary.svg"
          },
          {
            "file": "mechanism-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f02-a08/static/mechanism-map.svg"
          }
        ],
        "mermaid": [
          {
            "file": "calculation-flow.md",
            "caption": "Supertrend calculation flow",
            "source": "flowchart LR\n    A[\"Validated finalized bar\"] --> B[\"Causal window or recursive state\"]\n    B --> C[\"Explicit seed and boundary rule\"]\n    C --> D[\"Aligned Supertrend output\"]\n    D --> E[\"Diagnostics and audit evidence\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R1",
          "title": "Olivier Seban's Supertrend",
          "author": "Olivier Seban's Supertrend",
          "url": "https://www.tradingview.com/support/solutions/43000634738-supertrend/"
        },
        {
          "key": "R2",
          "title": "TradingView Supertrend",
          "author": "TA-Lib project or TradingView, as identified by the linked page",
          "url": "https://www.tradingview.com/support/solutions/43000634738-supertrend/"
        },
        {
          "key": "R3",
          "title": "TA-Lib ATR",
          "author": "TA-Lib project or TradingView",
          "url": "https://ta-lib.org/functions/atr"
        },
        {
          "key": "R4",
          "title": "Canonical synthetic fixture and independent arithmetic",
          "author": "The Fintech Builder",
          "url": null
        },
        {
          "key": "R5 â€” TradingView Pine Script built-ins documentation",
          "title": "R5 â€” TradingView Pine Script built-ins documentation",
          "author": "TA-Lib project or TradingView",
          "url": "https://www.tradingview.com/pine-script-docs/language/built-ins/"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/trend-systems/supertrend/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/trend-systems/supertrend/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A01",
      "name": "Relative Strength Index (RSI)",
      "headline": null,
      "slug": "rsi",
      "path": "technical-indicators/momentum/rsi",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/rsi",
        "entry": "rsi",
        "params": [
          "close",
          "p"
        ],
        "exports": [
          "rsi",
          "stochastic",
          "stochasticRsi",
          "williamsR",
          "cci",
          "ultimateOscillator",
          "tsi",
          "connorsRsi"
        ],
        "archetype": "series-transform",
        "signature": "rsi(close, p)"
      },
      "api": {
        "summary": "Relative strength index: Wilder-smoothed average gain over average loss, mapped to 0–100. In a strong trend a high reading means strength persisting, not exhaustion — which is the most common misreading of this indicator.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "p",
            "type": "number",
            "required": true,
            "description": "Wilder smoothing period. 14 is the conventional default.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "A single parallel series, `rsi`."
        },
        "warmup": {
          "count": "p",
          "value": "null",
          "note": "Wilder smoothing seeds on the first full window of gains and losses."
        },
        "errors": [
          {
            "when": "p < 1 or is not an integer",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "rsi([100,100.999214,102.324548,103.755998,105.030823,105.911843])",
        "args": [
          {
            "value": [
              100,
              100.999214,
              102.324548,
              103.755998,
              105.030823,
              105.911843
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          }
        ],
        "output": {
          "rsi": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 1 field: rsi"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "rsi-mechanism.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a01/static/rsi-mechanism.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "New Concepts in Technical Trading Systems",
          "title": "New Concepts in Technical Trading Systems",
          "author": "J. Welles Wilder / Windsor Books",
          "url": null
        },
        {
          "key": "TA-Lib Technical Analysis Documentation",
          "title": "TA-Lib Technical Analysis Documentation",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Claim-role ledger",
          "title": "Claim-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/rsi/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/rsi/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A02",
      "name": "Stochastic Oscillator",
      "headline": null,
      "slug": "stochastic-oscillator",
      "path": "technical-indicators/momentum/stochastic-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/stochastic-oscillator",
        "entry": "stochastic",
        "params": [
          "high",
          "low",
          "close",
          "kp",
          "sk",
          "sd"
        ],
        "exports": [
          "rsi",
          "stochastic",
          "stochasticRsi",
          "williamsR",
          "cci",
          "ultimateOscillator",
          "tsi",
          "connorsRsi"
        ],
        "archetype": "series-transform",
        "signature": "stochastic(high, low, close, kp, sk, sd)"
      },
      "api": {
        "summary": "Where the close sits within the high–low range of the lookback, expressed as 0–100, then smoothed twice.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "kp",
            "type": "number",
            "required": true,
            "description": "%K lookback: the window over which the high–low range is measured.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "sk",
            "type": "number",
            "required": true,
            "description": "Smoothing applied to raw %K to produce slow %K.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "sd",
            "type": "number",
            "required": true,
            "description": "Smoothing applied to slow %K to produce %D.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `fast_k`, `slow_k` and `slow_d`."
        },
        "warmup": {
          "count": "kp − 1 for fast %K, then sk − 1 and sd − 1 more for each smoothing stage",
          "value": "null"
        },
        "errors": [
          {
            "when": "any period is < 1 or is not an integer",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n × kp)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "stochastic([101,101.992465,103.28276,104.655405,105.856544,106.661472], [99.08,99.149664,100.233798,101.654978,103.180913,104.534685], [100,100.999214,102.324548,103.755998,105.030823,105.911843])",
        "args": [
          {
            "value": [
              101,
              101.992465,
              103.28276,
              104.655405,
              105.856544,
              106.661472
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              99.08,
              99.149664,
              100.233798,
              101.654978,
              103.180913,
              104.534685
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              100,
              100.999214,
              102.324548,
              103.755998,
              105.030823,
              105.911843
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          }
        ],
        "output": {
          "fast_k": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "slow_k": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "slow_d": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: fast_k, slow_k, slow_d"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "stochastic-oscillator-mechanism.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a02/static/stochastic-oscillator-mechanism.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Stochastic Oscillator Slow (STOCH)",
          "title": "Stochastic Oscillator Slow (STOCH)",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "TA-Lib Technical Analysis Documentation",
          "title": "TA-Lib Technical Analysis Documentation",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Claim-role ledger",
          "title": "Claim-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/stochastic-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/stochastic-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A03",
      "name": "Stochastic RSI",
      "headline": null,
      "slug": "stochastic-rsi",
      "path": "technical-indicators/momentum/stochastic-rsi",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/stochastic-rsi",
        "entry": "stochasticRsi",
        "params": [
          "close",
          "rp",
          "sp",
          "sk",
          "sd"
        ],
        "exports": [
          "rsi",
          "stochastic",
          "stochasticRsi",
          "williamsR",
          "cci",
          "ultimateOscillator",
          "tsi",
          "connorsRsi"
        ],
        "archetype": "series-transform",
        "signature": "stochasticRsi(close, rp, sp, sk, sd)"
      },
      "api": {
        "summary": "The stochastic formula applied to RSI rather than to price — a second-order indicator that measures where RSI sits within its own recent range, and therefore moves far faster than either input.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "rp",
            "type": "number",
            "required": true,
            "description": "RSI period computed first.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "sp",
            "type": "number",
            "required": true,
            "description": "Stochastic lookback applied over the RSI series.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "sk",
            "type": "number",
            "required": true,
            "description": "Smoothing applied to raw %K.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "sd",
            "type": "number",
            "required": true,
            "description": "Smoothing applied to %K to produce %D.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `rsi`, `raw_k`, `k` and `d`."
        },
        "warmup": {
          "count": "rp + sp − 1, plus each smoothing stage",
          "value": "null",
          "note": "Warm-ups accumulate across both stages, so this is defined much later than plain RSI."
        },
        "errors": [
          {
            "when": "any period is < 1 or is not an integer",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n × sp)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "stochasticRsi([100,100.999214,102.324548,103.755998,105.030823,105.911843])",
        "args": [
          {
            "value": [
              100,
              100.999214,
              102.324548,
              103.755998,
              105.030823,
              105.911843
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          }
        ],
        "output": {
          "rsi": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "raw_k": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "k": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "d": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: rsi, raw_k, k, d"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "stochastic-rsi-mechanism.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a03/static/stochastic-rsi-mechanism.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Stochastic RSI (STOCHRSI)",
          "title": "Stochastic RSI (STOCHRSI)",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "New Concepts in Technical Trading Systems",
          "title": "New Concepts in Technical Trading Systems",
          "author": "J. Welles Wilder / Windsor Books",
          "url": null
        },
        {
          "key": "TA-Lib Technical Analysis Documentation",
          "title": "TA-Lib Technical Analysis Documentation",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Claim-role ledger",
          "title": "Claim-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/stochastic-rsi/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/stochastic-rsi/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A04",
      "name": "Williams %R",
      "headline": null,
      "slug": "williams-r",
      "path": "technical-indicators/momentum/williams-r",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/williams-r",
        "entry": "williamsR",
        "params": [
          "high",
          "low",
          "close",
          "p"
        ],
        "exports": [
          "rsi",
          "stochastic",
          "stochasticRsi",
          "williamsR",
          "cci",
          "ultimateOscillator",
          "tsi",
          "connorsRsi"
        ],
        "archetype": "series-transform",
        "signature": "williamsR(high, low, close, p)"
      },
      "api": {
        "summary": "Where the close sits within the lookback's high–low range, on a −100…0 scale. Arithmetically the inverse of fast %K.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "p",
            "type": "number",
            "required": true,
            "description": "Lookback in bars.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "A single parallel series, `williams_r`, ranging from −100 to 0."
        },
        "warmup": {
          "count": "p − 1",
          "value": "null"
        },
        "errors": [
          {
            "when": "p < 1 or is not an integer",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n × p)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "williamsR([101,101.992465,103.28276,104.655405,105.856544,106.661472], [99.08,99.149664,100.233798,101.654978,103.180913,104.534685], [100,100.999214,102.324548,103.755998,105.030823,105.911843])",
        "args": [
          {
            "value": [
              101,
              101.992465,
              103.28276,
              104.655405,
              105.856544,
              106.661472
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              99.08,
              99.149664,
              100.233798,
              101.654978,
              103.180913,
              104.534685
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              100,
              100.999214,
              102.324548,
              103.755998,
              105.030823,
              105.911843
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          }
        ],
        "output": {
          "williams_r": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 1 field: williams_r"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "williams-r-mechanism.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a04/static/williams-r-mechanism.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Williams %R (WILLR)",
          "title": "Williams %R (WILLR)",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Stochastic Oscillator Slow (STOCH)",
          "title": "Stochastic Oscillator Slow (STOCH)",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "TA-Lib Technical Analysis Documentation",
          "title": "TA-Lib Technical Analysis Documentation",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Claim-role ledger",
          "title": "Claim-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/williams-r/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/williams-r/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A05",
      "name": "Commodity Channel Index (CCI)",
      "headline": null,
      "slug": "cci",
      "path": "technical-indicators/momentum/cci",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/cci",
        "entry": "cci",
        "params": [
          "high",
          "low",
          "close",
          "p",
          "k"
        ],
        "exports": [
          "rsi",
          "stochastic",
          "stochasticRsi",
          "williamsR",
          "cci",
          "ultimateOscillator",
          "tsi",
          "connorsRsi"
        ],
        "archetype": "series-transform",
        "signature": "cci(high, low, close, p, k)"
      },
      "api": {
        "summary": "Commodity channel index: the typical price's distance from its moving average, scaled by mean absolute deviation. Unbounded, unlike RSI or the stochastics.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "p",
            "type": "number",
            "required": true,
            "description": "Lookback for the average and the mean absolute deviation.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "k",
            "type": "number",
            "required": false,
            "description": "Scaling constant. The conventional 0.015 places roughly 70–80% of readings within ±100; changing it changes what any threshold means.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": 0.015
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `typical_price` and `cci`."
        },
        "warmup": {
          "count": "p − 1",
          "value": "null"
        },
        "errors": [
          {
            "when": "p < 1, is not an integer, or k is negative",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n × p)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "cci([101,101.992465,103.28276,104.655405,105.856544,106.661472], [99.08,99.149664,100.233798,101.654978,103.180913,104.534685], [100,100.999214,102.324548,103.755998,105.030823,105.911843])",
        "args": [
          {
            "value": [
              101,
              101.992465,
              103.28276,
              104.655405,
              105.856544,
              106.661472
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              99.08,
              99.149664,
              100.233798,
              101.654978,
              103.180913,
              104.534685
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              100,
              100.999214,
              102.324548,
              103.755998,
              105.030823,
              105.911843
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          }
        ],
        "output": {
          "typical_price": [
            100.02666666666666,
            100.713781,
            101.94703533333332,
            103.35546033333333,
            104.68942666666668,
            105.70266666666667
          ],
          "cci": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: typical_price, cci"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "cci-mechanism.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a05/static/cci-mechanism.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Commodity Channel Index (CCI)",
          "title": "Commodity Channel Index (CCI)",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "TA-Lib Technical Analysis Documentation",
          "title": "TA-Lib Technical Analysis Documentation",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Claim-role ledger",
          "title": "Claim-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/cci/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/cci/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A06",
      "name": "Ultimate Oscillator",
      "headline": null,
      "slug": "ultimate-oscillator",
      "path": "technical-indicators/momentum/ultimate-oscillator",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/ultimate-oscillator",
        "entry": "ultimateOscillator",
        "params": [
          "high",
          "low",
          "close",
          "s",
          "m",
          "g"
        ],
        "exports": [
          "rsi",
          "stochastic",
          "stochasticRsi",
          "williamsR",
          "cci",
          "ultimateOscillator",
          "tsi",
          "connorsRsi"
        ],
        "archetype": "series-transform",
        "signature": "ultimateOscillator(high, low, close, s, m, g)"
      },
      "api": {
        "summary": "Weighted buying pressure across three lookbacks at once, which is what makes it less sensitive to the choice of any single period than a plain oscillator.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "s",
            "type": "number",
            "required": true,
            "description": "Short lookback, conventionally weighted 4.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "m",
            "type": "number",
            "required": true,
            "description": "Medium lookback, conventionally weighted 2.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "g",
            "type": "number",
            "required": true,
            "description": "Long lookback, conventionally weighted 1.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `buying_pressure`, `true_range` and `ultimate_oscillator`."
        },
        "warmup": {
          "count": "the longest of the three lookbacks",
          "value": "null"
        },
        "errors": [
          {
            "when": "any lookback is < 1 or is not an integer",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n × g)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "ultimateOscillator([101,101.992465,103.28276,104.655405,105.856544,106.661472], [99.08,99.149664,100.233798,101.654978,103.180913,104.534685], [100,100.999214,102.324548,103.755998,105.030823,105.911843])",
        "args": [
          {
            "value": [
              101,
              101.992465,
              103.28276,
              104.655405,
              105.856544,
              106.661472
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              99.08,
              99.149664,
              100.233798,
              101.654978,
              103.180913,
              104.534685
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              100,
              100.999214,
              102.324548,
              103.755998,
              105.030823,
              105.911843
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          }
        ],
        "output": {
          "buying_pressure": [
            null,
            1.8495499999999936,
            2.09075,
            2.1010200000000054,
            1.8499099999999942,
            1.3771580000000085
          ],
          "true_range": [
            null,
            2.8428009999999944,
            3.048962000000003,
            3.000427000000002,
            2.6756309999999957,
            2.1267870000000073
          ],
          "ultimate_oscillator": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 3 fields: buying_pressure, true_range, ultimate_oscillator"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "ultimate-oscillator-mechanism.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a06/static/ultimate-oscillator-mechanism.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Ultimate Oscillator (ULTOSC)",
          "title": "Ultimate Oscillator (ULTOSC)",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "TA-Lib Technical Analysis Documentation",
          "title": "TA-Lib Technical Analysis Documentation",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Claim-role ledger",
          "title": "Claim-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/ultimate-oscillator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/ultimate-oscillator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A07",
      "name": "True Strength Index (TSI)",
      "headline": null,
      "slug": "tsi",
      "path": "technical-indicators/momentum/tsi",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/tsi",
        "entry": "tsi",
        "params": [
          "close",
          "g",
          "s"
        ],
        "exports": [
          "rsi",
          "stochastic",
          "stochasticRsi",
          "williamsR",
          "cci",
          "ultimateOscillator",
          "tsi",
          "connorsRsi"
        ],
        "archetype": "series-transform",
        "signature": "tsi(close, g, s)"
      },
      "api": {
        "summary": "True strength index: price change smoothed twice, divided by absolute price change smoothed the same way. The double smoothing is what separates it from a plain momentum reading.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "g",
            "type": "number",
            "required": true,
            "description": "Long smoothing span, applied first.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "s",
            "type": "number",
            "required": true,
            "description": "Short smoothing span, applied to the result of the first pass.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "A single parallel series, `tsi`."
        },
        "warmup": {
          "count": "g + s − 2",
          "value": "null",
          "note": "Both smoothing passes must fill."
        },
        "errors": [
          {
            "when": "either span is < 1 or is not an integer",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "tsi([100,100.999214,102.324548,103.755998,105.030823,105.911843])",
        "args": [
          {
            "value": [
              100,
              100.999214,
              102.324548,
              103.755998,
              105.030823,
              105.911843
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          }
        ],
        "output": {
          "tsi": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 1 field: tsi"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "tsi-mechanism.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a07/static/tsi-mechanism.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "True Strength Index (TSI)",
          "title": "True Strength Index (TSI)",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Momentum, Direction, and Divergence",
          "title": "Momentum, Direction, and Divergence",
          "author": "William Blau / Wiley",
          "url": null
        },
        {
          "key": "TA-Lib Technical Analysis Documentation",
          "title": "TA-Lib Technical Analysis Documentation",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Claim-role ledger",
          "title": "Claim-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/tsi/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/tsi/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F03-A08",
      "name": "Connors RSI",
      "headline": null,
      "slug": "connors-rsi",
      "path": "technical-indicators/momentum/connors-rsi",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F03",
        "family": "Momentum",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/momentum/connors-rsi",
        "entry": "connorsRsi",
        "params": [
          "close",
          "pp",
          "sp",
          "rp"
        ],
        "exports": [
          "rsi",
          "stochastic",
          "stochasticRsi",
          "williamsR",
          "cci",
          "ultimateOscillator",
          "tsi",
          "connorsRsi"
        ],
        "archetype": "series-transform",
        "signature": "connorsRsi(close, pp, sp, rp)"
      },
      "api": {
        "summary": "The average of three components: RSI of price, RSI of the up/down streak length, and the percentile rank of the latest return. Designed for short-horizon mean reversion rather than trend.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "pp",
            "type": "number",
            "required": true,
            "description": "RSI period applied to price.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "sp",
            "type": "number",
            "required": true,
            "description": "RSI period applied to the streak-length series.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "rp",
            "type": "number",
            "required": true,
            "description": "Lookback for the percentile rank of the most recent return.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `price_rsi`, `streak`, `streak_rsi`, `percent_rank` and `connors_rsi`."
        },
        "warmup": {
          "count": "the longest of the three components",
          "value": "null"
        },
        "errors": [
          {
            "when": "any period is < 1 or is not an integer",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n × rp)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "connorsRsi([100,100.999214,102.324548,103.755998,105.030823,105.911843])",
        "args": [
          {
            "value": [
              100,
              100.999214,
              102.324548,
              103.755998,
              105.030823,
              105.911843
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          }
        ],
        "output": {
          "price_rsi": [
            null,
            null,
            null,
            100,
            100,
            100
          ],
          "streak": [
            0,
            1,
            2,
            3,
            4,
            5
          ],
          "streak_rsi": [
            null,
            null,
            100,
            100,
            100,
            100
          ],
          "percent_rank": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "connors_rsi": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: price_rsi, streak, streak_rsi, percent_rank, connors_rsi"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "connors-rsi-mechanism.svg",
            "url": "https://thefintechbuilder.com/content/d07-f03-a08/static/connors-rsi-mechanism.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "ConnorsRelativeStrengthIndex.cs",
          "title": "ConnorsRelativeStrengthIndex.cs",
          "author": "QuantConnect LEAN",
          "url": null
        },
        {
          "key": "New Concepts in Technical Trading Systems",
          "title": "New Concepts in Technical Trading Systems",
          "author": "J. Welles Wilder / Windsor Books",
          "url": null
        },
        {
          "key": "Claim-role ledger",
          "title": "Claim-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/momentum/connors-rsi/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/momentum/connors-rsi/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F04-A01",
      "name": "True Range",
      "headline": null,
      "slug": "true-range",
      "path": "technical-indicators/volatility-and-channels/true-range",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F04",
        "family": "Volatility and Channels",
        "difficulty": 1
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volatility-and-channels/true-range",
        "entry": "trueRange",
        "params": [
          "high",
          "low",
          "close"
        ],
        "exports": [
          "trueRange"
        ],
        "archetype": "series-transform",
        "signature": "trueRange(high, low, close)"
      },
      "api": {
        "summary": "The greater of today's range, the gap up from yesterday's close, and the gap down from it. Using the plain high−low range instead understates volatility on every gap.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series including `true_range` and, for each bar, which of the three candidates won (`driver`) — which is what makes a surprising ATR diagnosable."
        },
        "warmup": {
          "count": "0",
          "value": "high - low",
          "note": "The first bar has no prior close, so this package publishes high minus low while leaving the two previous-close gap components unavailable."
        },
        "errors": [
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "trueRange([101.08,101.6243955,102.13058177,102.56507653,102.90321818,103.1320792], [98.92,99.39457765,99.83203556,100.19996391,100.47473988,100.64442473], [100,100.50948657,100.98130867,101.38252022,101.68897903,101.88825197])",
        "args": [
          {
            "value": [
              101.08,
              101.6243955,
              102.13058177,
              102.56507653,
              102.90321818,
              103.1320792
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 240
            }
          },
          {
            "value": [
              98.92,
              99.39457765,
              99.83203556,
              100.19996391,
              100.47473988,
              100.64442473
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 240
            }
          },
          {
            "value": [
              100,
              100.50948657,
              100.98130867,
              101.38252022,
              101.68897903,
              101.88825197
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 240
            }
          }
        ],
        "output": {
          "true_range": [
            2.1599999999999966,
            2.2298178500000034,
            2.298546210000012,
            2.365112620000005,
            2.4284782999999948,
            2.4876544700000096
          ],
          "high_low": [
            2.1599999999999966,
            2.2298178500000034,
            2.298546210000012,
            2.365112620000005,
            2.4284782999999948,
            2.4876544700000096
          ],
          "high_gap": [
            null,
            1.6243955000000057,
            1.6210951999999992,
            1.5837678599999947,
            1.5206979599999926,
            1.4431001700000081
          ],
          "low_gap": [
            null,
            0.6054223499999978,
            0.6774510100000128,
            0.7813447600000103,
            0.9077803400000022,
            1.0445543000000015
          ],
          "driver": [
            "high-low",
            "high-low",
            "high-low",
            "high-low",
            "high-low",
            "high-low"
          ]
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: true_range, high_low, high_gap, low_gap, driver"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "canonical-trace.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a01/static/canonical-trace.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a01/static/failure-boundary.svg"
          },
          {
            "file": "mechanism-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a01/static/mechanism-map.svg"
          },
          {
            "file": "memory-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a01/static/memory-comparison.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "TRANGE",
          "title": "True Range",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "ta_TRANGE.c",
          "title": "ta_TRANGE.c",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "ATR",
          "title": "Average True Range",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Public evidence boundary",
          "title": "Public evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volatility-and-channels/true-range/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volatility-and-channels/true-range/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F04-A02",
      "name": "Average True Range (ATR)",
      "headline": null,
      "slug": "atr",
      "path": "technical-indicators/volatility-and-channels/atr",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F04",
        "family": "Volatility and Channels",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volatility-and-channels/atr",
        "entry": "averageTrueRange",
        "params": [
          "high",
          "low",
          "close",
          "p"
        ],
        "exports": [
          "trueRange",
          "averageTrueRange"
        ],
        "archetype": "series-transform",
        "signature": "averageTrueRange(high, low, close, p)"
      },
      "api": {
        "summary": "Wilder-smoothed true range. Most often used for position sizing and stop placement rather than as a signal — it says how far price typically moves, not which way.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "p",
            "type": "number",
            "required": true,
            "description": "Wilder smoothing period. Note this is 1/p decay, not the 2/(p+1) of a standard EMA; substituting one changes every published ATR value.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `true_range` and `atr`."
        },
        "warmup": {
          "count": "p - 1",
          "value": "null",
          "note": "Applies to `atr` only; `true_range` is defined from the first bar. The first ATR is the mean of the first p true ranges, so it lands at index p - 1 and Wilder smoothing continues from there."
        },
        "errors": [
          {
            "when": "p < 1 or is not an integer",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "averageTrueRange([101.08,101.6243955,102.13058177,102.56507653,102.90321818,103.1320792], [98.92,99.39457765,99.83203556,100.19996391,100.47473988,100.64442473], [100,100.50948657,100.98130867,101.38252022,101.68897903,101.88825197], 14)",
        "args": [
          {
            "value": [
              101.08,
              101.6243955,
              102.13058177,
              102.56507653,
              102.90321818,
              103.1320792
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 240
            }
          },
          {
            "value": [
              98.92,
              99.39457765,
              99.83203556,
              100.19996391,
              100.47473988,
              100.64442473
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 240
            }
          },
          {
            "value": [
              100,
              100.50948657,
              100.98130867,
              101.38252022,
              101.68897903,
              101.88825197
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 240
            }
          },
          {
            "value": 14,
            "elided": null
          }
        ],
        "output": {
          "true_range": [
            2.1599999999999966,
            2.2298178500000034,
            2.298546210000012,
            2.365112620000005,
            2.4284782999999948,
            2.4876544700000096
          ],
          "atr": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: true_range, atr"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "canonical-trace.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a02/static/canonical-trace.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a02/static/failure-boundary.svg"
          },
          {
            "file": "mechanism-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a02/static/mechanism-map.svg"
          },
          {
            "file": "memory-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a02/static/memory-comparison.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "New Concepts in Technical Trading Systems",
          "title": "New Concepts in Technical Trading Systems",
          "author": "J. Welles Wilder Jr.",
          "url": null
        },
        {
          "key": "ATR",
          "title": "Average True Range",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "ta_ATR.c",
          "title": "ta_ATR.c",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "TRANGE",
          "title": "True Range",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Public evidence boundary",
          "title": "Public evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volatility-and-channels/atr/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volatility-and-channels/atr/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F04-A03",
      "name": "Bollinger Bands",
      "headline": null,
      "slug": "bollinger-bands",
      "path": "technical-indicators/volatility-and-channels/bollinger-bands",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F04",
        "family": "Volatility and Channels",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volatility-and-channels/bollinger-bands",
        "entry": "bollingerBands",
        "params": [
          "close",
          "p",
          "multiplier"
        ],
        "exports": [
          "bollingerBands"
        ],
        "archetype": "series-transform",
        "signature": "bollingerBands(close, p, multiplier)"
      },
      "api": {
        "summary": "A moving average with bands a number of standard deviations away, so the channel widens and narrows with realised volatility.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "p",
            "type": "number",
            "required": true,
            "description": "Lookback for both the average and the standard deviation.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "multiplier",
            "type": "number",
            "required": true,
            "description": "Number of standard deviations from the middle band to each outer band.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `middle`, `stddev`, `upper`, `lower`, and `percent_b` — where price sits within the channel, 0 at the lower band and 1 at the upper."
        },
        "warmup": {
          "count": "p − 1",
          "value": "null"
        },
        "errors": [
          {
            "when": "p < 1, is not an integer, or multiplier is negative",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n × p)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "bollingerBands([100,100.54129063,101.06589044,101.55765885,102.00153762,102.3840473], 20, 2)",
        "args": [
          {
            "value": [
              100,
              100.54129063,
              101.06589044,
              101.55765885,
              102.00153762,
              102.3840473
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 240
            }
          },
          {
            "value": 20,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          }
        ],
        "output": {
          "middle": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "stddev": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "upper": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "lower": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "percent_b": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: middle, stddev, upper, lower, percent_b"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "canonical-trace.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a03/static/canonical-trace.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a03/static/failure-boundary.svg"
          },
          {
            "file": "mechanism-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a03/static/mechanism-map.svg"
          },
          {
            "file": "memory-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a03/static/memory-comparison.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Bollinger Bands Rules",
          "title": "Bollinger Bands Rules",
          "author": "John Bollinger",
          "url": null
        },
        {
          "key": "Bollinger Bands (BB)",
          "title": "Bollinger Bands (BB)",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "BBANDS",
          "title": "Bollinger Bands",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "ta_BBANDS.c",
          "title": "ta_BBANDS.c",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "e-Handbook: Measures of Scale",
          "title": "e-Handbook: Measures of Scale",
          "author": "NIST/SEMATECH",
          "url": null
        },
        {
          "key": "Public evidence boundary",
          "title": "Public evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volatility-and-channels/bollinger-bands/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volatility-and-channels/bollinger-bands/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F04-A04",
      "name": "Keltner Channels",
      "headline": null,
      "slug": "keltner-channels",
      "path": "technical-indicators/volatility-and-channels/keltner-channels",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F04",
        "family": "Volatility and Channels",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volatility-and-channels/keltner-channels",
        "entry": "keltnerChannels",
        "params": [
          "high",
          "low",
          "close",
          "emaPeriod",
          "atrPeriod",
          "multiplier"
        ],
        "exports": [
          "trueRange",
          "averageTrueRange",
          "keltnerChannels"
        ],
        "archetype": "series-transform",
        "signature": "keltnerChannels(high, low, close, emaPeriod, atrPeriod, multiplier)"
      },
      "api": {
        "summary": "An EMA with bands placed a number of ATRs away. Because it scales with true range rather than standard deviation, it reacts differently to gaps than Bollinger Bands — which is the basis of the squeeze comparison between the two.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "emaPeriod",
            "type": "number",
            "required": true,
            "description": "Span of the EMA that forms the middle line.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "atrPeriod",
            "type": "number",
            "required": true,
            "description": "Wilder period for the ATR that sets the band width.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "multiplier",
            "type": "number",
            "required": true,
            "description": "Number of ATRs from the middle line to each band.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `true_range`, `atr`, `middle`, `upper` and `lower`."
        },
        "warmup": {
          "count": "max(emaPeriod, atrPeriod)",
          "value": "null"
        },
        "errors": [
          {
            "when": "either period is < 1, is not an integer, or multiplier is negative",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "keltnerChannels([101.08,101.6243955,102.13058177,102.56507653,102.90321818,103.1320792], [98.92,99.39457765,99.83203556,100.19996391,100.47473988,100.64442473], [100,100.50948657,100.98130867,101.38252022,101.68897903,101.88825197], 20, 10, 2)",
        "args": [
          {
            "value": [
              101.08,
              101.6243955,
              102.13058177,
              102.56507653,
              102.90321818,
              103.1320792
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 240
            }
          },
          {
            "value": [
              98.92,
              99.39457765,
              99.83203556,
              100.19996391,
              100.47473988,
              100.64442473
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 240
            }
          },
          {
            "value": [
              100,
              100.50948657,
              100.98130867,
              101.38252022,
              101.68897903,
              101.88825197
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 240
            }
          },
          {
            "value": 20,
            "elided": null
          },
          {
            "value": 10,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          }
        ],
        "output": {
          "true_range": [
            2.1599999999999966,
            2.2298178500000034,
            2.298546210000012,
            2.365112620000005,
            2.4284782999999948,
            2.4876544700000096
          ],
          "atr": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "middle": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "upper": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "lower": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: true_range, atr, middle, upper, lower"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "canonical-trace.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a04/static/canonical-trace.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a04/static/failure-boundary.svg"
          },
          {
            "file": "mechanism-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a04/static/mechanism-map.svg"
          },
          {
            "file": "memory-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a04/static/memory-comparison.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Keltner Channels (KC)",
          "title": "Keltner Channels (KC)",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "New Concepts in Technical Trading Systems",
          "title": "New Concepts in Technical Trading Systems",
          "author": "J. Welles Wilder Jr.",
          "url": null
        },
        {
          "key": "ATR",
          "title": "Average True Range",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "TRANGE",
          "title": "True Range",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Public evidence boundary",
          "title": "Public evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volatility-and-channels/keltner-channels/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volatility-and-channels/keltner-channels/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F04-A05",
      "name": "Donchian Channels",
      "headline": null,
      "slug": "donchian-channels",
      "path": "technical-indicators/volatility-and-channels/donchian-channels",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F04",
        "family": "Volatility and Channels",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volatility-and-channels/donchian-channels",
        "entry": "donchianChannels",
        "params": [
          "high",
          "low",
          "p"
        ],
        "exports": [
          "donchianChannels"
        ],
        "archetype": "series-transform",
        "signature": "donchianChannels(high, low, p)"
      },
      "api": {
        "summary": "The highest high and lowest low of the lookback. The oldest channel in use, and the only one here with no smoothing at all — the bands step rather than glide.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "p",
            "type": "number",
            "required": true,
            "description": "Lookback in bars for both extremes.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `upper`, `lower`, `middle` and `width`."
        },
        "warmup": {
          "count": "p − 1",
          "value": "null"
        },
        "errors": [
          {
            "when": "p < 1 or is not an integer",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n × p)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "donchianChannels([101.08,101.6243955,102.13058177,102.56507653,102.90321818,103.1320792], [98.92,99.39457765,99.83203556,100.19996391,100.47473988,100.64442473], 20)",
        "args": [
          {
            "value": [
              101.08,
              101.6243955,
              102.13058177,
              102.56507653,
              102.90321818,
              103.1320792
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 240
            }
          },
          {
            "value": [
              98.92,
              99.39457765,
              99.83203556,
              100.19996391,
              100.47473988,
              100.64442473
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 240
            }
          },
          {
            "value": 20,
            "elided": null
          }
        ],
        "output": {
          "upper": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "lower": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "middle": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "width": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: upper, lower, middle, width"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "canonical-trace.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a05/static/canonical-trace.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a05/static/failure-boundary.svg"
          },
          {
            "file": "mechanism-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a05/static/mechanism-map.svg"
          },
          {
            "file": "memory-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a05/static/memory-comparison.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Donchian Channels (DC)",
          "title": "Donchian Channels (DC)",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "A Century of Profitable Trends",
          "title": "A Century of Profitable Trends",
          "author": "CMT Association",
          "url": null
        },
        {
          "key": "Public evidence boundary",
          "title": "Public evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volatility-and-channels/donchian-channels/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volatility-and-channels/donchian-channels/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F04-A06",
      "name": "Bollinger BandWidth",
      "headline": null,
      "slug": "bollinger-bandwidth",
      "path": "technical-indicators/volatility-and-channels/bollinger-bandwidth",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F04",
        "family": "Volatility and Channels",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volatility-and-channels/bollinger-bandwidth",
        "entry": "bollingerBandwidth",
        "params": [
          "close",
          "p",
          "multiplier"
        ],
        "exports": [
          "bollingerBands",
          "bollingerBandwidth"
        ],
        "archetype": "series-transform",
        "signature": "bollingerBandwidth(close, p, multiplier)"
      },
      "api": {
        "summary": "The width of a Bollinger channel relative to its middle band. Low readings mark contraction, which historically precedes expansion — the quantity behind every 'squeeze' screen.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "p",
            "type": "number",
            "required": true,
            "description": "Lookback for the average and the standard deviation.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "multiplier",
            "type": "number",
            "required": true,
            "description": "Number of standard deviations to each band.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `middle`, `stddev`, `upper`, `lower` and `bandwidth`."
        },
        "warmup": {
          "count": "p − 1",
          "value": "null"
        },
        "errors": [
          {
            "when": "p < 1, is not an integer, or multiplier is negative",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n × p)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "bollingerBandwidth([100,100.40234656,100.79879348,101.18354586,101.55101638,101.89592451], 20, 2)",
        "args": [
          {
            "value": [
              100,
              100.40234656,
              100.79879348,
              101.18354586,
              101.55101638,
              101.89592451
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 240
            }
          },
          {
            "value": 20,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          }
        ],
        "output": {
          "middle": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "stddev": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "upper": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "lower": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "bandwidth": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: middle, stddev, upper, lower, bandwidth"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "canonical-trace.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a06/static/canonical-trace.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a06/static/failure-boundary.svg"
          },
          {
            "file": "mechanism-map.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a06/static/mechanism-map.svg"
          },
          {
            "file": "memory-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f04-a06/static/memory-comparison.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Bollinger Bands Rules",
          "title": "Bollinger Bands Rules",
          "author": "John Bollinger",
          "url": null
        },
        {
          "key": "Bollinger BandWidth (BBW)",
          "title": "Bollinger BandWidth (BBW)",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "Bollinger Bands (BB)",
          "title": "Bollinger Bands (BB)",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "BBANDS",
          "title": "Bollinger Bands",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "e-Handbook: Measures of Scale",
          "title": "e-Handbook: Measures of Scale",
          "author": "NIST/SEMATECH",
          "url": null
        },
        {
          "key": "Public evidence boundary",
          "title": "Public evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volatility-and-channels/bollinger-bandwidth/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volatility-and-channels/bollinger-bandwidth/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A01",
      "name": "On-Balance Volume (OBV)",
      "headline": null,
      "slug": "obv",
      "path": "technical-indicators/volume-indicators/obv",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/obv",
        "entry": "obv",
        "params": [
          "close",
          "volume",
          "initial"
        ],
        "exports": [
          "obv",
          "accumulationDistributionLine",
          "chaikinMoneyFlow",
          "moneyFlowIndex",
          "volumePriceTrend",
          "forceIndex"
        ],
        "archetype": "series-transform",
        "signature": "obv(close, volume, initial)"
      },
      "api": {
        "summary": "On-balance volume: a running total that adds the bar's volume when price closed up and subtracts it when price closed down. The level is arbitrary; only its direction carries information.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "volume",
            "type": "number[]",
            "required": true,
            "description": "Per-bar traded volume, aligned index-for-index with the price series.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "initial",
            "type": "number",
            "required": false,
            "description": "Starting value of the running total. Only affects the level, never the shape.",
            "constraints": null,
            "nulls": null,
            "default": 0
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `direction`, `volume`, `signed_volume` and the running `obv`."
        },
        "warmup": {
          "count": "0",
          "value": "not applicable — no position is null",
          "note": "The first bar has no prior close, so its direction is 0 and the running total starts at `initial`. Those are defined values rather than warm-up nulls, so every position of every returned series is populated."
        },
        "errors": [
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "obv([100.28,100.686113,101.200346,101.789282,102.408843,103.010585], [990000,1066468.036,1130033.236,1170141.961,1180511.26,1160272.794])",
        "args": [
          {
            "value": [
              100.28,
              100.686113,
              101.200346,
              101.789282,
              102.408843,
              103.010585
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              990000,
              1066468.036,
              1130033.236,
              1170141.961,
              1180511.26,
              1160272.794
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          }
        ],
        "output": {
          "direction": [
            0,
            1,
            1,
            1,
            1,
            1
          ],
          "volume": [
            990000,
            1066468.036,
            1130033.236,
            1170141.961,
            1180511.26,
            1160272.794
          ],
          "signed_volume": [
            0,
            1066468.036,
            1130033.236,
            1170141.961,
            1180511.26,
            1160272.794
          ],
          "obv": [
            0,
            1066468.036,
            2196501.272,
            3366643.233,
            4547154.493,
            5707427.287
          ]
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: direction, volume, signed_volume, obv"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "obv-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a01/static/obv-comparison.svg"
          },
          {
            "file": "obv-mechanism.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a01/static/obv-mechanism.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "On Balance Volume (OBV)",
          "title": "On Balance Volume (OBV)",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "Volume",
          "title": "Volume",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "TA-Lib function API and volume indicators",
          "title": "TA-Lib function API and volume indicators",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Consolidated Tape",
          "title": "Consolidated Tape",
          "author": "U.S. Securities and Exchange Commission, Investor.gov",
          "url": null
        },
        {
          "key": "Closing Price",
          "title": "Closing Price",
          "author": "U.S. Securities and Exchange Commission, Investor.gov",
          "url": null
        },
        {
          "key": "What is Volume?",
          "title": "What is Volume?",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "Claim-role ledger",
          "title": "Claim-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        },
        {
          "key": "Enhanced claim-to-source map",
          "title": "Enhanced claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "Public evidence boundary",
          "title": "Public evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/obv/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/obv/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A02",
      "name": "Accumulation/Distribution Line",
      "headline": null,
      "slug": "accumulation-distribution-line",
      "path": "technical-indicators/volume-indicators/accumulation-distribution-line",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/accumulation-distribution-line",
        "entry": "accumulationDistributionLine",
        "params": [
          "high",
          "low",
          "close",
          "volume",
          "initial"
        ],
        "exports": [
          "obv",
          "accumulationDistributionLine",
          "chaikinMoneyFlow",
          "moneyFlowIndex",
          "volumePriceTrend",
          "forceIndex"
        ],
        "archetype": "series-transform",
        "signature": "accumulationDistributionLine(high, low, close, volume, initial)"
      },
      "api": {
        "summary": "Weights each bar's volume by where the close sat within that bar's range, then accumulates. Unlike OBV it distinguishes a close at the high from a close barely above the open.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "volume",
            "type": "number[]",
            "required": true,
            "description": "Per-bar traded volume, aligned index-for-index with the price series.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "initial",
            "type": "number",
            "required": false,
            "description": "Starting value of the accumulation.",
            "constraints": null,
            "nulls": null,
            "default": 0
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `range`, `money_flow_multiplier`, `volume`, `money_flow_volume` and `adl`."
        },
        "warmup": {
          "count": "0",
          "value": "null",
          "note": "Defined from the first bar; a zero-range bar contributes nothing rather than dividing by zero."
        },
        "errors": [
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "accumulationDistributionLine([101.05,101.52482,102.098461,102.729464,103.36806,103.963227], [99.4,99.462904,99.936275,100.512674,101.151059,101.802588], [100.28,100.686113,101.200346,101.789282,102.408843,103.010585], [990000,1066468.036,1130033.236,1170141.961,1180511.26,1160272.794])",
        "args": [
          {
            "value": [
              101.05,
              101.52482,
              102.098461,
              102.729464,
              103.36806,
              103.963227
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              99.4,
              99.462904,
              99.936275,
              100.512674,
              101.151059,
              101.802588
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              100.28,
              100.686113,
              101.200346,
              101.789282,
              102.408843,
              103.010585
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              990000,
              1066468.036,
              1130033.236,
              1170141.961,
              1180511.26,
              1160272.794
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          }
        ],
        "output": {
          "range": [
            1.6499999999999915,
            2.0619160000000107,
            2.1621860000000055,
            2.216789999999989,
            2.2170009999999962,
            2.1606390000000033
          ],
          "money_flow_multiplier": [
            0.06666666666666667,
            0.1864780136533253,
            0.16925278398805474,
            0.1517626838807486,
            0.1346715675816141,
            0.118184944361371
          ],
          "volume": [
            990000,
            1066468.036,
            1130033.236,
            1170141.961,
            1180511.26,
            1160272.794
          ],
          "money_flow_volume": [
            66000,
            198872.84097804304,
            191261.2711920305,
            177583.88452284224,
            158981.30193194642,
            137126.7756029025
          ],
          "adl": [
            66000,
            264872.84097804304,
            456134.11217007355,
            633717.9966929158,
            792699.2986248622,
            929826.0742277647
          ]
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: range, money_flow_multiplier, volume, money_flow_volume, adl"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "accumulation-distribution-line-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a02/static/accumulation-distribution-line-comparison.svg"
          },
          {
            "file": "accumulation-distribution-line-mechanism.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a02/static/accumulation-distribution-line-mechanism.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Accumulation Distribution (ADL)",
          "title": "Accumulation Distribution (ADL)",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "Chaikin Oscillator",
          "title": "Chaikin Oscillator",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "Volume",
          "title": "Volume",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "TA-Lib function API and volume indicators",
          "title": "TA-Lib function API and volume indicators",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Consolidated Tape",
          "title": "Consolidated Tape",
          "author": "U.S. Securities and Exchange Commission, Investor.gov",
          "url": null
        },
        {
          "key": "Closing Price",
          "title": "Closing Price",
          "author": "U.S. Securities and Exchange Commission, Investor.gov",
          "url": null
        },
        {
          "key": "What is Volume?",
          "title": "What is Volume?",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "Claim-role ledger",
          "title": "Claim-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        },
        {
          "key": "Enhanced claim-to-source map",
          "title": "Enhanced claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "Public evidence boundary",
          "title": "Public evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/accumulation-distribution-line/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/accumulation-distribution-line/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A03",
      "name": "Chaikin Money Flow",
      "headline": null,
      "slug": "chaikin-money-flow",
      "path": "technical-indicators/volume-indicators/chaikin-money-flow",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/chaikin-money-flow",
        "entry": "chaikinMoneyFlow",
        "params": [
          "high",
          "low",
          "close",
          "volume",
          "p"
        ],
        "exports": [
          "obv",
          "accumulationDistributionLine",
          "chaikinMoneyFlow",
          "moneyFlowIndex",
          "volumePriceTrend",
          "forceIndex"
        ],
        "archetype": "series-transform",
        "signature": "chaikinMoneyFlow(high, low, close, volume, p)"
      },
      "api": {
        "summary": "Money-flow volume summed over a lookback and divided by total volume over the same window — the accumulation/distribution idea as a bounded oscillator rather than a running total.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "volume",
            "type": "number[]",
            "required": true,
            "description": "Per-bar traded volume, aligned index-for-index with the price series.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "p",
            "type": "number",
            "required": true,
            "description": "Lookback in bars.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `money_flow_multiplier`, `money_flow_volume`, `rolling_mfv`, `rolling_volume` and `cmf`."
        },
        "warmup": {
          "count": "p − 1",
          "value": "null"
        },
        "errors": [
          {
            "when": "p < 1 or is not an integer",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "chaikinMoneyFlow([101.05,101.52482,102.098461,102.729464,103.36806,103.963227], [99.4,99.462904,99.936275,100.512674,101.151059,101.802588], [100.28,100.686113,101.200346,101.789282,102.408843,103.010585], [990000,1066468.036,1130033.236,1170141.961,1180511.26,1160272.794])",
        "args": [
          {
            "value": [
              101.05,
              101.52482,
              102.098461,
              102.729464,
              103.36806,
              103.963227
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              99.4,
              99.462904,
              99.936275,
              100.512674,
              101.151059,
              101.802588
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              100.28,
              100.686113,
              101.200346,
              101.789282,
              102.408843,
              103.010585
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              990000,
              1066468.036,
              1130033.236,
              1170141.961,
              1180511.26,
              1160272.794
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          }
        ],
        "output": {
          "money_flow_multiplier": [
            0.06666666666666667,
            0.1864780136533253,
            0.16925278398805474,
            0.1517626838807486,
            0.1346715675816141,
            0.118184944361371
          ],
          "money_flow_volume": [
            66000,
            198872.84097804304,
            191261.2711920305,
            177583.88452284224,
            158981.30193194642,
            137126.7756029025
          ],
          "rolling_mfv": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "rolling_volume": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "cmf": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: money_flow_multiplier, money_flow_volume, rolling_mfv, rolling_volume, cmf"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "chaikin-money-flow-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a03/static/chaikin-money-flow-comparison.svg"
          },
          {
            "file": "chaikin-money-flow-mechanism.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a03/static/chaikin-money-flow-mechanism.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Chaikin Money Flow",
          "title": "Chaikin Money Flow",
          "author": "Chaikin Analytics",
          "url": null
        },
        {
          "key": "Chaikin Oscillator",
          "title": "Chaikin Oscillator",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "Volume",
          "title": "Volume",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "Consolidated Tape",
          "title": "Consolidated Tape",
          "author": "U.S. Securities and Exchange Commission, Investor.gov",
          "url": null
        },
        {
          "key": "Closing Price",
          "title": "Closing Price",
          "author": "U.S. Securities and Exchange Commission, Investor.gov",
          "url": null
        },
        {
          "key": "What is Volume?",
          "title": "What is Volume?",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "Claim-role ledger",
          "title": "Claim-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        },
        {
          "key": "Enhanced claim-to-source map",
          "title": "Enhanced claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "Public evidence boundary",
          "title": "Public evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/chaikin-money-flow/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/chaikin-money-flow/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A04",
      "name": "Money Flow Index",
      "headline": null,
      "slug": "money-flow-index",
      "path": "technical-indicators/volume-indicators/money-flow-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/money-flow-index",
        "entry": "moneyFlowIndex",
        "params": [
          "high",
          "low",
          "close",
          "volume",
          "p"
        ],
        "exports": [
          "obv",
          "accumulationDistributionLine",
          "chaikinMoneyFlow",
          "moneyFlowIndex",
          "volumePriceTrend",
          "forceIndex"
        ],
        "archetype": "series-transform",
        "signature": "moneyFlowIndex(high, low, close, volume, p)"
      },
      "api": {
        "summary": "RSI computed on typical price weighted by volume — commonly described as volume-weighted RSI, and read on the same 0–100 scale.",
        "params": [
          {
            "name": "high",
            "type": "number[]",
            "required": true,
            "description": "Per-bar high prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number[]",
            "required": true,
            "description": "Per-bar low prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "volume",
            "type": "number[]",
            "required": true,
            "description": "Per-bar traded volume, aligned index-for-index with the price series.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "p",
            "type": "number",
            "required": true,
            "description": "Lookback in bars.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `typical_price`, `raw_money_flow`, `positive_flow`, `negative_flow`, `money_flow_ratio` and `mfi`."
        },
        "warmup": {
          "count": "p",
          "value": "null",
          "note": "One extra bar is needed beyond the window, because the first bar has no prior typical price to compare against."
        },
        "errors": [
          {
            "when": "p < 1 or is not an integer",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "moneyFlowIndex([101.05,101.52482,102.098461,102.729464,103.36806,103.963227], [99.4,99.462904,99.936275,100.512674,101.151059,101.802588], [100.28,100.686113,101.200346,101.789282,102.408843,103.010585], [990000,1066468.036,1130033.236,1170141.961,1180511.26,1160272.794])",
        "args": [
          {
            "value": [
              101.05,
              101.52482,
              102.098461,
              102.729464,
              103.36806,
              103.963227
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              99.4,
              99.462904,
              99.936275,
              100.512674,
              101.151059,
              101.802588
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              100.28,
              100.686113,
              101.200346,
              101.789282,
              102.408843,
              103.010585
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              990000,
              1066468.036,
              1130033.236,
              1170141.961,
              1180511.26,
              1160272.794
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          }
        ],
        "output": {
          "typical_price": [
            100.24333333333334,
            100.55794566666668,
            101.07836066666668,
            101.67714000000001,
            102.30932066666666,
            102.92546666666668
          ],
          "raw_money_flow": [
            99240900,
            107241834.81932473,
            114221906.99372847,
            118976687.98847154,
            120777305.0499507,
            119421618.78308721
          ],
          "positive_flow": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "negative_flow": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "money_flow_ratio": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "mfi": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: typical_price, raw_money_flow, positive_flow, negative_flow, money_flow_ratio, mfi"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "money-flow-index-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a04/static/money-flow-index-comparison.svg"
          },
          {
            "file": "money-flow-index-mechanism.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a04/static/money-flow-index-mechanism.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Money Flow (MFI)",
          "title": "Money Flow (MFI)",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "Volume",
          "title": "Volume",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "TA-Lib function API and volume indicators",
          "title": "TA-Lib function API and volume indicators",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Consolidated Tape",
          "title": "Consolidated Tape",
          "author": "U.S. Securities and Exchange Commission, Investor.gov",
          "url": null
        },
        {
          "key": "Closing Price",
          "title": "Closing Price",
          "author": "U.S. Securities and Exchange Commission, Investor.gov",
          "url": null
        },
        {
          "key": "What is Volume?",
          "title": "What is Volume?",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "TA-Lib momentum indicator functions",
          "title": "TA-Lib momentum indicator functions",
          "author": "TA-Lib",
          "url": null
        },
        {
          "key": "Claim-role ledger",
          "title": "Claim-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        },
        {
          "key": "Enhanced claim-to-source map",
          "title": "Enhanced claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "Public evidence boundary",
          "title": "Public evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/money-flow-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/money-flow-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A05",
      "name": "Volume Price Trend",
      "headline": null,
      "slug": "volume-price-trend",
      "path": "technical-indicators/volume-indicators/volume-price-trend",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/volume-price-trend",
        "entry": "volumePriceTrend",
        "params": [
          "close",
          "volume",
          "initial"
        ],
        "exports": [
          "obv",
          "accumulationDistributionLine",
          "chaikinMoneyFlow",
          "moneyFlowIndex",
          "volumePriceTrend",
          "forceIndex"
        ],
        "archetype": "series-transform",
        "signature": "volumePriceTrend(close, volume, initial)"
      },
      "api": {
        "summary": "Like OBV, but each bar contributes volume scaled by the size of the return rather than only its sign — so a 3% move counts for more than a 0.1% one.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "volume",
            "type": "number[]",
            "required": true,
            "description": "Per-bar traded volume, aligned index-for-index with the price series.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "initial",
            "type": "number",
            "required": false,
            "description": "Starting value of the running total.",
            "constraints": null,
            "nulls": null,
            "default": 0
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `price_return`, `volume`, `volume_contribution` and `vpt`."
        },
        "warmup": {
          "count": "1",
          "value": "null",
          "note": "The first bar has no prior close, so no return."
        },
        "errors": [
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "volumePriceTrend([100.28,100.686113,101.200346,101.789282,102.408843,103.010585], [990000,1066468.036,1130033.236,1170141.961,1180511.26,1160272.794])",
        "args": [
          {
            "value": [
              100.28,
              100.686113,
              101.200346,
              101.789282,
              102.408843,
              103.010585
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              990000,
              1066468.036,
              1130033.236,
              1170141.961,
              1180511.26,
              1160272.794
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          }
        ],
        "output": {
          "price_return": [
            0,
            0.004049790586358245,
            0.005107288231496136,
            0.005819505794970345,
            0.006086701741348411,
            0.005875879292963026
          ],
          "volume": [
            990000,
            1066468.036,
            1130033.236,
            1170141.961,
            1180511.26,
            1160272.794
          ],
          "volume_contribution": [
            0,
            4318.972212844767,
            5771.405447422296,
            6809.647922977462,
            7185.419941923407,
            6817.622884452954
          ],
          "vpt": [
            0,
            4318.972212844767,
            10090.377660267062,
            16900.025583244525,
            24085.445525167932,
            30903.068409620886
          ]
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: price_return, volume, volume_contribution, vpt"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "volume-price-trend-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a05/static/volume-price-trend-comparison.svg"
          },
          {
            "file": "volume-price-trend-mechanism.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a05/static/volume-price-trend-mechanism.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Price Volume Trend (PVT)",
          "title": "Price Volume Trend (PVT)",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "On Balance Volume (OBV)",
          "title": "On Balance Volume (OBV)",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "Volume",
          "title": "Volume",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "Consolidated Tape",
          "title": "Consolidated Tape",
          "author": "U.S. Securities and Exchange Commission, Investor.gov",
          "url": null
        },
        {
          "key": "Closing Price",
          "title": "Closing Price",
          "author": "U.S. Securities and Exchange Commission, Investor.gov",
          "url": null
        },
        {
          "key": "What is Volume?",
          "title": "What is Volume?",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "Claim-role ledger",
          "title": "Claim-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        },
        {
          "key": "Enhanced claim-to-source map",
          "title": "Enhanced claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "Public evidence boundary",
          "title": "Public evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/volume-price-trend/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/volume-price-trend/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D07-F05-A06",
      "name": "Force Index",
      "headline": null,
      "slug": "force-index",
      "path": "technical-indicators/volume-indicators/force-index",
      "taxonomy": {
        "domainId": "D07",
        "domain": "Technical Indicators",
        "familyId": "D07-F05",
        "family": "Volume Indicators",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/technical-indicators/volume-indicators/force-index",
        "entry": "forceIndex",
        "params": [
          "close",
          "volume",
          "p"
        ],
        "exports": [
          "obv",
          "accumulationDistributionLine",
          "chaikinMoneyFlow",
          "moneyFlowIndex",
          "volumePriceTrend",
          "forceIndex"
        ],
        "archetype": "series-transform",
        "signature": "forceIndex(close, volume, p)"
      },
      "api": {
        "summary": "Price change multiplied by volume, then smoothed. Combines direction, size and participation in one number — a large move on no volume scores low.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Per-bar closing prices, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "volume",
            "type": "number[]",
            "required": true,
            "description": "Per-bar traded volume, aligned index-for-index with the price series.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "p",
            "type": "number",
            "required": true,
            "description": "EMA span applied to the raw force series.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "Record<string, (number | null)[]>",
          "length": "same-as-input",
          "description": "Parallel series: `change`, `volume`, `raw_force`, `ema_seed` and the smoothed `force_index`."
        },
        "warmup": {
          "count": "p",
          "value": "null",
          "note": "One bar for the price change, then the EMA seed window."
        },
        "errors": [
          {
            "when": "p < 1 or is not an integer",
            "behaviour": "throws RangeError"
          },
          {
            "when": "the input series are not all the same length",
            "behaviour": "throws RangeError"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "forceIndex([100.28,100.686113,101.200346,101.789282,102.408843,103.010585], [990000,1066468.036,1130033.236,1170141.961,1180511.26,1160272.794])",
        "args": [
          {
            "value": [
              100.28,
              100.686113,
              101.200346,
              101.789282,
              102.408843,
              103.010585
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          },
          {
            "value": [
              990000,
              1066468.036,
              1130033.236,
              1170141.961,
              1180511.26,
              1160272.794
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 120
            }
          }
        ],
        "output": {
          "change": [
            null,
            0.40611300000000483,
            0.5142329999999902,
            0.5889360000000039,
            0.6195610000000045,
            0.6017420000000016
          ],
          "volume": [
            990000,
            1066468.036,
            1130033.236,
            1170141.961,
            1180511.26,
            1160272.794
          ],
          "raw_force": [
            null,
            433106.53350407316,
            581100.3810479769,
            689138.7259435005,
            731398.7367568653,
            698184.8716071498
          ],
          "ema_seed": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "force_index": [
            null,
            null,
            null,
            null,
            null,
            null
          ]
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: change, volume, raw_force, ema_seed, force_index"
      },
      "verification": {
        "tier": "verified",
        "via": "scenario-fixture"
      },
      "assets": {
        "diagrams": [
          {
            "file": "force-index-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a06/static/force-index-comparison.svg"
          },
          {
            "file": "force-index-mechanism.svg",
            "url": "https://thefintechbuilder.com/content/d07-f05-a06/static/force-index-mechanism.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Elder's Force Index (EFI)",
          "title": "Elder's Force Index (EFI)",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "Volume",
          "title": "Volume",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "Consolidated Tape",
          "title": "Consolidated Tape",
          "author": "U.S. Securities and Exchange Commission, Investor.gov",
          "url": null
        },
        {
          "key": "Closing Price",
          "title": "Closing Price",
          "author": "U.S. Securities and Exchange Commission, Investor.gov",
          "url": null
        },
        {
          "key": "What is Volume?",
          "title": "What is Volume?",
          "author": "CME Group",
          "url": null
        },
        {
          "key": "Claim-role ledger",
          "title": "Claim-role ledger",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        },
        {
          "key": "Enhanced claim-to-source map",
          "title": "Enhanced claim-to-source map",
          "author": null,
          "url": null
        },
        {
          "key": "Public evidence boundary",
          "title": "Public evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/technical-indicators/volume-indicators/force-index/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/technical-indicators/volume-indicators/force-index/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F01-A01",
      "name": "Causal Pivot Detection",
      "headline": null,
      "slug": "causal-pivot-detection",
      "path": "geometric-chart-patterns/pivots-and-levels/causal-pivot-detection",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F01",
        "family": "Pivots and Levels",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/pivots-and-levels/causal-pivot-detection",
        "entry": "detectCausalPivots",
        "params": [
          "bars",
          "leftSpan",
          "rightSpan",
          "minSeparation"
        ],
        "exports": [
          "detectCausalPivots"
        ],
        "archetype": "row-classify",
        "signature": "detectCausalPivots(bars, leftSpan, rightSpan, minSeparation)"
      },
      "api": {
        "summary": "Finds swing highs and lows using only bars that had already arrived. Most pivot code confirms a pivot with bars that come *after* it and then plots it at the earlier index — which is lookahead bias, and it is invisible on a chart.",
        "params": [
          {
            "name": "bars",
            "type": "Bar[]",
            "required": true,
            "description": "OHLC bars in chronological order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "leftSpan",
            "type": "number",
            "required": true,
            "description": "Bars before the candidate that must be lower (or higher).",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "rightSpan",
            "type": "number",
            "required": true,
            "description": "Bars after the candidate required to confirm it. **This is the confirmation lag**: a pivot at index `i` is not knowable until `i + rightSpan`.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "minSeparation",
            "type": "number",
            "required": true,
            "description": "Minimum bars between accepted pivots, which stops a noisy region producing a cluster of them.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ kind, event_index, confirmation_index, price }[]",
          "description": "Both indices are returned deliberately: `event_index` is where the pivot occurred and `confirmation_index` is when you could have known. Any backtest must use the second."
        },
        "warmup": null,
        "errors": [
          {
            "when": "leftSpan or rightSpan is less than 1",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × span)",
          "space": "O(pivots)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D08-F01-A01.json",
        "call": "detectCausalPivots([{\"timestamp\":\"2026-01-01T00:00:00Z\",\"high\":10,\"low\":8,\"close\":9},{\"timestamp\":\"2026-01-01T01:00:00Z\",\"high\":12,\"low\":10,\"close\":11},{\"timestamp\":\"2026-01-01T02:00:00Z\",\"high\":15,\"low\":13,\"close\":14}], 2, 2, 0)",
        "args": [
          {
            "value": [
              {
                "timestamp": "2026-01-01T00:00:00Z",
                "high": 10,
                "low": 8,
                "close": 9
              },
              {
                "timestamp": "2026-01-01T01:00:00Z",
                "high": 12,
                "low": 10,
                "close": 11
              },
              {
                "timestamp": "2026-01-01T02:00:00Z",
                "high": 15,
                "low": 13,
                "close": 14
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": 2,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          },
          {
            "value": 0,
            "elided": null
          }
        ],
        "output": {
          "0": {
            "kind": "high",
            "event_index": 2,
            "confirmation_index": 4,
            "price": 15,
            "separation": 2,
            "latency": 2
          }
        },
        "outputElided": null,
        "outputShape": "object with 1 field: 0"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "failure-atlas.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a01/static/failure-atlas.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a01/static/family-handoff.svg"
          },
          {
            "file": "knowledge-time.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a01/static/knowledge-time.svg"
          },
          {
            "file": "parameter-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a01/static/parameter-boundary.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "TV_TECHNIQUES",
          "title": "Pine Script Techniques: pivots",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "TV_REPAINT",
          "title": "Pine Script Concepts: Repainting",
          "author": "TradingView",
          "url": null
        },
        {
          "key": "SCIPY_PEAKS",
          "title": "scipy.signal.find_peaks",
          "author": "SciPy project",
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pivots-and-levels/causal-pivot-detection/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pivots-and-levels/causal-pivot-detection/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F01-A02",
      "name": "ZigZag Segmentation",
      "headline": null,
      "slug": "zigzag-segmentation",
      "path": "geometric-chart-patterns/pivots-and-levels/zigzag-segmentation",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F01",
        "family": "Pivots and Levels",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/pivots-and-levels/zigzag-segmentation",
        "entry": "zigzagSegment",
        "params": [
          "closes",
          "threshold",
          "minBars"
        ],
        "exports": [
          "zigzagSegment"
        ],
        "archetype": "record-transform",
        "signature": "zigzagSegment(closes, threshold, minBars)"
      },
      "api": {
        "summary": "Segments a series into alternating swings that exceed a percentage threshold. Useful for structure, and routinely misused: the final swing is provisional and can be revised by the next bar.",
        "params": [
          {
            "name": "closes",
            "type": "number[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "threshold",
            "type": "number",
            "required": true,
            "description": "Minimum retracement, as a fraction, before a reversal is accepted.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "minBars",
            "type": "number",
            "required": true,
            "description": "Minimum bars a swing must span.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ pivots, states }",
          "description": "The pivots with a per-bar state, which is what shows the last swing is still open rather than settled."
        },
        "warmup": null,
        "errors": [
          {
            "when": "threshold is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D08-F01-A02.json",
        "call": "zigzagSegment([100,103,106,101,100], 0.05, 2)",
        "args": [
          {
            "value": [
              100,
              103,
              106,
              101,
              100
            ],
            "elided": null
          },
          {
            "value": 0.05,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          }
        ],
        "output": {
          "pivots": [
            {
              "kind": "low",
              "event_index": 0,
              "confirmation_index": 2,
              "price": 100
            },
            {
              "kind": "high",
              "event_index": 2,
              "confirmation_index": 4,
              "price": 106
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 1 field: pivots"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "failure-atlas.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a02/static/failure-atlas.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a02/static/family-handoff.svg"
          },
          {
            "file": "knowledge-time.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a02/static/knowledge-time.svg"
          },
          {
            "file": "parameter-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a02/static/parameter-boundary.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "LEAN_ZIGZAG_DOC",
          "title": "Zig Zag indicator",
          "author": "QuantConnect",
          "url": null
        },
        {
          "key": "LEAN_ZIGZAG_CODE",
          "title": "LEAN ZigZag source",
          "author": "QuantConnect",
          "url": null
        },
        {
          "key": "TV_REPAINT",
          "title": "Pine Script Concepts: Repainting",
          "author": "TradingView",
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pivots-and-levels/zigzag-segmentation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pivots-and-levels/zigzag-segmentation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F01-A03",
      "name": "Support/Resistance Clustering",
      "headline": null,
      "slug": "support-resistance-clustering",
      "path": "geometric-chart-patterns/pivots-and-levels/support-resistance-clustering",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F01",
        "family": "Pivots and Levels",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/pivots-and-levels/support-resistance-clustering",
        "entry": "clusterPivotLevels",
        "params": [
          "pivots",
          "epsBps",
          "minTouches"
        ],
        "exports": [
          "detectCausalPivots",
          "clusterPivotLevels"
        ],
        "archetype": "record-transform",
        "signature": "clusterPivotLevels(pivots, epsBps, minTouches)"
      },
      "api": {
        "summary": "Groups nearby pivots into levels. Clustering in basis points rather than absolute price is what makes the result meaningful across instruments — a $1 band is noise on one stock and a whole level on another.",
        "params": [
          {
            "name": "pivots",
            "type": "Pivot[]",
            "required": true,
            "description": "Pivots from causal detection, carrying kind, indices and price.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "epsBps",
            "type": "number",
            "required": true,
            "description": "Clustering radius in basis points.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "minTouches",
            "type": "number",
            "required": true,
            "description": "Minimum pivots required before a cluster counts as a level; below it the group is returned as noise rather than dropped.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ clusters, noise }",
          "description": "Accepted levels and the rejected groups — visible, because 'no level here' is itself informative."
        },
        "warmup": null,
        "errors": [
          {
            "when": "epsBps is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D08-F01-A03.json",
        "call": "clusterPivotLevels([{\"kind\":\"high\",\"event_index\":0,\"confirmation_index\":1,\"price\":100},{\"kind\":\"high\",\"event_index\":2,\"confirmation_index\":3,\"price\":100.3},{\"kind\":\"high\",\"event_index\":4,\"confirmation_index\":5,\"price\":99.9}], 50, 3)",
        "args": [
          {
            "value": [
              {
                "kind": "high",
                "event_index": 0,
                "confirmation_index": 1,
                "price": 100
              },
              {
                "kind": "high",
                "event_index": 2,
                "confirmation_index": 3,
                "price": 100.3
              },
              {
                "kind": "high",
                "event_index": 4,
                "confirmation_index": 5,
                "price": 99.9
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 4
            }
          },
          {
            "value": 50,
            "elided": null
          },
          {
            "value": 3,
            "elided": null
          }
        ],
        "output": {
          "clusters": [
            {
              "kind": "high",
              "cluster_id": "high-0",
              "level": 100,
              "lower": 99.9,
              "upper": 100.3,
              "touch_count": 3,
              "first_confirmation_index": 1,
              "last_confirmation_index": 5,
              "member_event_indexes": [
                0,
                2,
                4
              ]
            }
          ],
          "noise": [
            {
              "kind": "high",
              "event_index": 6,
              "confirmation_index": 7,
              "price": 105
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 2 fields: clusters, noise"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "failure-atlas.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a03/static/failure-atlas.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a03/static/family-handoff.svg"
          },
          {
            "file": "knowledge-time.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a03/static/knowledge-time.svg"
          },
          {
            "file": "parameter-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a03/static/parameter-boundary.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "DBSCAN_PAPER",
          "title": "A Density-Based Algorithm for Discovering Clusters in Large Spatial Databases with Noise",
          "author": "Martin Ester, Hans-Peter Kriegel, Jorg Sander, Xiaowei Xu",
          "url": null
        },
        {
          "key": "SKLEARN_DBSCAN",
          "title": "sklearn.cluster.DBSCAN",
          "author": "scikit-learn project",
          "url": null
        },
        {
          "key": "TV_REPAINT",
          "title": "Pine Script Concepts: Repainting",
          "author": "TradingView",
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pivots-and-levels/support-resistance-clustering/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pivots-and-levels/support-resistance-clustering/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F01-A04",
      "name": "Robust Trendline Fitting",
      "headline": null,
      "slug": "robust-trendline-fitting",
      "path": "geometric-chart-patterns/pivots-and-levels/robust-trendline-fitting",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F01",
        "family": "Pivots and Levels",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/pivots-and-levels/robust-trendline-fitting",
        "entry": "fitRobustTrendline",
        "params": [
          "pivots",
          "kind",
          "toleranceBps",
          "minInliers",
          "maxPoints"
        ],
        "exports": [
          "detectCausalPivots",
          "fitRobustTrendline"
        ],
        "archetype": "record-transform",
        "signature": "fitRobustTrendline(pivots, kind, toleranceBps, minInliers, maxPoints)"
      },
      "api": {
        "summary": "Fits a trendline through pivots in log space with outlier resistance. Log space matters: a straight line in price implies a constant *dollar* change per bar, which is not what a trend on a long chart means.",
        "params": [
          {
            "name": "pivots",
            "type": "Pivot[]",
            "required": true,
            "description": "Pivots to fit through.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "kind",
            "type": "\"support\" | \"resistance\"",
            "required": true,
            "description": "Which side to fit, which decides how violations are treated.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "toleranceBps",
            "type": "number",
            "required": true,
            "description": "How far a pivot may sit from the line and still count as an inlier.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "minInliers",
            "type": "number",
            "required": true,
            "description": "Minimum inliers for the fit to be accepted.",
            "constraints": {
              "min": 2,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "maxPoints",
            "type": "number",
            "required": true,
            "description": "Cap on pivots considered, bounding the search.",
            "constraints": {
              "min": 2,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ kind, slope_log_per_bar, intercept_log, projected_index, projected_price, inlier_count, … }",
          "description": "The fit in log space plus its projection in price, with the inlier count — a two-point 'trendline' is arithmetic, not evidence."
        },
        "warmup": null,
        "errors": [
          {
            "when": "fewer pivots are supplied than minInliers",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(points²)",
          "space": "O(points)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D08-F01-A04.json",
        "call": "fitRobustTrendline([{\"kind\":\"low\",\"event_index\":0,\"confirmation_index\":2,\"price\":99.48431564193378},{\"kind\":\"low\",\"event_index\":10,\"confirmation_index\":12,\"price\":109.94717245212352},{\"kind\":\"low\",\"event_index\":20,\"confirmation_index\":22,\"price\":121.51041751873485}], \"low\", 50, 3, 12)",
        "args": [
          {
            "value": [
              {
                "kind": "low",
                "event_index": 0,
                "confirmation_index": 2,
                "price": 99.48431564193378
              },
              {
                "kind": "low",
                "event_index": 10,
                "confirmation_index": 12,
                "price": 109.94717245212352
              },
              {
                "kind": "low",
                "event_index": 20,
                "confirmation_index": 22,
                "price": 121.51041751873485
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 4
            }
          },
          {
            "value": "low",
            "elided": null
          },
          {
            "value": 50,
            "elided": null
          },
          {
            "value": 3,
            "elided": null
          },
          {
            "value": 12,
            "elided": null
          }
        ],
        "output": {
          "kind": "low",
          "slope_log_per_bar": 0.010000000000000009,
          "intercept_log": 4.6,
          "projected_index": 31,
          "projected_price": 135.63941440846523,
          "inlier_count": 3,
          "outlier_count": 1,
          "median_absolute_residual_bps": 0,
          "inlier_event_indexes": [
            0,
            10,
            20
          ],
          "source_pivot_count": 4
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: kind, slope_log_per_bar, intercept_log, projected_index, projected_price, inlier_count, outlier_count, median_absolute_residual_bps, …"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "failure-atlas.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a04/static/failure-atlas.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a04/static/family-handoff.svg"
          },
          {
            "file": "knowledge-time.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a04/static/knowledge-time.svg"
          },
          {
            "file": "parameter-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d08-f01-a04/static/parameter-boundary.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "RANSAC_PAPER",
          "title": "Random Sample Consensus: A Paradigm for Model Fitting",
          "author": "Martin A. Fischler and Robert C. Bolles",
          "url": null
        },
        {
          "key": "SKLEARN_RANSAC",
          "title": "sklearn.linear_model.RANSACRegressor",
          "author": "scikit-learn project",
          "url": null
        },
        {
          "key": "NIST_LS",
          "title": "Linear Least Squares Regression",
          "author": "NIST/SEMATECH",
          "url": null
        },
        {
          "key": "TV_REPAINT",
          "title": "Pine Script Concepts: Repainting",
          "author": "TradingView",
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/pivots-and-levels/robust-trendline-fitting/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/pivots-and-levels/robust-trendline-fitting/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F02-A01",
      "name": "Double Top",
      "headline": null,
      "slug": "double-top",
      "path": "geometric-chart-patterns/reversal-structures/double-top",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F02",
        "family": "Reversal Structures",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/reversal-structures/double-top",
        "entry": "doubleTop",
        "params": [
          "close",
          "params"
        ],
        "exports": [
          "confirmedPivots",
          "detectReversal",
          "traceReversal",
          "doubleTop"
        ],
        "archetype": "record-transform",
        "signature": "doubleTop(close, params)"
      },
      "api": {
        "summary": "Double top detection: two comparable highs separated by a trough, confirmed on a close below the neckline. Chart patterns are usually described in prose vague enough to fit almost anything; encoding one forces a decision about how close \"comparable\" is and how much confirmation is required, and this returns those tolerances alongside the verdict. This topic wrapper accepts the close series and detection parameters, then delegates to the family detector core.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Finite, strictly positive closes in chronological order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "params",
            "type": "Record<string, number>",
            "required": false,
            "description": "Optional pivot, geometry, prior-trend, and confirmation overrides; unknown keys are rejected.",
            "constraints": null,
            "nulls": null,
            "default": "{}"
          }
        ],
        "returns": {
          "type": "{ pattern, state, reason, event, events, pivots, parameters }",
          "description": "A `state` rather than a boolean — searching, candidate, confirmed, or rejected — with the `reason`, the pivots that formed it, and the `parameters` in force. The parameters are the point: the same series yields a different answer under different tolerances, and a pattern reported without them cannot be reproduced."
        },
        "warmup": null,
        "errors": [
          {
            "when": "close is empty, non-finite, zero, or negative",
            "behaviour": "throws an Error"
          },
          {
            "when": "a parameter is unknown or outside its accepted range",
            "behaviour": "throws an Error"
          },
          {
            "when": "a valid non-empty series has insufficient confirmed pivots",
            "behaviour": "returns state `searching` rather than throwing"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(pivots)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "doubleTop([100,101,102,103,104,105])",
        "args": [
          {
            "value": [
              100,
              101,
              102,
              103,
              104,
              105
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 72
            }
          }
        ],
        "output": {
          "pattern": "double_top",
          "state": "confirmed",
          "reason": "neckline-break-confirmed",
          "event": {
            "pattern": "double_top",
            "pivot_indices": [
              14,
              22,
              30
            ],
            "pivot_prices": [
              120,
              110,
              121
            ],
            "pivot_types": [
              "high",
              "low",
              "high"
            ],
            "candidate_available_index": 32,
            "confirmation_index": 40,
            "neckline": 110,
            "metrics": {
              "test_mean": 120.5,
              "level_spread": 0.008298755186721992,
              "retracement_min": 0.08713692946058091,
              "head_dominance": null,
              "formation_bars": 16,
              "min_separation": 8
            },
            "prior_move": 0.1,
            "state": "confirmed",
            "reason": "neckline-break-confirmed",
            "direction": "bearish"
          },
          "events": [
            {
              "pattern": "double_top",
              "pivot_indices": [
                14,
                22,
                30
              ],
              "pivot_prices": [
                120,
                110,
                121
              ],
              "pivot_types": [
                "high",
                "low",
                "high"
              ],
              "candidate_available_index": 32,
              "confirmation_index": 40,
              "neckline": 110,
              "metrics": {
                "test_mean": 120.5,
                "level_spread": 0.008298755186721992,
                "retracement_min": 0.08713692946058091,
                "head_dominance": null,
                "formation_bars": 16,
                "min_separation": 8
              },
              "prior_move": 0.1,
              "state": "confirmed",
              "reason": "neckline-break-confirmed",
              "direction": "bearish"
            }
          ],
          "pivots": [
            {
              "kind": "high",
              "index": 14,
              "confirmation_index": 16,
              "price": 120
            },
            {
              "kind": "low",
              "index": 22,
              "confirmation_index": 24,
              "price": 110
            },
            {
              "kind": "high",
              "index": 30,
              "confirmation_index": 32,
              "price": 121
            }
          ],
          "parameters": {
            "pivot_left": 2,
            "pivot_right": 2,
            "min_swing_bars": 5,
            "max_pattern_bars": 40,
            "max_confirmation_bars": 15,
            "trend_lookback": 6,
            "level_tolerance": 0.025,
            "shoulder_tolerance": 0.025,
            "min_retracement": 0.05,
            "head_margin": 0.05,
            "min_prior_trend": 0.03,
            "break_buffer": 0
          }
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: pattern, state, reason, event, events, pivots, parameters"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "double-top-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f02-a01/static/double-top-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/reversal-structures/double-top/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/reversal-structures/double-top/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F02-A02",
      "name": "Double Bottom",
      "headline": null,
      "slug": "double-bottom",
      "path": "geometric-chart-patterns/reversal-structures/double-bottom",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F02",
        "family": "Reversal Structures",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/reversal-structures/double-bottom",
        "entry": "doubleBottom",
        "params": [
          "close",
          "params"
        ],
        "exports": [
          "confirmedPivots",
          "detectReversal",
          "traceReversal",
          "doubleBottom"
        ],
        "archetype": "record-transform",
        "signature": "doubleBottom(close, params)"
      },
      "api": {
        "summary": "Double bottom detection: two comparable lows separated by a peak, confirmed on a close above the neckline. Chart patterns are usually described in prose vague enough to fit almost anything; encoding one forces a decision about how close \"comparable\" is and how much confirmation is required, and this returns those tolerances alongside the verdict. This topic wrapper accepts the close series and detection parameters, then delegates to the family detector core.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Finite, strictly positive closes in chronological order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "params",
            "type": "Record<string, number>",
            "required": false,
            "description": "Optional pivot, geometry, prior-trend, and confirmation overrides; unknown keys are rejected.",
            "constraints": null,
            "nulls": null,
            "default": "{}"
          }
        ],
        "returns": {
          "type": "{ pattern, state, reason, event, events, pivots, parameters }",
          "description": "A `state` rather than a boolean — searching, candidate, confirmed, or rejected — with the `reason`, the pivots that formed it, and the `parameters` in force. The parameters are the point: the same series yields a different answer under different tolerances, and a pattern reported without them cannot be reproduced."
        },
        "warmup": null,
        "errors": [
          {
            "when": "close is empty, non-finite, zero, or negative",
            "behaviour": "throws an Error"
          },
          {
            "when": "a parameter is unknown or outside its accepted range",
            "behaviour": "throws an Error"
          },
          {
            "when": "a valid non-empty series has insufficient confirmed pivots",
            "behaviour": "returns state `searching` rather than throwing"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(pivots)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "doubleBottom([120,119,118,117,116,115])",
        "args": [
          {
            "value": [
              120,
              119,
              118,
              117,
              116,
              115
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 72
            }
          }
        ],
        "output": {
          "pattern": "double_bottom",
          "state": "confirmed",
          "reason": "neckline-break-confirmed",
          "event": {
            "pattern": "double_bottom",
            "pivot_indices": [
              14,
              22,
              30
            ],
            "pivot_prices": [
              100,
              110,
              99
            ],
            "pivot_types": [
              "low",
              "high",
              "low"
            ],
            "candidate_available_index": 32,
            "confirmation_index": 40,
            "neckline": 110,
            "metrics": {
              "test_mean": 99.5,
              "level_spread": 0.010050251256281407,
              "retracement_min": 0.10552763819095477,
              "head_dominance": null,
              "formation_bars": 16,
              "min_separation": 8
            },
            "prior_move": 0.12,
            "state": "confirmed",
            "reason": "neckline-break-confirmed",
            "direction": "bullish"
          },
          "events": [
            {
              "pattern": "double_bottom",
              "pivot_indices": [
                14,
                22,
                30
              ],
              "pivot_prices": [
                100,
                110,
                99
              ],
              "pivot_types": [
                "low",
                "high",
                "low"
              ],
              "candidate_available_index": 32,
              "confirmation_index": 40,
              "neckline": 110,
              "metrics": {
                "test_mean": 99.5,
                "level_spread": 0.010050251256281407,
                "retracement_min": 0.10552763819095477,
                "head_dominance": null,
                "formation_bars": 16,
                "min_separation": 8
              },
              "prior_move": 0.12,
              "state": "confirmed",
              "reason": "neckline-break-confirmed",
              "direction": "bullish"
            }
          ],
          "pivots": [
            {
              "kind": "low",
              "index": 14,
              "confirmation_index": 16,
              "price": 100
            },
            {
              "kind": "high",
              "index": 22,
              "confirmation_index": 24,
              "price": 110
            },
            {
              "kind": "low",
              "index": 30,
              "confirmation_index": 32,
              "price": 99
            }
          ],
          "parameters": {
            "pivot_left": 2,
            "pivot_right": 2,
            "min_swing_bars": 5,
            "max_pattern_bars": 40,
            "max_confirmation_bars": 15,
            "trend_lookback": 6,
            "level_tolerance": 0.025,
            "shoulder_tolerance": 0.025,
            "min_retracement": 0.05,
            "head_margin": 0.05,
            "min_prior_trend": 0.03,
            "break_buffer": 0
          }
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: pattern, state, reason, event, events, pivots, parameters"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "double-bottom-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f02-a02/static/double-bottom-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/reversal-structures/double-bottom/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/reversal-structures/double-bottom/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F02-A03",
      "name": "Triple Top",
      "headline": null,
      "slug": "triple-top",
      "path": "geometric-chart-patterns/reversal-structures/triple-top",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F02",
        "family": "Reversal Structures",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/reversal-structures/triple-top",
        "entry": "tripleTop",
        "params": [
          "close",
          "params"
        ],
        "exports": [
          "confirmedPivots",
          "detectReversal",
          "traceReversal",
          "tripleTop"
        ],
        "archetype": "record-transform",
        "signature": "tripleTop(close, params)"
      },
      "api": {
        "summary": "Triple top detection: three comparable highs, confirmed on a close below the neckline. Chart patterns are usually described in prose vague enough to fit almost anything; encoding one forces a decision about how close \"comparable\" is and how much confirmation is required, and this returns those tolerances alongside the verdict. This topic wrapper accepts the close series and detection parameters, then delegates to the family detector core.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Finite, strictly positive closes in chronological order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "params",
            "type": "Record<string, number>",
            "required": false,
            "description": "Optional pivot, geometry, prior-trend, and confirmation overrides; unknown keys are rejected.",
            "constraints": null,
            "nulls": null,
            "default": "{}"
          }
        ],
        "returns": {
          "type": "{ pattern, state, reason, event, events, pivots, parameters }",
          "description": "A `state` rather than a boolean — searching, candidate, confirmed, or rejected — with the `reason`, the pivots that formed it, and the `parameters` in force. The parameters are the point: the same series yields a different answer under different tolerances, and a pattern reported without them cannot be reproduced."
        },
        "warmup": null,
        "errors": [
          {
            "when": "close is empty, non-finite, zero, or negative",
            "behaviour": "throws an Error"
          },
          {
            "when": "a parameter is unknown or outside its accepted range",
            "behaviour": "throws an Error"
          },
          {
            "when": "a valid non-empty series has insufficient confirmed pivots",
            "behaviour": "returns state `searching` rather than throwing"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(pivots)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "tripleTop([100,101.125,102.25,103.375,104.5,105.625])",
        "args": [
          {
            "value": [
              100,
              101.125,
              102.25,
              103.375,
              104.5,
              105.625
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 72
            }
          }
        ],
        "output": {
          "pattern": "triple_top",
          "state": "confirmed",
          "reason": "neckline-break-confirmed",
          "event": {
            "pattern": "triple_top",
            "pivot_indices": [
              14,
              21,
              28,
              35,
              42
            ],
            "pivot_prices": [
              120,
              110,
              119.5,
              111,
              120.5
            ],
            "pivot_types": [
              "high",
              "low",
              "high",
              "low",
              "high"
            ],
            "candidate_available_index": 44,
            "confirmation_index": 50,
            "neckline": 112.07142857142857,
            "metrics": {
              "test_mean": 120,
              "level_spread": 0.008333333333333333,
              "retracement_min": 0.075,
              "head_dominance": null,
              "formation_bars": 28,
              "min_separation": 7
            },
            "prior_move": 0.09166666666666666,
            "state": "confirmed",
            "reason": "neckline-break-confirmed",
            "direction": "bearish"
          },
          "events": [
            {
              "pattern": "triple_top",
              "pivot_indices": [
                14,
                21,
                28,
                35,
                42
              ],
              "pivot_prices": [
                120,
                110,
                119.5,
                111,
                120.5
              ],
              "pivot_types": [
                "high",
                "low",
                "high",
                "low",
                "high"
              ],
              "candidate_available_index": 44,
              "confirmation_index": 50,
              "neckline": 112.07142857142857,
              "metrics": {
                "test_mean": 120,
                "level_spread": 0.008333333333333333,
                "retracement_min": 0.075,
                "head_dominance": null,
                "formation_bars": 28,
                "min_separation": 7
              },
              "prior_move": 0.09166666666666666,
              "state": "confirmed",
              "reason": "neckline-break-confirmed",
              "direction": "bearish"
            }
          ],
          "pivots": [
            {
              "kind": "high",
              "index": 14,
              "confirmation_index": 16,
              "price": 120
            },
            {
              "kind": "low",
              "index": 21,
              "confirmation_index": 23,
              "price": 110
            },
            {
              "kind": "high",
              "index": 28,
              "confirmation_index": 30,
              "price": 119.5
            }
          ],
          "parameters": {
            "pivot_left": 2,
            "pivot_right": 2,
            "min_swing_bars": 5,
            "max_pattern_bars": 40,
            "max_confirmation_bars": 15,
            "trend_lookback": 6,
            "level_tolerance": 0.025,
            "shoulder_tolerance": 0.025,
            "min_retracement": 0.05,
            "head_margin": 0.05,
            "min_prior_trend": 0.03,
            "break_buffer": 0
          }
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: pattern, state, reason, event, events, pivots, parameters"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "triple-top-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f02-a03/static/triple-top-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/reversal-structures/triple-top/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/reversal-structures/triple-top/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F02-A04",
      "name": "Triple Bottom",
      "headline": null,
      "slug": "triple-bottom",
      "path": "geometric-chart-patterns/reversal-structures/triple-bottom",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F02",
        "family": "Reversal Structures",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/reversal-structures/triple-bottom",
        "entry": "tripleBottom",
        "params": [
          "close",
          "params"
        ],
        "exports": [
          "confirmedPivots",
          "detectReversal",
          "traceReversal",
          "tripleBottom"
        ],
        "archetype": "record-transform",
        "signature": "tripleBottom(close, params)"
      },
      "api": {
        "summary": "Triple bottom detection: three comparable lows, confirmed on a close above the neckline. Chart patterns are usually described in prose vague enough to fit almost anything; encoding one forces a decision about how close \"comparable\" is and how much confirmation is required, and this returns those tolerances alongside the verdict. Takes the close series and detection parameters, then delegates to the family detector core.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Finite, strictly positive closes in chronological order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "params",
            "type": "Record<string, number>",
            "required": false,
            "description": "Optional pivot, geometry, prior-trend, and confirmation overrides; unknown keys are rejected.",
            "constraints": null,
            "nulls": null,
            "default": "{}"
          }
        ],
        "returns": {
          "type": "{ pattern, state, reason, event, events, pivots, parameters }",
          "description": "A `state` rather than a boolean — searching, candidate, confirmed, or rejected — with the `reason`, the pivots that formed it, and the `parameters` in force. The parameters are the point: the same series yields a different answer under different tolerances, and a pattern reported without them cannot be reproduced."
        },
        "warmup": null,
        "errors": [
          {
            "when": "close is empty, non-finite, zero, or negative",
            "behaviour": "throws an Error"
          },
          {
            "when": "a parameter is unknown or outside its accepted range",
            "behaviour": "throws an Error"
          },
          {
            "when": "a valid non-empty series has insufficient confirmed pivots",
            "behaviour": "returns state `searching` rather than throwing"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(pivots)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "tripleBottom([120,118.875,117.75,116.625,115.5,114.375])",
        "args": [
          {
            "value": [
              120,
              118.875,
              117.75,
              116.625,
              115.5,
              114.375
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 72
            }
          }
        ],
        "output": {
          "pattern": "triple_bottom",
          "state": "confirmed",
          "reason": "neckline-break-confirmed",
          "event": {
            "pattern": "triple_bottom",
            "pivot_indices": [
              14,
              21,
              28,
              35,
              42
            ],
            "pivot_prices": [
              100,
              110,
              100.5,
              109,
              99.5
            ],
            "pivot_types": [
              "low",
              "high",
              "low",
              "high",
              "low"
            ],
            "candidate_available_index": 44,
            "confirmation_index": 50,
            "neckline": 107.92857142857143,
            "metrics": {
              "test_mean": 100,
              "level_spread": 0.01,
              "retracement_min": 0.09,
              "head_dominance": null,
              "formation_bars": 28,
              "min_separation": 7
            },
            "prior_move": 0.11,
            "state": "confirmed",
            "reason": "neckline-break-confirmed",
            "direction": "bullish"
          },
          "events": [
            {
              "pattern": "triple_bottom",
              "pivot_indices": [
                14,
                21,
                28,
                35,
                42
              ],
              "pivot_prices": [
                100,
                110,
                100.5,
                109,
                99.5
              ],
              "pivot_types": [
                "low",
                "high",
                "low",
                "high",
                "low"
              ],
              "candidate_available_index": 44,
              "confirmation_index": 50,
              "neckline": 107.92857142857143,
              "metrics": {
                "test_mean": 100,
                "level_spread": 0.01,
                "retracement_min": 0.09,
                "head_dominance": null,
                "formation_bars": 28,
                "min_separation": 7
              },
              "prior_move": 0.11,
              "state": "confirmed",
              "reason": "neckline-break-confirmed",
              "direction": "bullish"
            }
          ],
          "pivots": [
            {
              "kind": "low",
              "index": 14,
              "confirmation_index": 16,
              "price": 100
            },
            {
              "kind": "high",
              "index": 21,
              "confirmation_index": 23,
              "price": 110
            },
            {
              "kind": "low",
              "index": 28,
              "confirmation_index": 30,
              "price": 100.5
            }
          ],
          "parameters": {
            "pivot_left": 2,
            "pivot_right": 2,
            "min_swing_bars": 5,
            "max_pattern_bars": 40,
            "max_confirmation_bars": 15,
            "trend_lookback": 6,
            "level_tolerance": 0.025,
            "shoulder_tolerance": 0.025,
            "min_retracement": 0.05,
            "head_margin": 0.05,
            "min_prior_trend": 0.03,
            "break_buffer": 0
          }
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: pattern, state, reason, event, events, pivots, parameters"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "triple-bottom-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f02-a04/static/triple-bottom-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/reversal-structures/triple-bottom/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/reversal-structures/triple-bottom/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F02-A05",
      "name": "Head and Shoulders",
      "headline": null,
      "slug": "head-and-shoulders",
      "path": "geometric-chart-patterns/reversal-structures/head-and-shoulders",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F02",
        "family": "Reversal Structures",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/reversal-structures/head-and-shoulders",
        "entry": "headAndShoulders",
        "params": [
          "close",
          "params"
        ],
        "exports": [
          "confirmedPivots",
          "detectReversal",
          "traceReversal",
          "headAndShoulders"
        ],
        "archetype": "record-transform",
        "signature": "headAndShoulders(close, params)"
      },
      "api": {
        "summary": "Head and shoulders detection: a central high flanked by two lower highs, confirmed on a close below the neckline. Chart patterns are usually described in prose vague enough to fit almost anything; encoding one forces a decision about how close \"comparable\" is and how much confirmation is required, and this returns those tolerances alongside the verdict. This topic wrapper accepts the close series and detection parameters, then delegates to the family detector core.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Finite, strictly positive closes in chronological order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "params",
            "type": "Record<string, number>",
            "required": false,
            "description": "Optional pivot, geometry, prior-trend, and confirmation overrides; unknown keys are rejected.",
            "constraints": null,
            "nulls": null,
            "default": "{}"
          }
        ],
        "returns": {
          "type": "{ pattern, state, reason, event, events, pivots, parameters }",
          "description": "A `state` rather than a boolean — searching, candidate, confirmed, or rejected — with the `reason`, the pivots that formed it, and the `parameters` in force. The parameters are the point: the same series yields a different answer under different tolerances, and a pattern reported without them cannot be reproduced."
        },
        "warmup": null,
        "errors": [
          {
            "when": "close is empty, non-finite, zero, or negative",
            "behaviour": "throws an Error"
          },
          {
            "when": "a parameter is unknown or outside its accepted range",
            "behaviour": "throws an Error"
          },
          {
            "when": "a valid non-empty series has insufficient confirmed pivots",
            "behaviour": "returns state `searching` rather than throwing"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(pivots)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "headAndShoulders([100,101.125,102.25,103.375,104.5,105.625])",
        "args": [
          {
            "value": [
              100,
              101.125,
              102.25,
              103.375,
              104.5,
              105.625
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 72
            }
          }
        ],
        "output": {
          "pattern": "head_and_shoulders",
          "state": "confirmed",
          "reason": "neckline-break-confirmed",
          "event": {
            "pattern": "head_and_shoulders",
            "pivot_indices": [
              14,
              22,
              31,
              39,
              47
            ],
            "pivot_prices": [
              118,
              109,
              127,
              110,
              119
            ],
            "pivot_types": [
              "high",
              "low",
              "high",
              "low",
              "high"
            ],
            "candidate_available_index": 49,
            "confirmation_index": 56,
            "neckline": 111,
            "metrics": {
              "test_mean": 118.5,
              "level_spread": 0.008438818565400843,
              "retracement_min": 0.07172995780590717,
              "head_dominance": 0.07172995780590717,
              "formation_bars": 33,
              "min_separation": 8
            },
            "prior_move": 0.07627118644067797,
            "state": "confirmed",
            "reason": "neckline-break-confirmed",
            "direction": "bearish"
          },
          "events": [
            {
              "pattern": "head_and_shoulders",
              "pivot_indices": [
                14,
                22,
                31,
                39,
                47
              ],
              "pivot_prices": [
                118,
                109,
                127,
                110,
                119
              ],
              "pivot_types": [
                "high",
                "low",
                "high",
                "low",
                "high"
              ],
              "candidate_available_index": 49,
              "confirmation_index": 56,
              "neckline": 111,
              "metrics": {
                "test_mean": 118.5,
                "level_spread": 0.008438818565400843,
                "retracement_min": 0.07172995780590717,
                "head_dominance": 0.07172995780590717,
                "formation_bars": 33,
                "min_separation": 8
              },
              "prior_move": 0.07627118644067797,
              "state": "confirmed",
              "reason": "neckline-break-confirmed",
              "direction": "bearish"
            }
          ],
          "pivots": [
            {
              "kind": "high",
              "index": 14,
              "confirmation_index": 16,
              "price": 118
            },
            {
              "kind": "low",
              "index": 22,
              "confirmation_index": 24,
              "price": 109
            },
            {
              "kind": "high",
              "index": 31,
              "confirmation_index": 33,
              "price": 127
            }
          ],
          "parameters": {
            "pivot_left": 2,
            "pivot_right": 2,
            "min_swing_bars": 5,
            "max_pattern_bars": 40,
            "max_confirmation_bars": 15,
            "trend_lookback": 6,
            "level_tolerance": 0.025,
            "shoulder_tolerance": 0.025,
            "min_retracement": 0.05,
            "head_margin": 0.05,
            "min_prior_trend": 0.03,
            "break_buffer": 0
          }
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: pattern, state, reason, event, events, pivots, parameters"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "head-and-shoulders-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f02-a05/static/head-and-shoulders-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/reversal-structures/head-and-shoulders/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/reversal-structures/head-and-shoulders/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F02-A06",
      "name": "Inverse Head and Shoulders",
      "headline": null,
      "slug": "inverse-head-and-shoulders",
      "path": "geometric-chart-patterns/reversal-structures/inverse-head-and-shoulders",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F02",
        "family": "Reversal Structures",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/reversal-structures/inverse-head-and-shoulders",
        "entry": "inverseHeadAndShoulders",
        "params": [
          "close",
          "params"
        ],
        "exports": [
          "confirmedPivots",
          "detectReversal",
          "traceReversal",
          "inverseHeadAndShoulders"
        ],
        "archetype": "record-transform",
        "signature": "inverseHeadAndShoulders(close, params)"
      },
      "api": {
        "summary": "Inverse head and shoulders detection: a central low flanked by two higher lows, confirmed on a close above the neckline. Chart patterns are usually described in prose vague enough to fit almost anything; encoding one forces a decision about how close \"comparable\" is and how much confirmation is required, and this returns those tolerances alongside the verdict. This topic wrapper accepts the close series and detection parameters, then delegates to the family detector core.",
        "params": [
          {
            "name": "close",
            "type": "number[]",
            "required": true,
            "description": "Finite, strictly positive closes in chronological order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "params",
            "type": "Record<string, number>",
            "required": false,
            "description": "Optional pivot, geometry, prior-trend, and confirmation overrides; unknown keys are rejected.",
            "constraints": null,
            "nulls": null,
            "default": "{}"
          }
        ],
        "returns": {
          "type": "{ pattern, state, reason, event, events, pivots, parameters }",
          "description": "A `state` rather than a boolean — searching, candidate, confirmed, or rejected — with the `reason`, the pivots that formed it, and the `parameters` in force. The parameters are the point: the same series yields a different answer under different tolerances, and a pattern reported without them cannot be reproduced."
        },
        "warmup": null,
        "errors": [
          {
            "when": "close is empty, non-finite, zero, or negative",
            "behaviour": "throws an Error"
          },
          {
            "when": "a parameter is unknown or outside its accepted range",
            "behaviour": "throws an Error"
          },
          {
            "when": "a valid non-empty series has insufficient confirmed pivots",
            "behaviour": "returns state `searching` rather than throwing"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(pivots)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "inverseHeadAndShoulders([120,118.875,117.75,116.625,115.5,114.375])",
        "args": [
          {
            "value": [
              120,
              118.875,
              117.75,
              116.625,
              115.5,
              114.375
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 72
            }
          }
        ],
        "output": {
          "pattern": "inverse_head_and_shoulders",
          "state": "confirmed",
          "reason": "neckline-break-confirmed",
          "event": {
            "pattern": "inverse_head_and_shoulders",
            "pivot_indices": [
              14,
              22,
              31,
              39,
              47
            ],
            "pivot_prices": [
              102,
              111,
              93,
              110,
              101
            ],
            "pivot_types": [
              "low",
              "high",
              "low",
              "high",
              "low"
            ],
            "candidate_available_index": 49,
            "confirmation_index": 56,
            "neckline": 109,
            "metrics": {
              "test_mean": 101.5,
              "level_spread": 0.009852216748768473,
              "retracement_min": 0.08374384236453201,
              "head_dominance": 0.08374384236453201,
              "formation_bars": 33,
              "min_separation": 8
            },
            "prior_move": 0.08823529411764706,
            "state": "confirmed",
            "reason": "neckline-break-confirmed",
            "direction": "bullish"
          },
          "events": [
            {
              "pattern": "inverse_head_and_shoulders",
              "pivot_indices": [
                14,
                22,
                31,
                39,
                47
              ],
              "pivot_prices": [
                102,
                111,
                93,
                110,
                101
              ],
              "pivot_types": [
                "low",
                "high",
                "low",
                "high",
                "low"
              ],
              "candidate_available_index": 49,
              "confirmation_index": 56,
              "neckline": 109,
              "metrics": {
                "test_mean": 101.5,
                "level_spread": 0.009852216748768473,
                "retracement_min": 0.08374384236453201,
                "head_dominance": 0.08374384236453201,
                "formation_bars": 33,
                "min_separation": 8
              },
              "prior_move": 0.08823529411764706,
              "state": "confirmed",
              "reason": "neckline-break-confirmed",
              "direction": "bullish"
            }
          ],
          "pivots": [
            {
              "kind": "low",
              "index": 14,
              "confirmation_index": 16,
              "price": 102
            },
            {
              "kind": "high",
              "index": 22,
              "confirmation_index": 24,
              "price": 111
            },
            {
              "kind": "low",
              "index": 31,
              "confirmation_index": 33,
              "price": 93
            }
          ],
          "parameters": {
            "pivot_left": 2,
            "pivot_right": 2,
            "min_swing_bars": 5,
            "max_pattern_bars": 40,
            "max_confirmation_bars": 15,
            "trend_lookback": 6,
            "level_tolerance": 0.025,
            "shoulder_tolerance": 0.025,
            "min_retracement": 0.05,
            "head_margin": 0.05,
            "min_prior_trend": 0.03,
            "break_buffer": 0
          }
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: pattern, state, reason, event, events, pivots, parameters"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "inverse-head-and-shoulders-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d08-f02-a06/static/inverse-head-and-shoulders-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Claim-to-source map",
          "title": "Claim-to-source map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/reversal-structures/inverse-head-and-shoulders/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/reversal-structures/inverse-head-and-shoulders/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F05-A01",
      "name": "Price–Indicator Pivot Alignment",
      "headline": null,
      "slug": "price-indicator-pivot-alignment",
      "path": "geometric-chart-patterns/indicator-divergence-detection/price-indicator-pivot-alignment",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F05",
        "family": "Indicator Divergence Detection",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/indicator-divergence-detection/price-indicator-pivot-alignment",
        "entry": "priceIndicatorPivotAlignment",
        "params": [
          "payload"
        ],
        "exports": [
          "adaptIndicator",
          "alignPivots",
          "detectDivergences",
          "scoreDivergence",
          "advanceState",
          "combineConfluence",
          "rankUniverse",
          "runTopic",
          "priceIndicatorPivotAlignment",
          "regularBullishBearishDivergenceDetection",
          "hiddenBullishBearishDivergenceDetection",
          "multiIndicatorDivergenceAdapters",
          "divergenceStrengthAndQualityScoring",
          "divergenceConfirmationAndInvalidationStateMachine",
          "multiIndicatorDivergenceConfluence",
          "marketWideDivergenceScannerAndRanking"
        ],
        "archetype": "record-transform",
        "signature": "priceIndicatorPivotAlignment(payload)"
      },
      "api": {
        "summary": "Aligns confirmed price and indicator pivots of the same kind within an explicit lag bound while preserving both event and knowledge indexes.",
        "params": [
          {
            "name": "payload",
            "type": "{ topic_id: string; data_class: string; as_of: string; bars: { timestamp: string; open: number; high: number; low: number; close: number; finalized: boolean }[]; price_pivots: { kind: string; event_index: number; confirmation_index: number; price: number; prominence: number }[]; indicators: { name: string; family: string; polarity: number; scale: number; pivots: { kind: string; event_index: number; confirmation_index: number; value: number; prominence: number }[] }[]; parameters: { max_lag: number; min_separation: number; max_separation: number; min_price_fraction: number; min_indicator_delta: number; confirmation_horizon: number; invalidation_buffer: number; minimum_indicators: number }; weights: { RSI: number; MACD-Histogram: number; Stochastic-K: number }; as_of_index: number; universe: { symbol: string; state: string; divergence_type: string; confluence_score: number; freshness: number; liquidity: number; data_quality: number; available_index: number; eligible: boolean }[] }",
            "required": true,
            "description": "Topic payload containing price pivots, indicator definitions, and `parameters.max_lag`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, state, alignments, alignment_count?, reason }",
          "description": "One alignment record. `state` is `warmup` when no indicator pivots or fewer than two alignments are available and `ready` otherwise; it does not describe leading null positions in a returned series."
        },
        "warmup": {
          "count": "2 eligible aligned pivots",
          "value": "state: warmup",
          "note": "The function returns one alignment record when fewer than two causal alignments are available; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "pivot identity, chronology, value, scale, polarity, or max-lag input is invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(p x q log q)\", space: \"O(p + q)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "priceIndicatorPivotAlignment({\"topic_id\":\"D08-F05-A01\",\"data_class\":\"synthetic-teaching\",\"as_of\":\"2026-01-08T13:30:00Z\",\"bars\":[{\"timestamp\":\"2026-01-05T14:30:00Z\",\"open\":105.75,\"high\":107,\"low\":105,\"close\":106,\"finalized\":true},{\"timestamp\":\"2026-01-05T15:30:00Z\",\"open\":106.112,\"high\":107.362,\"low\":105.362,\"close\":106.362,\"finalized\":true},{\"timestamp\":\"2026-01-05T16:30:00Z\",\"open\":106.4614,\"high\":107.7114,\"low\":105.7114,\"close\":106.7114,\"finalized\":true}],\"price_pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"price\":98,\"prominence\":0.72},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"price\":94,\"prominence\":0.84}],\"indicators\":[{\"name\":\"RSI\",\"family\":\"bounded-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":19,\"confirmation_index\":22,\"value\":28,\"prominence\":0.76},{\"kind\":\"low\",\"event_index\":41,\"confirmation_index\":44,\"value\":36,\"prominence\":0.86}]},{\"name\":\"MACD-Histogram\",\"family\":\"moving-average-momentum\",\"polarity\":1,\"scale\":5,\"pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"value\":-2.2,\"prominence\":0.7},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"value\":-1,\"prominence\":0.81}]},{\"name\":\"Stochastic-K\",\"family\":\"range-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":17,\"confirmation_index\":20,\"value\":18,\"prominence\":0.68},{\"kind\":\"low\",\"event_index\":43,\"confirmation_index\":46,\"value\":29,\"prominence\":0.78}]}],\"parameters\":{\"max_lag\":3,\"min_separation\":5,\"max_separation\":40,\"min_price_fraction\":0.005,\"min_indicator_delta\":0.05,\"confirmation_horizon\":12,\"invalidation_buffer\":0.005,\"minimum_indicators\":2},\"weights\":{\"RSI\":0.4,\"MACD-Histogram\":0.35,\"Stochastic-K\":0.25},\"as_of_index\":71,\"universe\":[{\"symbol\":\"SYNTH-A\",\"state\":\"confirmed\",\"divergence_type\":\"regular-bullish\",\"confluence_score\":86,\"freshness\":92,\"liquidity\":80,\"data_quality\":98,\"available_index\":47,\"eligible\":true},{\"symbol\":\"SYNTH-B\",\"state\":\"candidate\",\"divergence_type\":\"regular-bearish\",\"confluence_score\":91,\"freshness\":98,\"liquidity\":72,\"data_quality\":94,\"available_index\":54,\"eligible\":true},{\"symbol\":\"SYNTH-C\",\"state\":\"confirmed\",\"divergence_type\":\"hidden-bullish\",\"confluence_score\":74,\"freshness\":70,\"liquidity\":96,\"data_quality\":90,\"available_index\":39,\"eligible\":true}]})",
        "args": [
          {
            "value": {
              "topic_id": "D08-F05-A01",
              "data_class": "synthetic-teaching",
              "as_of": "2026-01-08T13:30:00Z",
              "bars": [
                {
                  "timestamp": "2026-01-05T14:30:00Z",
                  "open": 105.75,
                  "high": 107,
                  "low": 105,
                  "close": 106,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T15:30:00Z",
                  "open": 106.112,
                  "high": 107.362,
                  "low": 105.362,
                  "close": 106.362,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T16:30:00Z",
                  "open": 106.4614,
                  "high": 107.7114,
                  "low": 105.7114,
                  "close": 106.7114,
                  "finalized": true
                }
              ],
              "price_pivots": [
                {
                  "kind": "low",
                  "event_index": 18,
                  "confirmation_index": 21,
                  "price": 98,
                  "prominence": 0.72
                },
                {
                  "kind": "low",
                  "event_index": 42,
                  "confirmation_index": 45,
                  "price": 94,
                  "prominence": 0.84
                }
              ],
              "indicators": [
                {
                  "name": "RSI",
                  "family": "bounded-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 19,
                      "confirmation_index": 22,
                      "value": 28,
                      "prominence": 0.76
                    },
                    {
                      "kind": "low",
                      "event_index": 41,
                      "confirmation_index": 44,
                      "value": 36,
                      "prominence": 0.86
                    }
                  ]
                },
                {
                  "name": "MACD-Histogram",
                  "family": "moving-average-momentum",
                  "polarity": 1,
                  "scale": 5,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 18,
                      "confirmation_index": 21,
                      "value": -2.2,
                      "prominence": 0.7
                    },
                    {
                      "kind": "low",
                      "event_index": 42,
                      "confirmation_index": 45,
                      "value": -1,
                      "prominence": 0.81
                    }
                  ]
                },
                {
                  "name": "Stochastic-K",
                  "family": "range-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 17,
                      "confirmation_index": 20,
                      "value": 18,
                      "prominence": 0.68
                    },
                    {
                      "kind": "low",
                      "event_index": 43,
                      "confirmation_index": 46,
                      "value": 29,
                      "prominence": 0.78
                    }
                  ]
                }
              ],
              "parameters": {
                "max_lag": 3,
                "min_separation": 5,
                "max_separation": 40,
                "min_price_fraction": 0.005,
                "min_indicator_delta": 0.05,
                "confirmation_horizon": 12,
                "invalidation_buffer": 0.005,
                "minimum_indicators": 2
              },
              "weights": {
                "RSI": 0.4,
                "MACD-Histogram": 0.35,
                "Stochastic-K": 0.25
              },
              "as_of_index": 71,
              "universe": [
                {
                  "symbol": "SYNTH-A",
                  "state": "confirmed",
                  "divergence_type": "regular-bullish",
                  "confluence_score": 86,
                  "freshness": 92,
                  "liquidity": 80,
                  "data_quality": 98,
                  "available_index": 47,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-B",
                  "state": "candidate",
                  "divergence_type": "regular-bearish",
                  "confluence_score": 91,
                  "freshness": 98,
                  "liquidity": 72,
                  "data_quality": 94,
                  "available_index": 54,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-C",
                  "state": "confirmed",
                  "divergence_type": "hidden-bullish",
                  "confluence_score": 74,
                  "freshness": 70,
                  "liquidity": 96,
                  "data_quality": 90,
                  "available_index": 39,
                  "eligible": true
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F05-A01",
          "state": "ready",
          "alignments": [
            {
              "kind": "low",
              "price_event_index": 18,
              "price_confirmation_index": 21,
              "price": 98,
              "price_prominence": 0.72,
              "indicator_event_index": 19,
              "indicator_confirmation_index": 22,
              "indicator_value": 0.28,
              "indicator_raw_value": 28,
              "indicator_prominence": 0.76,
              "lag": 1,
              "knowledge_index": 22,
              "indicator": "RSI",
              "indicator_family": "bounded-momentum"
            },
            {
              "kind": "low",
              "price_event_index": 42,
              "price_confirmation_index": 45,
              "price": 94,
              "price_prominence": 0.84,
              "indicator_event_index": 41,
              "indicator_confirmation_index": 44,
              "indicator_value": 0.36,
              "indicator_raw_value": 36,
              "indicator_prominence": 0.86,
              "lag": 1,
              "knowledge_index": 45,
              "indicator": "RSI",
              "indicator_family": "bounded-momentum"
            }
          ],
          "alignment_count": 2,
          "reason": "aligned"
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: topic_id, state, alignments, alignment_count, reason"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a01/static/map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "TradingView — RSI divergence indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000589127-rsi-divergence-indicator/"
        },
        {
          "key": "S2",
          "title": "TradingView — MACD indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502344-moving-average-convergence-divergence-macd-indicator/"
        },
        {
          "key": "S3",
          "title": "TradingView Pine Script — Repainting",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/concepts/repainting/"
        },
        {
          "key": "S4",
          "title": "TradingView Pine Script — Visuals FAQ",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/faq/visuals/"
        },
        {
          "key": "S5",
          "title": "Fidelity — Relative Strength Index",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/RSI"
        },
        {
          "key": "S6",
          "title": "Fidelity — MACD",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/macd"
        },
        {
          "key": "S7",
          "title": "TA-Lib — Function index",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S8",
          "title": "TA-Lib — RSI",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/rsi.html"
        },
        {
          "key": "S9",
          "title": "SciPy — find_peaks",
          "author": "SciPy",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S10",
          "title": "Bailey et al. — Effects of Backtest Overfitting",
          "author": "Bailey et al.",
          "url": "https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2308659"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        },
        {
          "key": "Topic-specific applicability map",
          "title": "Topic-specific applicability map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/indicator-divergence-detection/price-indicator-pivot-alignment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/indicator-divergence-detection/price-indicator-pivot-alignment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F05-A02",
      "name": "Regular Bullish/Bearish Divergence Detection",
      "headline": null,
      "slug": "regular-bullish-bearish-divergence-detection",
      "path": "geometric-chart-patterns/indicator-divergence-detection/regular-bullish-bearish-divergence-detection",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F05",
        "family": "Indicator Divergence Detection",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/indicator-divergence-detection/regular-bullish-bearish-divergence-detection",
        "entry": "regularBullishBearishDivergenceDetection",
        "params": [
          "payload"
        ],
        "exports": [
          "adaptIndicator",
          "alignPivots",
          "detectDivergences",
          "scoreDivergence",
          "advanceState",
          "combineConfluence",
          "rankUniverse",
          "runTopic",
          "priceIndicatorPivotAlignment",
          "regularBullishBearishDivergenceDetection",
          "hiddenBullishBearishDivergenceDetection",
          "multiIndicatorDivergenceAdapters",
          "divergenceStrengthAndQualityScoring",
          "divergenceConfirmationAndInvalidationStateMachine",
          "multiIndicatorDivergenceConfluence",
          "marketWideDivergenceScannerAndRanking"
        ],
        "archetype": "record-transform",
        "signature": "regularBullishBearishDivergenceDetection(payload)"
      },
      "api": {
        "summary": "Detects regular bullish and bearish divergence from causally aligned consecutive pivot pairs.",
        "params": [
          {
            "name": "payload",
            "type": "{ topic_id: string; data_class: string; as_of: string; bars: { timestamp: string; open: number; high: number; low: number; close: number; finalized: boolean }[]; price_pivots: { kind: string; event_index: number; confirmation_index: number; price: number; prominence: number }[]; indicators: { name: string; family: string; polarity: number; scale: number; pivots: { kind: string; event_index: number; confirmation_index: number; value: number; prominence: number }[] }[]; parameters: { max_lag: number; min_separation: number; max_separation: number; min_price_fraction: number; min_indicator_delta: number; confirmation_horizon: number; invalidation_buffer: number; minimum_indicators: number }; weights: { RSI: number; MACD-Histogram: number; Stochastic-K: number }; as_of_index: number; universe: { symbol: string; state: string; divergence_type: string; confluence_score: number; freshness: number; liquidity: number; data_quality: number; available_index: number; eligible: boolean }[] }",
            "required": true,
            "description": "Topic payload containing price pivots, indicators, and separation, alignment, price, and indicator thresholds.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, state, events, event_count }",
          "description": "One detection record with `state` equal to `detected` or `not-detected` and regular-divergence event diagnostics."
        },
        "warmup": null,
        "errors": [
          {
            "when": "pivot, indicator, lag, separation, or divergence-threshold input is invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(k x p x q log q)\", space: \"O(p + q + events)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "regularBullishBearishDivergenceDetection({\"topic_id\":\"D08-F05-A02\",\"data_class\":\"synthetic-teaching\",\"as_of\":\"2026-01-08T13:30:00Z\",\"bars\":[{\"timestamp\":\"2026-01-05T14:30:00Z\",\"open\":105.75,\"high\":107,\"low\":105,\"close\":106,\"finalized\":true},{\"timestamp\":\"2026-01-05T15:30:00Z\",\"open\":106.112,\"high\":107.362,\"low\":105.362,\"close\":106.362,\"finalized\":true},{\"timestamp\":\"2026-01-05T16:30:00Z\",\"open\":106.4614,\"high\":107.7114,\"low\":105.7114,\"close\":106.7114,\"finalized\":true}],\"price_pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"price\":98,\"prominence\":0.72},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"price\":94,\"prominence\":0.84}],\"indicators\":[{\"name\":\"RSI\",\"family\":\"bounded-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":19,\"confirmation_index\":22,\"value\":28,\"prominence\":0.76},{\"kind\":\"low\",\"event_index\":41,\"confirmation_index\":44,\"value\":36,\"prominence\":0.86}]},{\"name\":\"MACD-Histogram\",\"family\":\"moving-average-momentum\",\"polarity\":1,\"scale\":5,\"pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"value\":-2.2,\"prominence\":0.7},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"value\":-1,\"prominence\":0.81}]},{\"name\":\"Stochastic-K\",\"family\":\"range-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":17,\"confirmation_index\":20,\"value\":18,\"prominence\":0.68},{\"kind\":\"low\",\"event_index\":43,\"confirmation_index\":46,\"value\":29,\"prominence\":0.78}]}],\"parameters\":{\"max_lag\":3,\"min_separation\":5,\"max_separation\":40,\"min_price_fraction\":0.005,\"min_indicator_delta\":0.05,\"confirmation_horizon\":12,\"invalidation_buffer\":0.005,\"minimum_indicators\":2},\"weights\":{\"RSI\":0.4,\"MACD-Histogram\":0.35,\"Stochastic-K\":0.25},\"as_of_index\":71,\"universe\":[{\"symbol\":\"SYNTH-A\",\"state\":\"confirmed\",\"divergence_type\":\"regular-bullish\",\"confluence_score\":86,\"freshness\":92,\"liquidity\":80,\"data_quality\":98,\"available_index\":47,\"eligible\":true},{\"symbol\":\"SYNTH-B\",\"state\":\"candidate\",\"divergence_type\":\"regular-bearish\",\"confluence_score\":91,\"freshness\":98,\"liquidity\":72,\"data_quality\":94,\"available_index\":54,\"eligible\":true},{\"symbol\":\"SYNTH-C\",\"state\":\"confirmed\",\"divergence_type\":\"hidden-bullish\",\"confluence_score\":74,\"freshness\":70,\"liquidity\":96,\"data_quality\":90,\"available_index\":39,\"eligible\":true}]})",
        "args": [
          {
            "value": {
              "topic_id": "D08-F05-A02",
              "data_class": "synthetic-teaching",
              "as_of": "2026-01-08T13:30:00Z",
              "bars": [
                {
                  "timestamp": "2026-01-05T14:30:00Z",
                  "open": 105.75,
                  "high": 107,
                  "low": 105,
                  "close": 106,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T15:30:00Z",
                  "open": 106.112,
                  "high": 107.362,
                  "low": 105.362,
                  "close": 106.362,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T16:30:00Z",
                  "open": 106.4614,
                  "high": 107.7114,
                  "low": 105.7114,
                  "close": 106.7114,
                  "finalized": true
                }
              ],
              "price_pivots": [
                {
                  "kind": "low",
                  "event_index": 18,
                  "confirmation_index": 21,
                  "price": 98,
                  "prominence": 0.72
                },
                {
                  "kind": "low",
                  "event_index": 42,
                  "confirmation_index": 45,
                  "price": 94,
                  "prominence": 0.84
                }
              ],
              "indicators": [
                {
                  "name": "RSI",
                  "family": "bounded-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 19,
                      "confirmation_index": 22,
                      "value": 28,
                      "prominence": 0.76
                    },
                    {
                      "kind": "low",
                      "event_index": 41,
                      "confirmation_index": 44,
                      "value": 36,
                      "prominence": 0.86
                    }
                  ]
                },
                {
                  "name": "MACD-Histogram",
                  "family": "moving-average-momentum",
                  "polarity": 1,
                  "scale": 5,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 18,
                      "confirmation_index": 21,
                      "value": -2.2,
                      "prominence": 0.7
                    },
                    {
                      "kind": "low",
                      "event_index": 42,
                      "confirmation_index": 45,
                      "value": -1,
                      "prominence": 0.81
                    }
                  ]
                },
                {
                  "name": "Stochastic-K",
                  "family": "range-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 17,
                      "confirmation_index": 20,
                      "value": 18,
                      "prominence": 0.68
                    },
                    {
                      "kind": "low",
                      "event_index": 43,
                      "confirmation_index": 46,
                      "value": 29,
                      "prominence": 0.78
                    }
                  ]
                }
              ],
              "parameters": {
                "max_lag": 3,
                "min_separation": 5,
                "max_separation": 40,
                "min_price_fraction": 0.005,
                "min_indicator_delta": 0.05,
                "confirmation_horizon": 12,
                "invalidation_buffer": 0.005,
                "minimum_indicators": 2
              },
              "weights": {
                "RSI": 0.4,
                "MACD-Histogram": 0.35,
                "Stochastic-K": 0.25
              },
              "as_of_index": 71,
              "universe": [
                {
                  "symbol": "SYNTH-A",
                  "state": "confirmed",
                  "divergence_type": "regular-bullish",
                  "confluence_score": 86,
                  "freshness": 92,
                  "liquidity": 80,
                  "data_quality": 98,
                  "available_index": 47,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-B",
                  "state": "candidate",
                  "divergence_type": "regular-bearish",
                  "confluence_score": 91,
                  "freshness": 98,
                  "liquidity": 72,
                  "data_quality": 94,
                  "available_index": 54,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-C",
                  "state": "confirmed",
                  "divergence_type": "hidden-bullish",
                  "confluence_score": 74,
                  "freshness": 70,
                  "liquidity": 96,
                  "data_quality": 90,
                  "available_index": 39,
                  "eligible": true
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F05-A02",
          "state": "detected",
          "events": [
            {
              "type": "regular-bullish",
              "direction": "bullish",
              "kind": "low",
              "indicator": "MACD-Histogram",
              "indicator_family": "moving-average-momentum",
              "price_pair": [
                18,
                42
              ],
              "indicator_pair": [
                18,
                42
              ],
              "price_values": [
                98,
                94
              ],
              "indicator_values": [
                -0.44000000000000006,
                -0.2
              ],
              "price_delta_fraction": -0.04081632653061224,
              "indicator_delta": 0.24000000000000005,
              "separation": 24,
              "max_alignment_lag": 0,
              "prominence": 0.7675
            },
            {
              "type": "regular-bullish",
              "direction": "bullish",
              "kind": "low",
              "indicator": "RSI",
              "indicator_family": "bounded-momentum",
              "price_pair": [
                18,
                42
              ],
              "indicator_pair": [
                19,
                41
              ],
              "price_values": [
                98,
                94
              ],
              "indicator_values": [
                0.28,
                0.36
              ],
              "price_delta_fraction": -0.04081632653061224,
              "indicator_delta": 0.07999999999999996,
              "separation": 24,
              "max_alignment_lag": 1,
              "prominence": 0.795
            },
            {
              "type": "regular-bullish",
              "direction": "bullish",
              "kind": "low",
              "indicator": "Stochastic-K",
              "indicator_family": "range-momentum",
              "price_pair": [
                18,
                42
              ],
              "indicator_pair": [
                17,
                43
              ],
              "price_values": [
                98,
                94
              ],
              "indicator_values": [
                0.18,
                0.29
              ],
              "price_delta_fraction": -0.04081632653061224,
              "indicator_delta": 0.10999999999999999,
              "separation": 24,
              "max_alignment_lag": 1,
              "prominence": 0.7550000000000001
            }
          ],
          "event_count": 3
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: topic_id, state, events, event_count"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a02/static/map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "TradingView — RSI divergence indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000589127-rsi-divergence-indicator/"
        },
        {
          "key": "S2",
          "title": "TradingView — MACD indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502344-moving-average-convergence-divergence-macd-indicator/"
        },
        {
          "key": "S3",
          "title": "TradingView Pine Script — Repainting",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/concepts/repainting/"
        },
        {
          "key": "S4",
          "title": "TradingView Pine Script — Visuals FAQ",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/faq/visuals/"
        },
        {
          "key": "S5",
          "title": "Fidelity — Relative Strength Index",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/RSI"
        },
        {
          "key": "S6",
          "title": "Fidelity — MACD",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/macd"
        },
        {
          "key": "S7",
          "title": "TA-Lib — Function index",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S8",
          "title": "TA-Lib — RSI",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/rsi.html"
        },
        {
          "key": "S9",
          "title": "SciPy — find_peaks",
          "author": "SciPy",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S10",
          "title": "Bailey et al. — Effects of Backtest Overfitting",
          "author": "Bailey et al.",
          "url": "https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2308659"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        },
        {
          "key": "Topic-specific applicability map",
          "title": "Topic-specific applicability map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/indicator-divergence-detection/regular-bullish-bearish-divergence-detection/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/indicator-divergence-detection/regular-bullish-bearish-divergence-detection/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F05-A03",
      "name": "Hidden Bullish/Bearish Divergence Detection",
      "headline": null,
      "slug": "hidden-bullish-bearish-divergence-detection",
      "path": "geometric-chart-patterns/indicator-divergence-detection/hidden-bullish-bearish-divergence-detection",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F05",
        "family": "Indicator Divergence Detection",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/indicator-divergence-detection/hidden-bullish-bearish-divergence-detection",
        "entry": "hiddenBullishBearishDivergenceDetection",
        "params": [
          "payload"
        ],
        "exports": [
          "adaptIndicator",
          "alignPivots",
          "detectDivergences",
          "scoreDivergence",
          "advanceState",
          "combineConfluence",
          "rankUniverse",
          "runTopic",
          "priceIndicatorPivotAlignment",
          "regularBullishBearishDivergenceDetection",
          "hiddenBullishBearishDivergenceDetection",
          "multiIndicatorDivergenceAdapters",
          "divergenceStrengthAndQualityScoring",
          "divergenceConfirmationAndInvalidationStateMachine",
          "multiIndicatorDivergenceConfluence",
          "marketWideDivergenceScannerAndRanking"
        ],
        "archetype": "record-transform",
        "signature": "hiddenBullishBearishDivergenceDetection(payload)"
      },
      "api": {
        "summary": "Detects hidden bullish and bearish divergence from causally aligned consecutive pivot pairs.",
        "params": [
          {
            "name": "payload",
            "type": "{ topic_id: string; data_class: string; as_of: string; bars: { timestamp: string; open: number; high: number; low: number; close: number; finalized: boolean }[]; price_pivots: { kind: string; event_index: number; confirmation_index: number; price: number; prominence: number }[]; indicators: { name: string; family: string; polarity: number; scale: number; pivots: { kind: string; event_index: number; confirmation_index: number; value: number; prominence: number }[] }[]; parameters: { max_lag: number; min_separation: number; max_separation: number; min_price_fraction: number; min_indicator_delta: number; confirmation_horizon: number; invalidation_buffer: number; minimum_indicators: number }; weights: { RSI: number; MACD-Histogram: number; Stochastic-K: number }; as_of_index: number; universe: { symbol: string; state: string; divergence_type: string; confluence_score: number; freshness: number; liquidity: number; data_quality: number; available_index: number; eligible: boolean }[] }",
            "required": true,
            "description": "Topic payload containing price pivots, indicators, and separation, alignment, price, and indicator thresholds.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, state, events, event_count }",
          "description": "One detection record with `state` equal to `detected` or `not-detected` and hidden-divergence event diagnostics."
        },
        "warmup": null,
        "errors": [
          {
            "when": "pivot, indicator, lag, separation, or divergence-threshold input is invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(k x p x q log q)\", space: \"O(p + q + events)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "hiddenBullishBearishDivergenceDetection({\"topic_id\":\"D08-F05-A03\",\"data_class\":\"synthetic-teaching\",\"as_of\":\"2026-01-08T13:30:00Z\",\"bars\":[{\"timestamp\":\"2026-01-05T14:30:00Z\",\"open\":105.75,\"high\":107,\"low\":105,\"close\":106,\"finalized\":true},{\"timestamp\":\"2026-01-05T15:30:00Z\",\"open\":106.112,\"high\":107.362,\"low\":105.362,\"close\":106.362,\"finalized\":true},{\"timestamp\":\"2026-01-05T16:30:00Z\",\"open\":106.4614,\"high\":107.7114,\"low\":105.7114,\"close\":106.7114,\"finalized\":true}],\"price_pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"price\":98,\"prominence\":0.72},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"price\":102,\"prominence\":0.84}],\"indicators\":[{\"name\":\"RSI\",\"family\":\"bounded-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":19,\"confirmation_index\":22,\"value\":36,\"prominence\":0.76},{\"kind\":\"low\",\"event_index\":41,\"confirmation_index\":44,\"value\":28,\"prominence\":0.86}]},{\"name\":\"MACD-Histogram\",\"family\":\"moving-average-momentum\",\"polarity\":1,\"scale\":5,\"pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"value\":-1,\"prominence\":0.7},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"value\":-2.2,\"prominence\":0.81}]},{\"name\":\"Stochastic-K\",\"family\":\"range-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":17,\"confirmation_index\":20,\"value\":31,\"prominence\":0.68},{\"kind\":\"low\",\"event_index\":43,\"confirmation_index\":46,\"value\":19,\"prominence\":0.78}]}],\"parameters\":{\"max_lag\":3,\"min_separation\":5,\"max_separation\":40,\"min_price_fraction\":0.005,\"min_indicator_delta\":0.05,\"confirmation_horizon\":12,\"invalidation_buffer\":0.005,\"minimum_indicators\":2},\"weights\":{\"RSI\":0.4,\"MACD-Histogram\":0.35,\"Stochastic-K\":0.25},\"as_of_index\":71,\"universe\":[{\"symbol\":\"SYNTH-A\",\"state\":\"confirmed\",\"divergence_type\":\"regular-bullish\",\"confluence_score\":86,\"freshness\":92,\"liquidity\":80,\"data_quality\":98,\"available_index\":47,\"eligible\":true},{\"symbol\":\"SYNTH-B\",\"state\":\"candidate\",\"divergence_type\":\"regular-bearish\",\"confluence_score\":91,\"freshness\":98,\"liquidity\":72,\"data_quality\":94,\"available_index\":54,\"eligible\":true},{\"symbol\":\"SYNTH-C\",\"state\":\"confirmed\",\"divergence_type\":\"hidden-bullish\",\"confluence_score\":74,\"freshness\":70,\"liquidity\":96,\"data_quality\":90,\"available_index\":39,\"eligible\":true}]})",
        "args": [
          {
            "value": {
              "topic_id": "D08-F05-A03",
              "data_class": "synthetic-teaching",
              "as_of": "2026-01-08T13:30:00Z",
              "bars": [
                {
                  "timestamp": "2026-01-05T14:30:00Z",
                  "open": 105.75,
                  "high": 107,
                  "low": 105,
                  "close": 106,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T15:30:00Z",
                  "open": 106.112,
                  "high": 107.362,
                  "low": 105.362,
                  "close": 106.362,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T16:30:00Z",
                  "open": 106.4614,
                  "high": 107.7114,
                  "low": 105.7114,
                  "close": 106.7114,
                  "finalized": true
                }
              ],
              "price_pivots": [
                {
                  "kind": "low",
                  "event_index": 18,
                  "confirmation_index": 21,
                  "price": 98,
                  "prominence": 0.72
                },
                {
                  "kind": "low",
                  "event_index": 42,
                  "confirmation_index": 45,
                  "price": 102,
                  "prominence": 0.84
                }
              ],
              "indicators": [
                {
                  "name": "RSI",
                  "family": "bounded-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 19,
                      "confirmation_index": 22,
                      "value": 36,
                      "prominence": 0.76
                    },
                    {
                      "kind": "low",
                      "event_index": 41,
                      "confirmation_index": 44,
                      "value": 28,
                      "prominence": 0.86
                    }
                  ]
                },
                {
                  "name": "MACD-Histogram",
                  "family": "moving-average-momentum",
                  "polarity": 1,
                  "scale": 5,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 18,
                      "confirmation_index": 21,
                      "value": -1,
                      "prominence": 0.7
                    },
                    {
                      "kind": "low",
                      "event_index": 42,
                      "confirmation_index": 45,
                      "value": -2.2,
                      "prominence": 0.81
                    }
                  ]
                },
                {
                  "name": "Stochastic-K",
                  "family": "range-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 17,
                      "confirmation_index": 20,
                      "value": 31,
                      "prominence": 0.68
                    },
                    {
                      "kind": "low",
                      "event_index": 43,
                      "confirmation_index": 46,
                      "value": 19,
                      "prominence": 0.78
                    }
                  ]
                }
              ],
              "parameters": {
                "max_lag": 3,
                "min_separation": 5,
                "max_separation": 40,
                "min_price_fraction": 0.005,
                "min_indicator_delta": 0.05,
                "confirmation_horizon": 12,
                "invalidation_buffer": 0.005,
                "minimum_indicators": 2
              },
              "weights": {
                "RSI": 0.4,
                "MACD-Histogram": 0.35,
                "Stochastic-K": 0.25
              },
              "as_of_index": 71,
              "universe": [
                {
                  "symbol": "SYNTH-A",
                  "state": "confirmed",
                  "divergence_type": "regular-bullish",
                  "confluence_score": 86,
                  "freshness": 92,
                  "liquidity": 80,
                  "data_quality": 98,
                  "available_index": 47,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-B",
                  "state": "candidate",
                  "divergence_type": "regular-bearish",
                  "confluence_score": 91,
                  "freshness": 98,
                  "liquidity": 72,
                  "data_quality": 94,
                  "available_index": 54,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-C",
                  "state": "confirmed",
                  "divergence_type": "hidden-bullish",
                  "confluence_score": 74,
                  "freshness": 70,
                  "liquidity": 96,
                  "data_quality": 90,
                  "available_index": 39,
                  "eligible": true
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F05-A03",
          "state": "detected",
          "events": [
            {
              "type": "hidden-bullish",
              "direction": "bullish",
              "kind": "low",
              "indicator": "MACD-Histogram",
              "indicator_family": "moving-average-momentum",
              "price_pair": [
                18,
                42
              ],
              "indicator_pair": [
                18,
                42
              ],
              "price_values": [
                98,
                102
              ],
              "indicator_values": [
                -0.2,
                -0.44000000000000006
              ],
              "price_delta_fraction": 0.04081632653061224,
              "indicator_delta": -0.24000000000000005,
              "separation": 24,
              "max_alignment_lag": 0,
              "prominence": 0.7675
            },
            {
              "type": "hidden-bullish",
              "direction": "bullish",
              "kind": "low",
              "indicator": "RSI",
              "indicator_family": "bounded-momentum",
              "price_pair": [
                18,
                42
              ],
              "indicator_pair": [
                19,
                41
              ],
              "price_values": [
                98,
                102
              ],
              "indicator_values": [
                0.36,
                0.28
              ],
              "price_delta_fraction": 0.04081632653061224,
              "indicator_delta": -0.07999999999999996,
              "separation": 24,
              "max_alignment_lag": 1,
              "prominence": 0.795
            },
            {
              "type": "hidden-bullish",
              "direction": "bullish",
              "kind": "low",
              "indicator": "Stochastic-K",
              "indicator_family": "range-momentum",
              "price_pair": [
                18,
                42
              ],
              "indicator_pair": [
                17,
                43
              ],
              "price_values": [
                98,
                102
              ],
              "indicator_values": [
                0.31,
                0.19
              ],
              "price_delta_fraction": 0.04081632653061224,
              "indicator_delta": -0.12,
              "separation": 24,
              "max_alignment_lag": 1,
              "prominence": 0.7550000000000001
            }
          ],
          "event_count": 3
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: topic_id, state, events, event_count"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a03/static/map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "TradingView — RSI divergence indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000589127-rsi-divergence-indicator/"
        },
        {
          "key": "S2",
          "title": "TradingView — MACD indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502344-moving-average-convergence-divergence-macd-indicator/"
        },
        {
          "key": "S3",
          "title": "TradingView Pine Script — Repainting",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/concepts/repainting/"
        },
        {
          "key": "S4",
          "title": "TradingView Pine Script — Visuals FAQ",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/faq/visuals/"
        },
        {
          "key": "S5",
          "title": "Fidelity — Relative Strength Index",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/RSI"
        },
        {
          "key": "S6",
          "title": "Fidelity — MACD",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/macd"
        },
        {
          "key": "S7",
          "title": "TA-Lib — Function index",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S8",
          "title": "TA-Lib — RSI",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/rsi.html"
        },
        {
          "key": "S9",
          "title": "SciPy — find_peaks",
          "author": "SciPy",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S10",
          "title": "Bailey et al. — Effects of Backtest Overfitting",
          "author": "Bailey et al.",
          "url": "https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2308659"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        },
        {
          "key": "Topic-specific applicability map",
          "title": "Topic-specific applicability map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/indicator-divergence-detection/hidden-bullish-bearish-divergence-detection/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/indicator-divergence-detection/hidden-bullish-bearish-divergence-detection/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F05-A04",
      "name": "Multi-Indicator Divergence Adapters",
      "headline": null,
      "slug": "multi-indicator-divergence-adapters",
      "path": "geometric-chart-patterns/indicator-divergence-detection/multi-indicator-divergence-adapters",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F05",
        "family": "Indicator Divergence Detection",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/indicator-divergence-detection/multi-indicator-divergence-adapters",
        "entry": "multiIndicatorDivergenceAdapters",
        "params": [
          "payload"
        ],
        "exports": [
          "adaptIndicator",
          "alignPivots",
          "detectDivergences",
          "scoreDivergence",
          "advanceState",
          "combineConfluence",
          "rankUniverse",
          "runTopic",
          "priceIndicatorPivotAlignment",
          "regularBullishBearishDivergenceDetection",
          "hiddenBullishBearishDivergenceDetection",
          "multiIndicatorDivergenceAdapters",
          "divergenceStrengthAndQualityScoring",
          "divergenceConfirmationAndInvalidationStateMachine",
          "multiIndicatorDivergenceConfluence",
          "marketWideDivergenceScannerAndRanking"
        ],
        "archetype": "record-transform",
        "signature": "multiIndicatorDivergenceAdapters(payload)"
      },
      "api": {
        "summary": "Normalizes indicator pivots into one polarity- and scale-aware representation for downstream divergence logic.",
        "params": [
          {
            "name": "payload",
            "type": "{ topic_id: string; data_class: string; as_of: string; bars: { timestamp: string; open: number; high: number; low: number; close: number; finalized: boolean }[]; price_pivots: { kind: string; event_index: number; confirmation_index: number; price: number; prominence: number }[]; indicators: { name: string; family: string; polarity: number; scale: number; pivots: { kind: string; event_index: number; confirmation_index: number; value: number; prominence: number }[] }[]; parameters: { max_lag: number; min_separation: number; max_separation: number; min_price_fraction: number; min_indicator_delta: number; confirmation_horizon: number; invalidation_buffer: number; minimum_indicators: number }; weights: { RSI: number; MACD-Histogram: number; Stochastic-K: number }; as_of_index: number; universe: { symbol: string; state: string; divergence_type: string; confluence_score: number; freshness: number; liquidity: number; data_quality: number; available_index: number; eligible: boolean }[] }",
            "required": true,
            "description": "Topic payload containing zero or more named indicator definitions and their confirmed pivots.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, state, adapters, adapter_count }",
          "description": "One adapter record. `state` is `warmup` when no indicators were supplied and `ready` when at least one adapter was built; no positional warmup series is returned."
        },
        "warmup": {
          "count": "1 supplied indicator",
          "value": "state: warmup",
          "note": "The function returns one adapter record when no indicator is supplied; it does not emit a positional null prefix."
        },
        "errors": [
          {
            "when": "an indicator lacks valid identity, family, polarity, scale, or pivot fields",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(pivots)\", space: \"O(pivots)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "multiIndicatorDivergenceAdapters({\"topic_id\":\"D08-F05-A04\",\"data_class\":\"synthetic-teaching\",\"as_of\":\"2026-01-08T13:30:00Z\",\"bars\":[{\"timestamp\":\"2026-01-05T14:30:00Z\",\"open\":105.75,\"high\":107,\"low\":105,\"close\":106,\"finalized\":true},{\"timestamp\":\"2026-01-05T15:30:00Z\",\"open\":106.112,\"high\":107.362,\"low\":105.362,\"close\":106.362,\"finalized\":true},{\"timestamp\":\"2026-01-05T16:30:00Z\",\"open\":106.4614,\"high\":107.7114,\"low\":105.7114,\"close\":106.7114,\"finalized\":true}],\"price_pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"price\":98,\"prominence\":0.72},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"price\":94,\"prominence\":0.84}],\"indicators\":[{\"name\":\"RSI\",\"family\":\"bounded-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":19,\"confirmation_index\":22,\"value\":28,\"prominence\":0.76},{\"kind\":\"low\",\"event_index\":41,\"confirmation_index\":44,\"value\":36,\"prominence\":0.86}]},{\"name\":\"MACD-Histogram\",\"family\":\"moving-average-momentum\",\"polarity\":1,\"scale\":5,\"pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"value\":-2.2,\"prominence\":0.7},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"value\":-1,\"prominence\":0.81}]},{\"name\":\"Stochastic-K\",\"family\":\"range-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":17,\"confirmation_index\":20,\"value\":18,\"prominence\":0.68},{\"kind\":\"low\",\"event_index\":43,\"confirmation_index\":46,\"value\":29,\"prominence\":0.78}]}],\"parameters\":{\"max_lag\":3,\"min_separation\":5,\"max_separation\":40,\"min_price_fraction\":0.005,\"min_indicator_delta\":0.05,\"confirmation_horizon\":12,\"invalidation_buffer\":0.005,\"minimum_indicators\":2},\"weights\":{\"RSI\":0.4,\"MACD-Histogram\":0.35,\"Stochastic-K\":0.25},\"as_of_index\":71,\"universe\":[{\"symbol\":\"SYNTH-A\",\"state\":\"confirmed\",\"divergence_type\":\"regular-bullish\",\"confluence_score\":86,\"freshness\":92,\"liquidity\":80,\"data_quality\":98,\"available_index\":47,\"eligible\":true},{\"symbol\":\"SYNTH-B\",\"state\":\"candidate\",\"divergence_type\":\"regular-bearish\",\"confluence_score\":91,\"freshness\":98,\"liquidity\":72,\"data_quality\":94,\"available_index\":54,\"eligible\":true},{\"symbol\":\"SYNTH-C\",\"state\":\"confirmed\",\"divergence_type\":\"hidden-bullish\",\"confluence_score\":74,\"freshness\":70,\"liquidity\":96,\"data_quality\":90,\"available_index\":39,\"eligible\":true}]})",
        "args": [
          {
            "value": {
              "topic_id": "D08-F05-A04",
              "data_class": "synthetic-teaching",
              "as_of": "2026-01-08T13:30:00Z",
              "bars": [
                {
                  "timestamp": "2026-01-05T14:30:00Z",
                  "open": 105.75,
                  "high": 107,
                  "low": 105,
                  "close": 106,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T15:30:00Z",
                  "open": 106.112,
                  "high": 107.362,
                  "low": 105.362,
                  "close": 106.362,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T16:30:00Z",
                  "open": 106.4614,
                  "high": 107.7114,
                  "low": 105.7114,
                  "close": 106.7114,
                  "finalized": true
                }
              ],
              "price_pivots": [
                {
                  "kind": "low",
                  "event_index": 18,
                  "confirmation_index": 21,
                  "price": 98,
                  "prominence": 0.72
                },
                {
                  "kind": "low",
                  "event_index": 42,
                  "confirmation_index": 45,
                  "price": 94,
                  "prominence": 0.84
                }
              ],
              "indicators": [
                {
                  "name": "RSI",
                  "family": "bounded-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 19,
                      "confirmation_index": 22,
                      "value": 28,
                      "prominence": 0.76
                    },
                    {
                      "kind": "low",
                      "event_index": 41,
                      "confirmation_index": 44,
                      "value": 36,
                      "prominence": 0.86
                    }
                  ]
                },
                {
                  "name": "MACD-Histogram",
                  "family": "moving-average-momentum",
                  "polarity": 1,
                  "scale": 5,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 18,
                      "confirmation_index": 21,
                      "value": -2.2,
                      "prominence": 0.7
                    },
                    {
                      "kind": "low",
                      "event_index": 42,
                      "confirmation_index": 45,
                      "value": -1,
                      "prominence": 0.81
                    }
                  ]
                },
                {
                  "name": "Stochastic-K",
                  "family": "range-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 17,
                      "confirmation_index": 20,
                      "value": 18,
                      "prominence": 0.68
                    },
                    {
                      "kind": "low",
                      "event_index": 43,
                      "confirmation_index": 46,
                      "value": 29,
                      "prominence": 0.78
                    }
                  ]
                }
              ],
              "parameters": {
                "max_lag": 3,
                "min_separation": 5,
                "max_separation": 40,
                "min_price_fraction": 0.005,
                "min_indicator_delta": 0.05,
                "confirmation_horizon": 12,
                "invalidation_buffer": 0.005,
                "minimum_indicators": 2
              },
              "weights": {
                "RSI": 0.4,
                "MACD-Histogram": 0.35,
                "Stochastic-K": 0.25
              },
              "as_of_index": 71,
              "universe": [
                {
                  "symbol": "SYNTH-A",
                  "state": "confirmed",
                  "divergence_type": "regular-bullish",
                  "confluence_score": 86,
                  "freshness": 92,
                  "liquidity": 80,
                  "data_quality": 98,
                  "available_index": 47,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-B",
                  "state": "candidate",
                  "divergence_type": "regular-bearish",
                  "confluence_score": 91,
                  "freshness": 98,
                  "liquidity": 72,
                  "data_quality": 94,
                  "available_index": 54,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-C",
                  "state": "confirmed",
                  "divergence_type": "hidden-bullish",
                  "confluence_score": 74,
                  "freshness": 70,
                  "liquidity": 96,
                  "data_quality": 90,
                  "available_index": 39,
                  "eligible": true
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F05-A04",
          "state": "ready",
          "adapters": [
            {
              "name": "RSI",
              "family": "bounded-momentum",
              "polarity": 1,
              "scale": 100,
              "pivots": [
                {
                  "kind": "low",
                  "event_index": 19,
                  "confirmation_index": 22,
                  "raw_value": 28,
                  "normalized_value": 0.28,
                  "prominence": 0.76
                },
                {
                  "kind": "low",
                  "event_index": 41,
                  "confirmation_index": 44,
                  "raw_value": 36,
                  "normalized_value": 0.36,
                  "prominence": 0.86
                }
              ]
            },
            {
              "name": "MACD-Histogram",
              "family": "moving-average-momentum",
              "polarity": 1,
              "scale": 5,
              "pivots": [
                {
                  "kind": "low",
                  "event_index": 18,
                  "confirmation_index": 21,
                  "raw_value": -2.2,
                  "normalized_value": -0.44000000000000006,
                  "prominence": 0.7
                },
                {
                  "kind": "low",
                  "event_index": 42,
                  "confirmation_index": 45,
                  "raw_value": -1,
                  "normalized_value": -0.2,
                  "prominence": 0.81
                }
              ]
            },
            {
              "name": "Stochastic-K",
              "family": "range-momentum",
              "polarity": 1,
              "scale": 100,
              "pivots": [
                {
                  "kind": "low",
                  "event_index": 17,
                  "confirmation_index": 20,
                  "raw_value": 18,
                  "normalized_value": 0.18,
                  "prominence": 0.68
                },
                {
                  "kind": "low",
                  "event_index": 43,
                  "confirmation_index": 46,
                  "raw_value": 29,
                  "normalized_value": 0.29,
                  "prominence": 0.78
                }
              ]
            }
          ],
          "adapter_count": 3
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: topic_id, state, adapters, adapter_count"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a04/static/map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "TradingView — RSI divergence indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000589127-rsi-divergence-indicator/"
        },
        {
          "key": "S2",
          "title": "TradingView — MACD indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502344-moving-average-convergence-divergence-macd-indicator/"
        },
        {
          "key": "S3",
          "title": "TradingView Pine Script — Repainting",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/concepts/repainting/"
        },
        {
          "key": "S4",
          "title": "TradingView Pine Script — Visuals FAQ",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/faq/visuals/"
        },
        {
          "key": "S5",
          "title": "Fidelity — Relative Strength Index",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/RSI"
        },
        {
          "key": "S6",
          "title": "Fidelity — MACD",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/macd"
        },
        {
          "key": "S7",
          "title": "TA-Lib — Function index",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S8",
          "title": "TA-Lib — RSI",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/rsi.html"
        },
        {
          "key": "S9",
          "title": "SciPy — find_peaks",
          "author": "SciPy",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S10",
          "title": "Bailey et al. — Effects of Backtest Overfitting",
          "author": "Bailey et al.",
          "url": "https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2308659"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        },
        {
          "key": "Topic-specific applicability map",
          "title": "Topic-specific applicability map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/indicator-divergence-detection/multi-indicator-divergence-adapters/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/indicator-divergence-detection/multi-indicator-divergence-adapters/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F05-A05",
      "name": "Divergence Strength and Quality Scoring",
      "headline": null,
      "slug": "divergence-strength-and-quality-scoring",
      "path": "geometric-chart-patterns/indicator-divergence-detection/divergence-strength-and-quality-scoring",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F05",
        "family": "Indicator Divergence Detection",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/indicator-divergence-detection/divergence-strength-and-quality-scoring",
        "entry": "divergenceStrengthAndQualityScoring",
        "params": [
          "payload"
        ],
        "exports": [
          "adaptIndicator",
          "alignPivots",
          "detectDivergences",
          "scoreDivergence",
          "advanceState",
          "combineConfluence",
          "rankUniverse",
          "runTopic",
          "priceIndicatorPivotAlignment",
          "regularBullishBearishDivergenceDetection",
          "hiddenBullishBearishDivergenceDetection",
          "multiIndicatorDivergenceAdapters",
          "divergenceStrengthAndQualityScoring",
          "divergenceConfirmationAndInvalidationStateMachine",
          "multiIndicatorDivergenceConfluence",
          "marketWideDivergenceScannerAndRanking"
        ],
        "archetype": "record-transform",
        "signature": "divergenceStrengthAndQualityScoring(payload)"
      },
      "api": {
        "summary": "Scores the first detected divergence from explicit geometry, prominence, alignment, and separation components.",
        "params": [
          {
            "name": "payload",
            "type": "{ topic_id: string; data_class: string; as_of: string; bars: { timestamp: string; open: number; high: number; low: number; close: number; finalized: boolean }[]; price_pivots: { kind: string; event_index: number; confirmation_index: number; price: number; prominence: number }[]; indicators: { name: string; family: string; polarity: number; scale: number; pivots: { kind: string; event_index: number; confirmation_index: number; value: number; prominence: number }[] }[]; parameters: { max_lag: number; min_separation: number; max_separation: number; min_price_fraction: number; min_indicator_delta: number; confirmation_horizon: number; invalidation_buffer: number; minimum_indicators: number }; weights: { RSI: number; MACD-Histogram: number; Stochastic-K: number }; as_of_index: number; universe: { symbol: string; state: string; divergence_type: string; confluence_score: number; freshness: number; liquidity: number; data_quality: number; available_index: number; eligible: boolean }[] }",
            "required": true,
            "description": "Topic payload containing the price pivots, indicators, and detection parameters needed to produce a divergence event.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, state, event?, score, reason? }",
          "description": "One scoring record: `not-detected` with null score and a reason, or `scored` with the event and component score object."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the underlying pivot, indicator, detection, or score inputs are invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(k x p x q log q)\", space: \"O(p + q + events)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "divergenceStrengthAndQualityScoring({\"topic_id\":\"D08-F05-A05\",\"data_class\":\"synthetic-teaching\",\"as_of\":\"2026-01-08T13:30:00Z\",\"bars\":[{\"timestamp\":\"2026-01-05T14:30:00Z\",\"open\":105.75,\"high\":107,\"low\":105,\"close\":106,\"finalized\":true},{\"timestamp\":\"2026-01-05T15:30:00Z\",\"open\":106.112,\"high\":107.362,\"low\":105.362,\"close\":106.362,\"finalized\":true},{\"timestamp\":\"2026-01-05T16:30:00Z\",\"open\":106.4614,\"high\":107.7114,\"low\":105.7114,\"close\":106.7114,\"finalized\":true}],\"price_pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"price\":98,\"prominence\":0.72},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"price\":94,\"prominence\":0.84}],\"indicators\":[{\"name\":\"RSI\",\"family\":\"bounded-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":19,\"confirmation_index\":22,\"value\":28,\"prominence\":0.76},{\"kind\":\"low\",\"event_index\":41,\"confirmation_index\":44,\"value\":36,\"prominence\":0.86}]},{\"name\":\"MACD-Histogram\",\"family\":\"moving-average-momentum\",\"polarity\":1,\"scale\":5,\"pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"value\":-2.2,\"prominence\":0.7},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"value\":-1,\"prominence\":0.81}]},{\"name\":\"Stochastic-K\",\"family\":\"range-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":17,\"confirmation_index\":20,\"value\":18,\"prominence\":0.68},{\"kind\":\"low\",\"event_index\":43,\"confirmation_index\":46,\"value\":29,\"prominence\":0.78}]}],\"parameters\":{\"max_lag\":3,\"min_separation\":5,\"max_separation\":40,\"min_price_fraction\":0.005,\"min_indicator_delta\":0.05,\"confirmation_horizon\":12,\"invalidation_buffer\":0.005,\"minimum_indicators\":2},\"weights\":{\"RSI\":0.4,\"MACD-Histogram\":0.35,\"Stochastic-K\":0.25},\"as_of_index\":71,\"universe\":[{\"symbol\":\"SYNTH-A\",\"state\":\"confirmed\",\"divergence_type\":\"regular-bullish\",\"confluence_score\":86,\"freshness\":92,\"liquidity\":80,\"data_quality\":98,\"available_index\":47,\"eligible\":true},{\"symbol\":\"SYNTH-B\",\"state\":\"candidate\",\"divergence_type\":\"regular-bearish\",\"confluence_score\":91,\"freshness\":98,\"liquidity\":72,\"data_quality\":94,\"available_index\":54,\"eligible\":true},{\"symbol\":\"SYNTH-C\",\"state\":\"confirmed\",\"divergence_type\":\"hidden-bullish\",\"confluence_score\":74,\"freshness\":70,\"liquidity\":96,\"data_quality\":90,\"available_index\":39,\"eligible\":true}]})",
        "args": [
          {
            "value": {
              "topic_id": "D08-F05-A05",
              "data_class": "synthetic-teaching",
              "as_of": "2026-01-08T13:30:00Z",
              "bars": [
                {
                  "timestamp": "2026-01-05T14:30:00Z",
                  "open": 105.75,
                  "high": 107,
                  "low": 105,
                  "close": 106,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T15:30:00Z",
                  "open": 106.112,
                  "high": 107.362,
                  "low": 105.362,
                  "close": 106.362,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T16:30:00Z",
                  "open": 106.4614,
                  "high": 107.7114,
                  "low": 105.7114,
                  "close": 106.7114,
                  "finalized": true
                }
              ],
              "price_pivots": [
                {
                  "kind": "low",
                  "event_index": 18,
                  "confirmation_index": 21,
                  "price": 98,
                  "prominence": 0.72
                },
                {
                  "kind": "low",
                  "event_index": 42,
                  "confirmation_index": 45,
                  "price": 94,
                  "prominence": 0.84
                }
              ],
              "indicators": [
                {
                  "name": "RSI",
                  "family": "bounded-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 19,
                      "confirmation_index": 22,
                      "value": 28,
                      "prominence": 0.76
                    },
                    {
                      "kind": "low",
                      "event_index": 41,
                      "confirmation_index": 44,
                      "value": 36,
                      "prominence": 0.86
                    }
                  ]
                },
                {
                  "name": "MACD-Histogram",
                  "family": "moving-average-momentum",
                  "polarity": 1,
                  "scale": 5,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 18,
                      "confirmation_index": 21,
                      "value": -2.2,
                      "prominence": 0.7
                    },
                    {
                      "kind": "low",
                      "event_index": 42,
                      "confirmation_index": 45,
                      "value": -1,
                      "prominence": 0.81
                    }
                  ]
                },
                {
                  "name": "Stochastic-K",
                  "family": "range-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 17,
                      "confirmation_index": 20,
                      "value": 18,
                      "prominence": 0.68
                    },
                    {
                      "kind": "low",
                      "event_index": 43,
                      "confirmation_index": 46,
                      "value": 29,
                      "prominence": 0.78
                    }
                  ]
                }
              ],
              "parameters": {
                "max_lag": 3,
                "min_separation": 5,
                "max_separation": 40,
                "min_price_fraction": 0.005,
                "min_indicator_delta": 0.05,
                "confirmation_horizon": 12,
                "invalidation_buffer": 0.005,
                "minimum_indicators": 2
              },
              "weights": {
                "RSI": 0.4,
                "MACD-Histogram": 0.35,
                "Stochastic-K": 0.25
              },
              "as_of_index": 71,
              "universe": [
                {
                  "symbol": "SYNTH-A",
                  "state": "confirmed",
                  "divergence_type": "regular-bullish",
                  "confluence_score": 86,
                  "freshness": 92,
                  "liquidity": 80,
                  "data_quality": 98,
                  "available_index": 47,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-B",
                  "state": "candidate",
                  "divergence_type": "regular-bearish",
                  "confluence_score": 91,
                  "freshness": 98,
                  "liquidity": 72,
                  "data_quality": 94,
                  "available_index": 54,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-C",
                  "state": "confirmed",
                  "divergence_type": "hidden-bullish",
                  "confluence_score": 74,
                  "freshness": 70,
                  "liquidity": 96,
                  "data_quality": 90,
                  "available_index": 39,
                  "eligible": true
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F05-A05",
          "state": "scored",
          "event": {
            "type": "regular-bullish",
            "direction": "bullish",
            "kind": "low",
            "indicator": "MACD-Histogram",
            "indicator_family": "moving-average-momentum",
            "price_pair": [
              18,
              42
            ],
            "indicator_pair": [
              18,
              42
            ],
            "price_values": [
              98,
              94
            ],
            "indicator_values": [
              -0.44000000000000006,
              -0.2
            ],
            "price_delta_fraction": -0.04081632653061224,
            "indicator_delta": 0.24000000000000005,
            "separation": 24,
            "max_alignment_lag": 0,
            "prominence": 0.7675
          },
          "score": {
            "score": 95.815,
            "quality": "exceptional",
            "components": {
              "price_geometry": 1,
              "indicator_geometry": 1,
              "prominence": 0.7675,
              "alignment": 1,
              "separation": 1
            },
            "interpretation": "definition-strength score; not probability or expected return"
          }
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: topic_id, state, event, score"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a05/static/map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "TradingView — RSI divergence indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000589127-rsi-divergence-indicator/"
        },
        {
          "key": "S2",
          "title": "TradingView — MACD indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502344-moving-average-convergence-divergence-macd-indicator/"
        },
        {
          "key": "S3",
          "title": "TradingView Pine Script — Repainting",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/concepts/repainting/"
        },
        {
          "key": "S4",
          "title": "TradingView Pine Script — Visuals FAQ",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/faq/visuals/"
        },
        {
          "key": "S5",
          "title": "Fidelity — Relative Strength Index",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/RSI"
        },
        {
          "key": "S6",
          "title": "Fidelity — MACD",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/macd"
        },
        {
          "key": "S7",
          "title": "TA-Lib — Function index",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S8",
          "title": "TA-Lib — RSI",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/rsi.html"
        },
        {
          "key": "S9",
          "title": "SciPy — find_peaks",
          "author": "SciPy",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S10",
          "title": "Bailey et al. — Effects of Backtest Overfitting",
          "author": "Bailey et al.",
          "url": "https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2308659"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        },
        {
          "key": "Topic-specific applicability map",
          "title": "Topic-specific applicability map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/indicator-divergence-detection/divergence-strength-and-quality-scoring/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/indicator-divergence-detection/divergence-strength-and-quality-scoring/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F05-A06",
      "name": "Divergence Confirmation and Invalidation State Machine",
      "headline": null,
      "slug": "divergence-confirmation-and-invalidation-state-machine",
      "path": "geometric-chart-patterns/indicator-divergence-detection/divergence-confirmation-and-invalidation-state-machine",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F05",
        "family": "Indicator Divergence Detection",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/indicator-divergence-detection/divergence-confirmation-and-invalidation-state-machine",
        "entry": "divergenceConfirmationAndInvalidationStateMachine",
        "params": [
          "payload"
        ],
        "exports": [
          "adaptIndicator",
          "alignPivots",
          "detectDivergences",
          "scoreDivergence",
          "advanceState",
          "combineConfluence",
          "rankUniverse",
          "runTopic",
          "priceIndicatorPivotAlignment",
          "regularBullishBearishDivergenceDetection",
          "hiddenBullishBearishDivergenceDetection",
          "multiIndicatorDivergenceAdapters",
          "divergenceStrengthAndQualityScoring",
          "divergenceConfirmationAndInvalidationStateMachine",
          "multiIndicatorDivergenceConfluence",
          "marketWideDivergenceScannerAndRanking"
        ],
        "archetype": "record-transform",
        "signature": "divergenceConfirmationAndInvalidationStateMachine(payload)"
      },
      "api": {
        "summary": "Advances the first detected divergence through causal confirmation, invalidation, and expiry checks.",
        "params": [
          {
            "name": "payload",
            "type": "{ topic_id: string; data_class: string; as_of: string; bars: { timestamp: string; open: number; high: number; low: number; close: number; finalized: boolean }[]; price_pivots: { kind: string; event_index: number; confirmation_index: number; price: number; prominence: number }[]; indicators: { name: string; family: string; polarity: number; scale: number; pivots: { kind: string; event_index: number; confirmation_index: number; value: number; prominence: number }[] }[]; parameters: { max_lag: number; min_separation: number; max_separation: number; min_price_fraction: number; min_indicator_delta: number; confirmation_horizon: number; invalidation_buffer: number; minimum_indicators: number }; weights: { RSI: number; MACD-Histogram: number; Stochastic-K: number }; as_of_index: number; universe: { symbol: string; state: string; divergence_type: string; confluence_score: number; freshness: number; liquidity: number; data_quality: number; available_index: number; eligible: boolean }[] }",
            "required": true,
            "description": "Topic payload containing divergence inputs, bars, confirmation horizon, and invalidation buffer.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, state, event, lifecycle }",
          "description": "One lifecycle record. Without an event, `state` is `searching`; otherwise it mirrors the lifecycle state (`candidate`, `confirmed`, `invalidated`, or `expired`) and includes causal levels and trace."
        },
        "warmup": null,
        "errors": [
          {
            "when": "detection input, bar data, confirmation horizon, or invalidation buffer is invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(k x p x q log q + bars)\", space: \"O(events + bars)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "divergenceConfirmationAndInvalidationStateMachine({\"topic_id\":\"D08-F05-A06\",\"data_class\":\"synthetic-teaching\",\"as_of\":\"2026-01-08T13:30:00Z\",\"bars\":[{\"timestamp\":\"2026-01-05T14:30:00Z\",\"open\":105.75,\"high\":107,\"low\":105,\"close\":106,\"finalized\":true},{\"timestamp\":\"2026-01-05T15:30:00Z\",\"open\":106.112,\"high\":107.362,\"low\":105.362,\"close\":106.362,\"finalized\":true},{\"timestamp\":\"2026-01-05T16:30:00Z\",\"open\":106.4614,\"high\":107.7114,\"low\":105.7114,\"close\":106.7114,\"finalized\":true}],\"price_pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"price\":98,\"prominence\":0.72},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"price\":94,\"prominence\":0.84}],\"indicators\":[{\"name\":\"RSI\",\"family\":\"bounded-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":19,\"confirmation_index\":22,\"value\":28,\"prominence\":0.76},{\"kind\":\"low\",\"event_index\":41,\"confirmation_index\":44,\"value\":36,\"prominence\":0.86}]},{\"name\":\"MACD-Histogram\",\"family\":\"moving-average-momentum\",\"polarity\":1,\"scale\":5,\"pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"value\":-2.2,\"prominence\":0.7},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"value\":-1,\"prominence\":0.81}]},{\"name\":\"Stochastic-K\",\"family\":\"range-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":17,\"confirmation_index\":20,\"value\":18,\"prominence\":0.68},{\"kind\":\"low\",\"event_index\":43,\"confirmation_index\":46,\"value\":29,\"prominence\":0.78}]}],\"parameters\":{\"max_lag\":3,\"min_separation\":5,\"max_separation\":40,\"min_price_fraction\":0.005,\"min_indicator_delta\":0.05,\"confirmation_horizon\":12,\"invalidation_buffer\":0.005,\"minimum_indicators\":2},\"weights\":{\"RSI\":0.4,\"MACD-Histogram\":0.35,\"Stochastic-K\":0.25},\"as_of_index\":71,\"universe\":[{\"symbol\":\"SYNTH-A\",\"state\":\"confirmed\",\"divergence_type\":\"regular-bullish\",\"confluence_score\":86,\"freshness\":92,\"liquidity\":80,\"data_quality\":98,\"available_index\":47,\"eligible\":true},{\"symbol\":\"SYNTH-B\",\"state\":\"candidate\",\"divergence_type\":\"regular-bearish\",\"confluence_score\":91,\"freshness\":98,\"liquidity\":72,\"data_quality\":94,\"available_index\":54,\"eligible\":true},{\"symbol\":\"SYNTH-C\",\"state\":\"confirmed\",\"divergence_type\":\"hidden-bullish\",\"confluence_score\":74,\"freshness\":70,\"liquidity\":96,\"data_quality\":90,\"available_index\":39,\"eligible\":true}]})",
        "args": [
          {
            "value": {
              "topic_id": "D08-F05-A06",
              "data_class": "synthetic-teaching",
              "as_of": "2026-01-08T13:30:00Z",
              "bars": [
                {
                  "timestamp": "2026-01-05T14:30:00Z",
                  "open": 105.75,
                  "high": 107,
                  "low": 105,
                  "close": 106,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T15:30:00Z",
                  "open": 106.112,
                  "high": 107.362,
                  "low": 105.362,
                  "close": 106.362,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T16:30:00Z",
                  "open": 106.4614,
                  "high": 107.7114,
                  "low": 105.7114,
                  "close": 106.7114,
                  "finalized": true
                }
              ],
              "price_pivots": [
                {
                  "kind": "low",
                  "event_index": 18,
                  "confirmation_index": 21,
                  "price": 98,
                  "prominence": 0.72
                },
                {
                  "kind": "low",
                  "event_index": 42,
                  "confirmation_index": 45,
                  "price": 94,
                  "prominence": 0.84
                }
              ],
              "indicators": [
                {
                  "name": "RSI",
                  "family": "bounded-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 19,
                      "confirmation_index": 22,
                      "value": 28,
                      "prominence": 0.76
                    },
                    {
                      "kind": "low",
                      "event_index": 41,
                      "confirmation_index": 44,
                      "value": 36,
                      "prominence": 0.86
                    }
                  ]
                },
                {
                  "name": "MACD-Histogram",
                  "family": "moving-average-momentum",
                  "polarity": 1,
                  "scale": 5,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 18,
                      "confirmation_index": 21,
                      "value": -2.2,
                      "prominence": 0.7
                    },
                    {
                      "kind": "low",
                      "event_index": 42,
                      "confirmation_index": 45,
                      "value": -1,
                      "prominence": 0.81
                    }
                  ]
                },
                {
                  "name": "Stochastic-K",
                  "family": "range-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 17,
                      "confirmation_index": 20,
                      "value": 18,
                      "prominence": 0.68
                    },
                    {
                      "kind": "low",
                      "event_index": 43,
                      "confirmation_index": 46,
                      "value": 29,
                      "prominence": 0.78
                    }
                  ]
                }
              ],
              "parameters": {
                "max_lag": 3,
                "min_separation": 5,
                "max_separation": 40,
                "min_price_fraction": 0.005,
                "min_indicator_delta": 0.05,
                "confirmation_horizon": 12,
                "invalidation_buffer": 0.005,
                "minimum_indicators": 2
              },
              "weights": {
                "RSI": 0.4,
                "MACD-Histogram": 0.35,
                "Stochastic-K": 0.25
              },
              "as_of_index": 71,
              "universe": [
                {
                  "symbol": "SYNTH-A",
                  "state": "confirmed",
                  "divergence_type": "regular-bullish",
                  "confluence_score": 86,
                  "freshness": 92,
                  "liquidity": 80,
                  "data_quality": 98,
                  "available_index": 47,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-B",
                  "state": "candidate",
                  "divergence_type": "regular-bearish",
                  "confluence_score": 91,
                  "freshness": 98,
                  "liquidity": 72,
                  "data_quality": 94,
                  "available_index": 54,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-C",
                  "state": "confirmed",
                  "divergence_type": "hidden-bullish",
                  "confluence_score": 74,
                  "freshness": 70,
                  "liquidity": 96,
                  "data_quality": 90,
                  "available_index": 39,
                  "eligible": true
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F05-A06",
          "state": "confirmed",
          "event": {
            "type": "regular-bullish",
            "direction": "bullish",
            "kind": "low",
            "indicator": "MACD-Histogram",
            "indicator_family": "moving-average-momentum",
            "price_pair": [
              18,
              42
            ],
            "indicator_pair": [
              18,
              42
            ],
            "price_values": [
              98,
              94
            ],
            "indicator_values": [
              -0.44000000000000006,
              -0.2
            ],
            "price_delta_fraction": -0.04081632653061224,
            "indicator_delta": 0.24000000000000005,
            "separation": 24,
            "max_alignment_lag": 0,
            "prominence": 0.7675
          },
          "lifecycle": {
            "state": "confirmed",
            "candidate_index": 45,
            "final_index": 47,
            "confirmation_level": 109.5372,
            "invalidation_level": 93.53,
            "deadline": 57,
            "trace": [
              {
                "index": 45,
                "state": "candidate",
                "close": 99
              },
              {
                "index": 46,
                "state": "candidate",
                "close": 103
              },
              {
                "index": 47,
                "state": "confirmed",
                "close": 112
              }
            ]
          }
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: topic_id, state, event, lifecycle"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a06/static/map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "TradingView — RSI divergence indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000589127-rsi-divergence-indicator/"
        },
        {
          "key": "S2",
          "title": "TradingView — MACD indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502344-moving-average-convergence-divergence-macd-indicator/"
        },
        {
          "key": "S3",
          "title": "TradingView Pine Script — Repainting",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/concepts/repainting/"
        },
        {
          "key": "S4",
          "title": "TradingView Pine Script — Visuals FAQ",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/faq/visuals/"
        },
        {
          "key": "S5",
          "title": "Fidelity — Relative Strength Index",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/RSI"
        },
        {
          "key": "S6",
          "title": "Fidelity — MACD",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/macd"
        },
        {
          "key": "S7",
          "title": "TA-Lib — Function index",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S8",
          "title": "TA-Lib — RSI",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/rsi.html"
        },
        {
          "key": "S9",
          "title": "SciPy — find_peaks",
          "author": "SciPy",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S10",
          "title": "Bailey et al. — Effects of Backtest Overfitting",
          "author": "Bailey et al.",
          "url": "https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2308659"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        },
        {
          "key": "Topic-specific applicability map",
          "title": "Topic-specific applicability map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/indicator-divergence-detection/divergence-confirmation-and-invalidation-state-machine/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/indicator-divergence-detection/divergence-confirmation-and-invalidation-state-machine/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F05-A07",
      "name": "Multi-Indicator Divergence Confluence",
      "headline": null,
      "slug": "multi-indicator-divergence-confluence",
      "path": "geometric-chart-patterns/indicator-divergence-detection/multi-indicator-divergence-confluence",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F05",
        "family": "Indicator Divergence Detection",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/indicator-divergence-detection/multi-indicator-divergence-confluence",
        "entry": "multiIndicatorDivergenceConfluence",
        "params": [
          "payload"
        ],
        "exports": [
          "adaptIndicator",
          "alignPivots",
          "detectDivergences",
          "scoreDivergence",
          "advanceState",
          "combineConfluence",
          "rankUniverse",
          "runTopic",
          "priceIndicatorPivotAlignment",
          "regularBullishBearishDivergenceDetection",
          "hiddenBullishBearishDivergenceDetection",
          "multiIndicatorDivergenceAdapters",
          "divergenceStrengthAndQualityScoring",
          "divergenceConfirmationAndInvalidationStateMachine",
          "multiIndicatorDivergenceConfluence",
          "marketWideDivergenceScannerAndRanking"
        ],
        "archetype": "record-transform",
        "signature": "multiIndicatorDivergenceConfluence(payload)"
      },
      "api": {
        "summary": "Combines same-geometry divergence events across distinct indicators using declared non-negative weights.",
        "params": [
          {
            "name": "payload",
            "type": "{ topic_id: string; data_class: string; as_of: string; bars: { timestamp: string; open: number; high: number; low: number; close: number; finalized: boolean }[]; price_pivots: { kind: string; event_index: number; confirmation_index: number; price: number; prominence: number }[]; indicators: { name: string; family: string; polarity: number; scale: number; pivots: { kind: string; event_index: number; confirmation_index: number; value: number; prominence: number }[] }[]; parameters: { max_lag: number; min_separation: number; max_separation: number; min_price_fraction: number; min_indicator_delta: number; confirmation_horizon: number; invalidation_buffer: number; minimum_indicators: number }; weights: { RSI: number; MACD-Histogram: number; Stochastic-K: number }; as_of_index: number; universe: { symbol: string; state: string; divergence_type: string; confluence_score: number; freshness: number; liquidity: number; data_quality: number; available_index: number; eligible: boolean }[] }",
            "required": true,
            "description": "Topic payload containing divergence inputs, indicator weights, and `parameters.minimum_indicators`.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, state, groups, group_count }",
          "description": "One confluence record with `state` equal to `confluent` or `insufficient-confluence` and deterministic group scores."
        },
        "warmup": null,
        "errors": [
          {
            "when": "event, weight, or minimum-indicator input is invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(events log events)\", space: \"O(events)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "multiIndicatorDivergenceConfluence({\"topic_id\":\"D08-F05-A07\",\"data_class\":\"synthetic-teaching\",\"as_of\":\"2026-01-08T13:30:00Z\",\"bars\":[{\"timestamp\":\"2026-01-05T14:30:00Z\",\"open\":105.75,\"high\":107,\"low\":105,\"close\":106,\"finalized\":true},{\"timestamp\":\"2026-01-05T15:30:00Z\",\"open\":106.112,\"high\":107.362,\"low\":105.362,\"close\":106.362,\"finalized\":true},{\"timestamp\":\"2026-01-05T16:30:00Z\",\"open\":106.4614,\"high\":107.7114,\"low\":105.7114,\"close\":106.7114,\"finalized\":true}],\"price_pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"price\":98,\"prominence\":0.72},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"price\":94,\"prominence\":0.84}],\"indicators\":[{\"name\":\"RSI\",\"family\":\"bounded-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":19,\"confirmation_index\":22,\"value\":28,\"prominence\":0.76},{\"kind\":\"low\",\"event_index\":41,\"confirmation_index\":44,\"value\":36,\"prominence\":0.86}]},{\"name\":\"MACD-Histogram\",\"family\":\"moving-average-momentum\",\"polarity\":1,\"scale\":5,\"pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"value\":-2.2,\"prominence\":0.7},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"value\":-1,\"prominence\":0.81}]},{\"name\":\"Stochastic-K\",\"family\":\"range-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":17,\"confirmation_index\":20,\"value\":18,\"prominence\":0.68},{\"kind\":\"low\",\"event_index\":43,\"confirmation_index\":46,\"value\":29,\"prominence\":0.78}]}],\"parameters\":{\"max_lag\":3,\"min_separation\":5,\"max_separation\":40,\"min_price_fraction\":0.005,\"min_indicator_delta\":0.05,\"confirmation_horizon\":12,\"invalidation_buffer\":0.005,\"minimum_indicators\":2},\"weights\":{\"RSI\":0.4,\"MACD-Histogram\":0.35,\"Stochastic-K\":0.25},\"as_of_index\":71,\"universe\":[{\"symbol\":\"SYNTH-A\",\"state\":\"confirmed\",\"divergence_type\":\"regular-bullish\",\"confluence_score\":86,\"freshness\":92,\"liquidity\":80,\"data_quality\":98,\"available_index\":47,\"eligible\":true},{\"symbol\":\"SYNTH-B\",\"state\":\"candidate\",\"divergence_type\":\"regular-bearish\",\"confluence_score\":91,\"freshness\":98,\"liquidity\":72,\"data_quality\":94,\"available_index\":54,\"eligible\":true},{\"symbol\":\"SYNTH-C\",\"state\":\"confirmed\",\"divergence_type\":\"hidden-bullish\",\"confluence_score\":74,\"freshness\":70,\"liquidity\":96,\"data_quality\":90,\"available_index\":39,\"eligible\":true}]})",
        "args": [
          {
            "value": {
              "topic_id": "D08-F05-A07",
              "data_class": "synthetic-teaching",
              "as_of": "2026-01-08T13:30:00Z",
              "bars": [
                {
                  "timestamp": "2026-01-05T14:30:00Z",
                  "open": 105.75,
                  "high": 107,
                  "low": 105,
                  "close": 106,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T15:30:00Z",
                  "open": 106.112,
                  "high": 107.362,
                  "low": 105.362,
                  "close": 106.362,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T16:30:00Z",
                  "open": 106.4614,
                  "high": 107.7114,
                  "low": 105.7114,
                  "close": 106.7114,
                  "finalized": true
                }
              ],
              "price_pivots": [
                {
                  "kind": "low",
                  "event_index": 18,
                  "confirmation_index": 21,
                  "price": 98,
                  "prominence": 0.72
                },
                {
                  "kind": "low",
                  "event_index": 42,
                  "confirmation_index": 45,
                  "price": 94,
                  "prominence": 0.84
                }
              ],
              "indicators": [
                {
                  "name": "RSI",
                  "family": "bounded-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 19,
                      "confirmation_index": 22,
                      "value": 28,
                      "prominence": 0.76
                    },
                    {
                      "kind": "low",
                      "event_index": 41,
                      "confirmation_index": 44,
                      "value": 36,
                      "prominence": 0.86
                    }
                  ]
                },
                {
                  "name": "MACD-Histogram",
                  "family": "moving-average-momentum",
                  "polarity": 1,
                  "scale": 5,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 18,
                      "confirmation_index": 21,
                      "value": -2.2,
                      "prominence": 0.7
                    },
                    {
                      "kind": "low",
                      "event_index": 42,
                      "confirmation_index": 45,
                      "value": -1,
                      "prominence": 0.81
                    }
                  ]
                },
                {
                  "name": "Stochastic-K",
                  "family": "range-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 17,
                      "confirmation_index": 20,
                      "value": 18,
                      "prominence": 0.68
                    },
                    {
                      "kind": "low",
                      "event_index": 43,
                      "confirmation_index": 46,
                      "value": 29,
                      "prominence": 0.78
                    }
                  ]
                }
              ],
              "parameters": {
                "max_lag": 3,
                "min_separation": 5,
                "max_separation": 40,
                "min_price_fraction": 0.005,
                "min_indicator_delta": 0.05,
                "confirmation_horizon": 12,
                "invalidation_buffer": 0.005,
                "minimum_indicators": 2
              },
              "weights": {
                "RSI": 0.4,
                "MACD-Histogram": 0.35,
                "Stochastic-K": 0.25
              },
              "as_of_index": 71,
              "universe": [
                {
                  "symbol": "SYNTH-A",
                  "state": "confirmed",
                  "divergence_type": "regular-bullish",
                  "confluence_score": 86,
                  "freshness": 92,
                  "liquidity": 80,
                  "data_quality": 98,
                  "available_index": 47,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-B",
                  "state": "candidate",
                  "divergence_type": "regular-bearish",
                  "confluence_score": 91,
                  "freshness": 98,
                  "liquidity": 72,
                  "data_quality": 94,
                  "available_index": 54,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-C",
                  "state": "confirmed",
                  "divergence_type": "hidden-bullish",
                  "confluence_score": 74,
                  "freshness": 70,
                  "liquidity": 96,
                  "data_quality": 90,
                  "available_index": 39,
                  "eligible": true
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F05-A07",
          "state": "confluent",
          "groups": [
            {
              "type": "regular-bullish",
              "direction": "bullish",
              "price_pair": [
                18,
                42
              ],
              "indicators": [
                "MACD-Histogram",
                "RSI",
                "Stochastic-K"
              ],
              "indicator_count": 3,
              "weighted_quality": 85.830084,
              "weight_coverage": 1,
              "family_coverage": 1,
              "confluence_score": 93.623538,
              "knowledge_index": 46,
              "interpretation": "agreement score; not independent evidence or probability"
            }
          ],
          "group_count": 1
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: topic_id, state, groups, group_count"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a07/static/map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "TradingView — RSI divergence indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000589127-rsi-divergence-indicator/"
        },
        {
          "key": "S2",
          "title": "TradingView — MACD indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502344-moving-average-convergence-divergence-macd-indicator/"
        },
        {
          "key": "S3",
          "title": "TradingView Pine Script — Repainting",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/concepts/repainting/"
        },
        {
          "key": "S4",
          "title": "TradingView Pine Script — Visuals FAQ",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/faq/visuals/"
        },
        {
          "key": "S5",
          "title": "Fidelity — Relative Strength Index",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/RSI"
        },
        {
          "key": "S6",
          "title": "Fidelity — MACD",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/macd"
        },
        {
          "key": "S7",
          "title": "TA-Lib — Function index",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S8",
          "title": "TA-Lib — RSI",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/rsi.html"
        },
        {
          "key": "S9",
          "title": "SciPy — find_peaks",
          "author": "SciPy",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S10",
          "title": "Bailey et al. — Effects of Backtest Overfitting",
          "author": "Bailey et al.",
          "url": "https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2308659"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        },
        {
          "key": "Topic-specific applicability map",
          "title": "Topic-specific applicability map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/indicator-divergence-detection/multi-indicator-divergence-confluence/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/indicator-divergence-detection/multi-indicator-divergence-confluence/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F05-A08",
      "name": "Market-Wide Divergence Scanner and Ranking",
      "headline": null,
      "slug": "market-wide-divergence-scanner-and-ranking",
      "path": "geometric-chart-patterns/indicator-divergence-detection/market-wide-divergence-scanner-and-ranking",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F05",
        "family": "Indicator Divergence Detection",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/indicator-divergence-detection/market-wide-divergence-scanner-and-ranking",
        "entry": "marketWideDivergenceScannerAndRanking",
        "params": [
          "payload"
        ],
        "exports": [
          "adaptIndicator",
          "alignPivots",
          "detectDivergences",
          "scoreDivergence",
          "advanceState",
          "combineConfluence",
          "rankUniverse",
          "runTopic",
          "priceIndicatorPivotAlignment",
          "regularBullishBearishDivergenceDetection",
          "hiddenBullishBearishDivergenceDetection",
          "multiIndicatorDivergenceAdapters",
          "divergenceStrengthAndQualityScoring",
          "divergenceConfirmationAndInvalidationStateMachine",
          "multiIndicatorDivergenceConfluence",
          "marketWideDivergenceScannerAndRanking"
        ],
        "archetype": "record-transform",
        "signature": "marketWideDivergenceScannerAndRanking(payload)"
      },
      "api": {
        "summary": "Filters point-in-time eligible universe records and ranks them from explicit confluence, state, freshness, liquidity, and data-quality components.",
        "params": [
          {
            "name": "payload",
            "type": "{ topic_id: string; data_class: string; as_of: string; bars: { timestamp: string; open: number; high: number; low: number; close: number; finalized: boolean }[]; price_pivots: { kind: string; event_index: number; confirmation_index: number; price: number; prominence: number }[]; indicators: { name: string; family: string; polarity: number; scale: number; pivots: { kind: string; event_index: number; confirmation_index: number; value: number; prominence: number }[] }[]; parameters: { max_lag: number; min_separation: number; max_separation: number; min_price_fraction: number; min_indicator_delta: number; confirmation_horizon: number; invalidation_buffer: number; minimum_indicators: number }; weights: { RSI: number; MACD-Histogram: number; Stochastic-K: number }; as_of_index: number; universe: { symbol: string; state: string; divergence_type: string; confluence_score: number; freshness: number; liquidity: number; data_quality: number; available_index: number; eligible: boolean }[] }",
            "required": true,
            "description": "Topic payload containing `universe` records and an `as_of_index` or bars from which that index can be derived.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ topic_id, state, ranking, eligible_count }",
          "description": "One scanner record with `state` equal to `ranked` or `empty`; each eligible row has a stable rank and component trace."
        },
        "warmup": null,
        "errors": [
          {
            "when": "as-of index, universe score, availability, or scanner-state input is invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n log n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "marketWideDivergenceScannerAndRanking({\"topic_id\":\"D08-F05-A08\",\"data_class\":\"synthetic-teaching\",\"as_of\":\"2026-01-08T13:30:00Z\",\"bars\":[{\"timestamp\":\"2026-01-05T14:30:00Z\",\"open\":105.75,\"high\":107,\"low\":105,\"close\":106,\"finalized\":true},{\"timestamp\":\"2026-01-05T15:30:00Z\",\"open\":106.112,\"high\":107.362,\"low\":105.362,\"close\":106.362,\"finalized\":true},{\"timestamp\":\"2026-01-05T16:30:00Z\",\"open\":106.4614,\"high\":107.7114,\"low\":105.7114,\"close\":106.7114,\"finalized\":true}],\"price_pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"price\":98,\"prominence\":0.72},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"price\":94,\"prominence\":0.84}],\"indicators\":[{\"name\":\"RSI\",\"family\":\"bounded-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":19,\"confirmation_index\":22,\"value\":28,\"prominence\":0.76},{\"kind\":\"low\",\"event_index\":41,\"confirmation_index\":44,\"value\":36,\"prominence\":0.86}]},{\"name\":\"MACD-Histogram\",\"family\":\"moving-average-momentum\",\"polarity\":1,\"scale\":5,\"pivots\":[{\"kind\":\"low\",\"event_index\":18,\"confirmation_index\":21,\"value\":-2.2,\"prominence\":0.7},{\"kind\":\"low\",\"event_index\":42,\"confirmation_index\":45,\"value\":-1,\"prominence\":0.81}]},{\"name\":\"Stochastic-K\",\"family\":\"range-momentum\",\"polarity\":1,\"scale\":100,\"pivots\":[{\"kind\":\"low\",\"event_index\":17,\"confirmation_index\":20,\"value\":18,\"prominence\":0.68},{\"kind\":\"low\",\"event_index\":43,\"confirmation_index\":46,\"value\":29,\"prominence\":0.78}]}],\"parameters\":{\"max_lag\":3,\"min_separation\":5,\"max_separation\":40,\"min_price_fraction\":0.005,\"min_indicator_delta\":0.05,\"confirmation_horizon\":12,\"invalidation_buffer\":0.005,\"minimum_indicators\":2},\"weights\":{\"RSI\":0.4,\"MACD-Histogram\":0.35,\"Stochastic-K\":0.25},\"as_of_index\":71,\"universe\":[{\"symbol\":\"SYNTH-A\",\"state\":\"confirmed\",\"divergence_type\":\"regular-bullish\",\"confluence_score\":86,\"freshness\":92,\"liquidity\":80,\"data_quality\":98,\"available_index\":47,\"eligible\":true},{\"symbol\":\"SYNTH-B\",\"state\":\"candidate\",\"divergence_type\":\"regular-bearish\",\"confluence_score\":91,\"freshness\":98,\"liquidity\":72,\"data_quality\":94,\"available_index\":54,\"eligible\":true},{\"symbol\":\"SYNTH-C\",\"state\":\"confirmed\",\"divergence_type\":\"hidden-bullish\",\"confluence_score\":74,\"freshness\":70,\"liquidity\":96,\"data_quality\":90,\"available_index\":39,\"eligible\":true}]})",
        "args": [
          {
            "value": {
              "topic_id": "D08-F05-A08",
              "data_class": "synthetic-teaching",
              "as_of": "2026-01-08T13:30:00Z",
              "bars": [
                {
                  "timestamp": "2026-01-05T14:30:00Z",
                  "open": 105.75,
                  "high": 107,
                  "low": 105,
                  "close": 106,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T15:30:00Z",
                  "open": 106.112,
                  "high": 107.362,
                  "low": 105.362,
                  "close": 106.362,
                  "finalized": true
                },
                {
                  "timestamp": "2026-01-05T16:30:00Z",
                  "open": 106.4614,
                  "high": 107.7114,
                  "low": 105.7114,
                  "close": 106.7114,
                  "finalized": true
                }
              ],
              "price_pivots": [
                {
                  "kind": "low",
                  "event_index": 18,
                  "confirmation_index": 21,
                  "price": 98,
                  "prominence": 0.72
                },
                {
                  "kind": "low",
                  "event_index": 42,
                  "confirmation_index": 45,
                  "price": 94,
                  "prominence": 0.84
                }
              ],
              "indicators": [
                {
                  "name": "RSI",
                  "family": "bounded-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 19,
                      "confirmation_index": 22,
                      "value": 28,
                      "prominence": 0.76
                    },
                    {
                      "kind": "low",
                      "event_index": 41,
                      "confirmation_index": 44,
                      "value": 36,
                      "prominence": 0.86
                    }
                  ]
                },
                {
                  "name": "MACD-Histogram",
                  "family": "moving-average-momentum",
                  "polarity": 1,
                  "scale": 5,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 18,
                      "confirmation_index": 21,
                      "value": -2.2,
                      "prominence": 0.7
                    },
                    {
                      "kind": "low",
                      "event_index": 42,
                      "confirmation_index": 45,
                      "value": -1,
                      "prominence": 0.81
                    }
                  ]
                },
                {
                  "name": "Stochastic-K",
                  "family": "range-momentum",
                  "polarity": 1,
                  "scale": 100,
                  "pivots": [
                    {
                      "kind": "low",
                      "event_index": 17,
                      "confirmation_index": 20,
                      "value": 18,
                      "prominence": 0.68
                    },
                    {
                      "kind": "low",
                      "event_index": 43,
                      "confirmation_index": 46,
                      "value": 29,
                      "prominence": 0.78
                    }
                  ]
                }
              ],
              "parameters": {
                "max_lag": 3,
                "min_separation": 5,
                "max_separation": 40,
                "min_price_fraction": 0.005,
                "min_indicator_delta": 0.05,
                "confirmation_horizon": 12,
                "invalidation_buffer": 0.005,
                "minimum_indicators": 2
              },
              "weights": {
                "RSI": 0.4,
                "MACD-Histogram": 0.35,
                "Stochastic-K": 0.25
              },
              "as_of_index": 71,
              "universe": [
                {
                  "symbol": "SYNTH-A",
                  "state": "confirmed",
                  "divergence_type": "regular-bullish",
                  "confluence_score": 86,
                  "freshness": 92,
                  "liquidity": 80,
                  "data_quality": 98,
                  "available_index": 47,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-B",
                  "state": "candidate",
                  "divergence_type": "regular-bearish",
                  "confluence_score": 91,
                  "freshness": 98,
                  "liquidity": 72,
                  "data_quality": 94,
                  "available_index": 54,
                  "eligible": true
                },
                {
                  "symbol": "SYNTH-C",
                  "state": "confirmed",
                  "divergence_type": "hidden-bullish",
                  "confluence_score": 74,
                  "freshness": 70,
                  "liquidity": 96,
                  "data_quality": 90,
                  "available_index": 39,
                  "eligible": true
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "topic_id": "D08-F05-A08",
          "state": "ranked",
          "ranking": [
            {
              "symbol": "SYNTH-A",
              "state": "confirmed",
              "divergence_type": "regular-bullish",
              "rank_score": 89.3,
              "components": {
                "confluence_score": 86,
                "freshness": 92,
                "liquidity": 80,
                "data_quality": 98
              },
              "as_of_index": 71,
              "interpretation": "deterministic triage priority; not an order or return forecast",
              "rank": 1
            },
            {
              "symbol": "SYNTH-B",
              "state": "candidate",
              "divergence_type": "regular-bearish",
              "rank_score": 86.95,
              "components": {
                "confluence_score": 91,
                "freshness": 98,
                "liquidity": 72,
                "data_quality": 94
              },
              "as_of_index": 71,
              "interpretation": "deterministic triage priority; not an order or return forecast",
              "rank": 2
            },
            {
              "symbol": "SYNTH-C",
              "state": "confirmed",
              "divergence_type": "hidden-bullish",
              "rank_score": 81.3,
              "components": {
                "confluence_score": 74,
                "freshness": 70,
                "liquidity": 96,
                "data_quality": 90
              },
              "as_of_index": 71,
              "interpretation": "deterministic triage priority; not an order or return forecast",
              "rank": 3
            }
          ],
          "eligible_count": 4
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: topic_id, state, ranking, eligible_count"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f05-a08/static/map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "TradingView — RSI divergence indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000589127-rsi-divergence-indicator/"
        },
        {
          "key": "S2",
          "title": "TradingView — MACD indicator",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502344-moving-average-convergence-divergence-macd-indicator/"
        },
        {
          "key": "S3",
          "title": "TradingView Pine Script — Repainting",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/concepts/repainting/"
        },
        {
          "key": "S4",
          "title": "TradingView Pine Script — Visuals FAQ",
          "author": "TradingView Pine Script",
          "url": "https://www.tradingview.com/pine-script-docs/faq/visuals/"
        },
        {
          "key": "S5",
          "title": "Fidelity — Relative Strength Index",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/RSI"
        },
        {
          "key": "S6",
          "title": "Fidelity — MACD",
          "author": "Fidelity",
          "url": "https://www.fidelity.com/learning-center/trading-investing/technical-analysis/technical-indicator-guide/macd"
        },
        {
          "key": "S7",
          "title": "TA-Lib — Function index",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/"
        },
        {
          "key": "S8",
          "title": "TA-Lib — RSI",
          "author": "TA-Lib",
          "url": "https://ta-lib.org/functions/rsi.html"
        },
        {
          "key": "S9",
          "title": "SciPy — find_peaks",
          "author": "SciPy",
          "url": "https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html"
        },
        {
          "key": "S10",
          "title": "Bailey et al. — Effects of Backtest Overfitting",
          "author": "Bailey et al.",
          "url": "https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2308659"
        },
        {
          "key": "Historical-example decision",
          "title": "Historical-example decision",
          "author": null,
          "url": null
        },
        {
          "key": "Topic-specific applicability map",
          "title": "Topic-specific applicability map",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/indicator-divergence-detection/market-wide-divergence-scanner-and-ranking/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/indicator-divergence-detection/market-wide-divergence-scanner-and-ranking/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F06-A01",
      "name": "Price-by-Volume Profile Construction",
      "headline": null,
      "slug": "price-by-volume-profile-construction",
      "path": "geometric-chart-patterns/level-confluence-and-zone-scoring/price-by-volume-profile-construction",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F06",
        "family": "Level Confluence and Zone Scoring",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/level-confluence-and-zone-scoring/price-by-volume-profile-construction",
        "entry": "priceByVolumeProfileConstruction",
        "params": [
          "input"
        ],
        "exports": [
          "calculate",
          "priceByVolumeProfileConstruction",
          "pocValueAreaHvnLvnDetection",
          "fibonacciRetracementExtensionProjection",
          "psychologicalRoundNumberLevelGeneration",
          "multiSourceSupportResistanceZoneFusion",
          "supportResistanceZoneStrengthDecayScoring",
          "supportResistanceRoleReversalStateMachine",
          "breakoutAndRetestDetection",
          "marketWideZoneProximityScannerRanking"
        ],
        "archetype": "record-transform",
        "signature": "priceByVolumeProfileConstruction(input)"
      },
      "api": {
        "summary": "Aggregates eligible point-in-time trades into deterministic tick-aligned price-by-volume bins.",
        "params": [
          {
            "name": "input",
            "type": "{ tick_size: number; bin_size_ticks: number; window_end: string; trades: { trade_id: string; timestamp: string; price: number; volume: number; final: boolean }[] }",
            "required": true,
            "description": "Record containing `tick_size`, `bin_size_ticks`, `window_end`, and chronologically ordered unique trades.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, tick_size, bin_size_ticks, bin_width, total_volume, trade_count, eligible_trade_count, rows }",
          "description": "One `calculated` profile record; each row contains bin index, bounds, midpoint, volume, and volume share."
        },
        "warmup": null,
        "errors": [
          {
            "when": "tick/bin settings, window time, trade identity, chronology, price, or volume is invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(t log t)\", space: \"O(b)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "priceByVolumeProfileConstruction({\"tick_size\":0.25,\"bin_size_ticks\":2,\"window_end\":\"2026-08-03T10:30:00Z\",\"trades\":[{\"trade_id\":\"T01\",\"timestamp\":\"2026-08-03T10:00:00Z\",\"price\":99,\"volume\":10,\"final\":true},{\"trade_id\":\"T02\",\"timestamp\":\"2026-08-03T10:02:00Z\",\"price\":99.25,\"volume\":15,\"final\":true},{\"trade_id\":\"T03\",\"timestamp\":\"2026-08-03T10:04:00Z\",\"price\":99.5,\"volume\":25,\"final\":true}]})",
        "args": [
          {
            "value": {
              "tick_size": 0.25,
              "bin_size_ticks": 2,
              "window_end": "2026-08-03T10:30:00Z",
              "trades": [
                {
                  "trade_id": "T01",
                  "timestamp": "2026-08-03T10:00:00Z",
                  "price": 99,
                  "volume": 10,
                  "final": true
                },
                {
                  "trade_id": "T02",
                  "timestamp": "2026-08-03T10:02:00Z",
                  "price": 99.25,
                  "volume": 15,
                  "final": true
                },
                {
                  "trade_id": "T03",
                  "timestamp": "2026-08-03T10:04:00Z",
                  "price": 99.5,
                  "volume": 25,
                  "final": true
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "calculated",
          "tick_size": 0.25,
          "bin_size_ticks": 2,
          "bin_width": 0.5,
          "total_volume": 340,
          "trade_count": 12,
          "eligible_trade_count": 12,
          "rows": [
            {
              "bin_index": 198,
              "lower": 99,
              "upper": 99.5,
              "midpoint": 99.25,
              "volume": 25,
              "share": 0.073529411765
            },
            {
              "bin_index": 199,
              "lower": 99.5,
              "upper": 100,
              "midpoint": 99.75,
              "volume": 45,
              "share": 0.132352941176
            },
            {
              "bin_index": 200,
              "lower": 100,
              "upper": 100.5,
              "midpoint": 100.25,
              "volume": 152,
              "share": 0.447058823529
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: state, tick_size, bin_size_ticks, bin_width, total_volume, trade_count, eligible_trade_count, rows"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Volume profile indicators: basic concepts",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502040-volume-profile-indicators-basic-concepts/"
        },
        {
          "key": "S2",
          "title": "Session volume profile charts explained",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000745275-session-volume-profile-charts-explained/"
        },
        {
          "key": "S3",
          "title": "Foundations of Technical Analysis: Computational Algorithms, Statistical Inference, and Empirical Implementation",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/level-confluence-and-zone-scoring/price-by-volume-profile-construction/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/level-confluence-and-zone-scoring/price-by-volume-profile-construction/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F06-A02",
      "name": "Point of Control, Value Area, HVN, and LVN Detection",
      "headline": null,
      "slug": "poc-value-area-hvn-lvn-detection",
      "path": "geometric-chart-patterns/level-confluence-and-zone-scoring/poc-value-area-hvn-lvn-detection",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F06",
        "family": "Level Confluence and Zone Scoring",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/level-confluence-and-zone-scoring/poc-value-area-hvn-lvn-detection",
        "entry": "pocValueAreaHvnLvnDetection",
        "params": [
          "input"
        ],
        "exports": [
          "calculate",
          "priceByVolumeProfileConstruction",
          "pocValueAreaHvnLvnDetection",
          "fibonacciRetracementExtensionProjection",
          "psychologicalRoundNumberLevelGeneration",
          "multiSourceSupportResistanceZoneFusion",
          "supportResistanceZoneStrengthDecayScoring",
          "supportResistanceRoleReversalStateMachine",
          "breakoutAndRetestDetection",
          "marketWideZoneProximityScannerRanking"
        ],
        "archetype": "record-transform",
        "signature": "pocValueAreaHvnLvnDetection(input)"
      },
      "api": {
        "summary": "Selects the point of control, expands a deterministic value area, and identifies local high- and low-volume nodes.",
        "params": [
          {
            "name": "input",
            "type": "{ profile_rows: { lower: number; upper: number; volume: number }[]; value_area_fraction: number; hvn_median_ratio: number; lvn_median_ratio: number }",
            "required": true,
            "description": "Record containing at least three ordered contiguous `profile_rows` and declared value-area, HVN, and LVN thresholds.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, poc_index, poc_price, poc_volume, value_area_low, value_area_high, value_area_volume, value_area_share, target_share, included_indices, expansion_trace, hvn, lvn }",
          "description": "One `calculated` feature record with auditable expansion order and node diagnostics; insufficient rows are rejected rather than emitted as positional warmup."
        },
        "warmup": {
          "count": "0",
          "value": "not emitted",
          "note": "This record transform has no warm-up output: fewer than three profile rows are rejected explicitly instead of producing positional or state warm-up values."
        },
        "errors": [
          {
            "when": "profile rows are too few, unordered, non-contiguous, or thresholds are outside their canonical ranges",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(b log b)\", space: \"O(b)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "pocValueAreaHvnLvnDetection({\"profile_rows\":[{\"lower\":99,\"upper\":99.5,\"volume\":10},{\"lower\":99.5,\"upper\":100,\"volume\":18},{\"lower\":100,\"upper\":100.5,\"volume\":35}],\"value_area_fraction\":0.7,\"hvn_median_ratio\":1.2,\"lvn_median_ratio\":0.65})",
        "args": [
          {
            "value": {
              "profile_rows": [
                {
                  "lower": 99,
                  "upper": 99.5,
                  "volume": 10
                },
                {
                  "lower": 99.5,
                  "upper": 100,
                  "volume": 18
                },
                {
                  "lower": 100,
                  "upper": 100.5,
                  "volume": 35
                }
              ],
              "value_area_fraction": 0.7,
              "hvn_median_ratio": 1.2,
              "lvn_median_ratio": 0.65
            },
            "elided": null
          }
        ],
        "output": {
          "state": "calculated",
          "poc_index": 4,
          "poc_price": 101.25,
          "poc_volume": 120,
          "value_area_low": 100,
          "value_area_high": 102.5,
          "value_area_volume": 350,
          "value_area_share": 0.755939524838,
          "target_share": 0.7,
          "included_indices": [
            2,
            3,
            4,
            5,
            6
          ],
          "expansion_trace": [
            4,
            5,
            3,
            6,
            2
          ],
          "hvn": [
            {
              "price": 101.25,
              "volume": 120,
              "median_ratio": 3
            },
            {
              "price": 103.25,
              "volume": 50,
              "median_ratio": 1.25
            }
          ],
          "lvn": [
            {
              "price": 102.75,
              "volume": 20,
              "median_ratio": 0.5
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: state, poc_index, poc_price, poc_volume, value_area_low, value_area_high, value_area_volume, value_area_share, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Volume profile indicators: basic concepts",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502040-volume-profile-indicators-basic-concepts/"
        },
        {
          "key": "S2",
          "title": "Session volume profile charts explained",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000745275-session-volume-profile-charts-explained/"
        },
        {
          "key": "S3",
          "title": "Foundations of Technical Analysis: Computational Algorithms, Statistical Inference, and Empirical Implementation",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/level-confluence-and-zone-scoring/poc-value-area-hvn-lvn-detection/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/level-confluence-and-zone-scoring/poc-value-area-hvn-lvn-detection/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F06-A03",
      "name": "Fibonacci Retracement and Extension Projection",
      "headline": null,
      "slug": "fibonacci-retracement-extension-projection",
      "path": "geometric-chart-patterns/level-confluence-and-zone-scoring/fibonacci-retracement-extension-projection",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F06",
        "family": "Level Confluence and Zone Scoring",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/level-confluence-and-zone-scoring/fibonacci-retracement-extension-projection",
        "entry": "fibonacciRetracementExtensionProjection",
        "params": [
          "input"
        ],
        "exports": [
          "calculate",
          "priceByVolumeProfileConstruction",
          "pocValueAreaHvnLvnDetection",
          "fibonacciRetracementExtensionProjection",
          "psychologicalRoundNumberLevelGeneration",
          "multiSourceSupportResistanceZoneFusion",
          "supportResistanceZoneStrengthDecayScoring",
          "supportResistanceRoleReversalStateMachine",
          "breakoutAndRetestDetection",
          "marketWideZoneProximityScannerRanking"
        ],
        "archetype": "record-transform",
        "signature": "fibonacciRetracementExtensionProjection(input)"
      },
      "api": {
        "summary": "Projects declared retracement and extension ratios from a directed price leg and snaps every level to the nearest tick.",
        "params": [
          {
            "name": "input",
            "type": "{ start_price: number; end_price: number; retracement_end_price: number; tick_size: number; retracement_ratios: number[]; extension_ratios: number[] }",
            "required": true,
            "description": "Record containing leg anchors, retracement-end anchor, tick size, and non-empty retracement and extension ratio lists.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, direction, leg_size, retracement_levels, extension_levels, rounding }",
          "description": "One `calculated` projection record; each level reports its ratio, raw price, and tick-snapped price."
        },
        "warmup": null,
        "errors": [
          {
            "when": "anchors coincide, tick size is invalid, ratios are empty, or ratios fall outside allowed ranges",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(r + e)\", space: \"O(r + e)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "fibonacciRetracementExtensionProjection({\"start_price\":100,\"end_price\":120,\"retracement_end_price\":112,\"tick_size\":0.1,\"retracement_ratios\":[0.236,0.382,0.5,0.618,0.786],\"extension_ratios\":[1,1.272,1.618,2]})",
        "args": [
          {
            "value": {
              "start_price": 100,
              "end_price": 120,
              "retracement_end_price": 112,
              "tick_size": 0.1,
              "retracement_ratios": [
                0.236,
                0.382,
                0.5,
                0.618,
                0.786
              ],
              "extension_ratios": [
                1,
                1.272,
                1.618,
                2
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "calculated",
          "direction": "up",
          "leg_size": 20,
          "retracement_levels": [
            {
              "ratio": 0.236,
              "raw_price": 115.28,
              "price": 115.3
            },
            {
              "ratio": 0.382,
              "raw_price": 112.36,
              "price": 112.4
            },
            {
              "ratio": 0.5,
              "raw_price": 110,
              "price": 110
            }
          ],
          "extension_levels": [
            {
              "ratio": 1,
              "raw_price": 132,
              "price": 132
            },
            {
              "ratio": 1.272,
              "raw_price": 137.44,
              "price": 137.4
            },
            {
              "ratio": 1.618,
              "raw_price": 144.36,
              "price": 144.4
            }
          ],
          "rounding": "nearest tick, half away from zero"
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: state, direction, leg_size, retracement_levels, extension_levels, rounding"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Auto Fib Retracement",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000585089-auto-fib-retracement/"
        },
        {
          "key": "S2",
          "title": "Trend-based Fib Extension drawing tool",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000518137-trend-based-fib-extension-drawing-tool/"
        },
        {
          "key": "S3",
          "title": "Foundations of Technical Analysis: Computational Algorithms, Statistical Inference, and Empirical Implementation",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/level-confluence-and-zone-scoring/fibonacci-retracement-extension-projection/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/level-confluence-and-zone-scoring/fibonacci-retracement-extension-projection/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F06-A04",
      "name": "Psychological Round-Number Level Generation",
      "headline": null,
      "slug": "psychological-round-number-level-generation",
      "path": "geometric-chart-patterns/level-confluence-and-zone-scoring/psychological-round-number-level-generation",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F06",
        "family": "Level Confluence and Zone Scoring",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/level-confluence-and-zone-scoring/psychological-round-number-level-generation",
        "entry": "psychologicalRoundNumberLevelGeneration",
        "params": [
          "input"
        ],
        "exports": [
          "calculate",
          "priceByVolumeProfileConstruction",
          "pocValueAreaHvnLvnDetection",
          "fibonacciRetracementExtensionProjection",
          "psychologicalRoundNumberLevelGeneration",
          "multiSourceSupportResistanceZoneFusion",
          "supportResistanceZoneStrengthDecayScoring",
          "supportResistanceRoleReversalStateMachine",
          "breakoutAndRetestDetection",
          "marketWideZoneProximityScannerRanking"
        ],
        "archetype": "record-transform",
        "signature": "psychologicalRoundNumberLevelGeneration(input)"
      },
      "api": {
        "summary": "Generates tick-aligned round-number levels inside explicit bounds and labels their salience and distance from current price.",
        "params": [
          {
            "name": "input",
            "type": "{ current_price: number; lower_bound: number; upper_bound: number; tick_size: number; base_unit: number }",
            "required": true,
            "description": "Record containing current price, lower/upper bounds, tick size, and an aligned base unit.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, base_unit, level_count, closest_level, levels }",
          "description": "One `calculated` level record; every level reports class, salience weight, absolute distance, and basis-point distance."
        },
        "warmup": null,
        "errors": [
          {
            "when": "bounds are inconsistent, tick/base-unit values are invalid or misaligned, or the bounds contain no levels",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(levels)\", space: \"O(levels)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "psychologicalRoundNumberLevelGeneration({\"current_price\":103.4,\"lower_bound\":95,\"upper_bound\":110,\"tick_size\":0.1,\"base_unit\":1})",
        "args": [
          {
            "value": {
              "current_price": 103.4,
              "lower_bound": 95,
              "upper_bound": 110,
              "tick_size": 0.1,
              "base_unit": 1
            },
            "elided": null
          }
        ],
        "output": {
          "state": "calculated",
          "base_unit": 1,
          "level_count": 16,
          "closest_level": {
            "price": 103,
            "class": "minor",
            "salience_weight": 0.5,
            "distance": 0.4,
            "distance_bps": 38.684719535784
          },
          "levels": [
            {
              "price": 95,
              "class": "half",
              "salience_weight": 0.75,
              "distance": 8.4,
              "distance_bps": 812.379110251451
            },
            {
              "price": 96,
              "class": "minor",
              "salience_weight": 0.5,
              "distance": 7.4,
              "distance_bps": 715.667311411993
            },
            {
              "price": 97,
              "class": "minor",
              "salience_weight": 0.5,
              "distance": 6.4,
              "distance_bps": 618.955512572534
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: state, base_unit, level_count, closest_level, levels"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Currency Orders and Exchange-Rate Dynamics: Explaining the Success of Technical Analysis",
          "author": "Carol L. Osler",
          "url": "https://www.newyorkfed.org/medialibrary/media/research/staff_reports/sr125.html"
        },
        {
          "key": "S2",
          "title": "Foundations of Technical Analysis: Computational Algorithms, Statistical Inference, and Empirical Implementation",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/level-confluence-and-zone-scoring/psychological-round-number-level-generation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/level-confluence-and-zone-scoring/psychological-round-number-level-generation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F06-A05",
      "name": "Multi-Source Support/Resistance Zone Fusion",
      "headline": null,
      "slug": "multi-source-support-resistance-zone-fusion",
      "path": "geometric-chart-patterns/level-confluence-and-zone-scoring/multi-source-support-resistance-zone-fusion",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F06",
        "family": "Level Confluence and Zone Scoring",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/level-confluence-and-zone-scoring/multi-source-support-resistance-zone-fusion",
        "entry": "multiSourceSupportResistanceZoneFusion",
        "params": [
          "input"
        ],
        "exports": [
          "calculate",
          "priceByVolumeProfileConstruction",
          "pocValueAreaHvnLvnDetection",
          "fibonacciRetracementExtensionProjection",
          "psychologicalRoundNumberLevelGeneration",
          "multiSourceSupportResistanceZoneFusion",
          "supportResistanceZoneStrengthDecayScoring",
          "supportResistanceRoleReversalStateMachine",
          "breakoutAndRetestDetection",
          "marketWideZoneProximityScannerRanking"
        ],
        "archetype": "record-transform",
        "signature": "multiSourceSupportResistanceZoneFusion(input)"
      },
      "api": {
        "summary": "Clusters nearby levels, computes deterministic zone centers, and separates accepted multi-source zones from rejected clusters.",
        "params": [
          {
            "name": "input",
            "type": "{ fusion_tolerance: number; minimum_sources: number; levels: { level_id: string; source: string; price: number; weight: number }[] }",
            "required": true,
            "description": "Record containing non-empty uniquely identified levels, fusion tolerance, and minimum distinct-source count.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, zones, rejected_clusters, fusion_tolerance, minimum_sources }",
          "description": "One `calculated` fusion record with ranked accepted zones and reason-coded rejected clusters."
        },
        "warmup": null,
        "errors": [
          {
            "when": "levels are empty, identities repeat, source/price/weight fields are invalid, or fusion settings are invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n log n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "multiSourceSupportResistanceZoneFusion({\"fusion_tolerance\":0.25,\"minimum_sources\":2,\"levels\":[{\"level_id\":\"PIV-1\",\"source\":\"pivot\",\"price\":99.8,\"weight\":0.9},{\"level_id\":\"FIB-1\",\"source\":\"fibonacci\",\"price\":100.1,\"weight\":0.7},{\"level_id\":\"RND-1\",\"source\":\"round-number\",\"price\":100,\"weight\":0.8}]})",
        "args": [
          {
            "value": {
              "fusion_tolerance": 0.25,
              "minimum_sources": 2,
              "levels": [
                {
                  "level_id": "PIV-1",
                  "source": "pivot",
                  "price": 99.8,
                  "weight": 0.9
                },
                {
                  "level_id": "FIB-1",
                  "source": "fibonacci",
                  "price": 100.1,
                  "weight": 0.7
                },
                {
                  "level_id": "RND-1",
                  "source": "round-number",
                  "price": 100,
                  "weight": 0.8
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "calculated",
          "zones": [
            {
              "zone_id": "Z01",
              "lower": 99.55,
              "upper": 100.45,
              "center": 100.026470588235,
              "source_count": 4,
              "sources": [
                "fibonacci",
                "pivot",
                "round-number",
                "volume-profile"
              ],
              "weight_sum": 3.4,
              "member_ids": [
                "PIV-1",
                "RND-1",
                "FIB-1",
                "VOL-1"
              ]
            }
          ],
          "rejected_clusters": [
            {
              "zone_id": "Z02",
              "lower": 104.75,
              "upper": 105.25,
              "center": 105,
              "source_count": 1,
              "sources": [
                "pivot"
              ],
              "weight_sum": 0.6,
              "member_ids": [
                "PIV-2"
              ],
              "reason": "insufficient-distinct-sources"
            }
          ],
          "fusion_tolerance": 0.25,
          "minimum_sources": 2
        },
        "outputElided": null,
        "outputShape": "object with 5 fields: state, zones, rejected_clusters, fusion_tolerance, minimum_sources"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Volume profile indicators: basic concepts",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502040-volume-profile-indicators-basic-concepts/"
        },
        {
          "key": "S2",
          "title": "Auto Fib Retracement",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000585089-auto-fib-retracement/"
        },
        {
          "key": "S3",
          "title": "Currency Orders and Exchange-Rate Dynamics: Explaining the Success of Technical Analysis",
          "author": "Carol L. Osler",
          "url": "https://www.newyorkfed.org/medialibrary/media/research/staff_reports/sr125.html"
        },
        {
          "key": "S4",
          "title": "Foundations of Technical Analysis: Computational Algorithms, Statistical Inference, and Empirical Implementation",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/level-confluence-and-zone-scoring/multi-source-support-resistance-zone-fusion/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/level-confluence-and-zone-scoring/multi-source-support-resistance-zone-fusion/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F06-A06",
      "name": "Support/Resistance Zone Strength and Decay Scoring",
      "headline": null,
      "slug": "support-resistance-zone-strength-decay-scoring",
      "path": "geometric-chart-patterns/level-confluence-and-zone-scoring/support-resistance-zone-strength-decay-scoring",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F06",
        "family": "Level Confluence and Zone Scoring",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/level-confluence-and-zone-scoring/support-resistance-zone-strength-decay-scoring",
        "entry": "supportResistanceZoneStrengthDecayScoring",
        "params": [
          "input"
        ],
        "exports": [
          "calculate",
          "priceByVolumeProfileConstruction",
          "pocValueAreaHvnLvnDetection",
          "fibonacciRetracementExtensionProjection",
          "psychologicalRoundNumberLevelGeneration",
          "multiSourceSupportResistanceZoneFusion",
          "supportResistanceZoneStrengthDecayScoring",
          "supportResistanceRoleReversalStateMachine",
          "breakoutAndRetestDetection",
          "marketWideZoneProximityScannerRanking"
        ],
        "archetype": "record-transform",
        "signature": "supportResistanceZoneStrengthDecayScoring(input)"
      },
      "api": {
        "summary": "Scores zone strength from source confluence, decayed touches, rejection quality, durability, and break penalties.",
        "params": [
          {
            "name": "input",
            "type": "{ source_confluence: number; zone_age_bars: number; half_life_bars: number; break_count: number; rejection_target_atr: number; touches: { age_bars: number; rejection_atr: number }[] }",
            "required": true,
            "description": "Record containing source confluence, zone age, decay half-life, break count, rejection target, and touch observations.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, score, grade, components, decayed_touch_evidence, touch_count }",
          "description": "One `calculated` score record with a bounded 0-100 score, qualitative grade, and every component contribution."
        },
        "warmup": null,
        "errors": [
          {
            "when": "confluence, age, half-life, break-count, rejection, or touch input is outside its declared range",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(touches)\", space: \"O(touches)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "supportResistanceZoneStrengthDecayScoring({\"source_confluence\":0.8,\"zone_age_bars\":10,\"half_life_bars\":20,\"break_count\":0,\"rejection_target_atr\":1,\"touches\":[{\"age_bars\":2,\"rejection_atr\":0.8},{\"age_bars\":8,\"rejection_atr\":1.4},{\"age_bars\":20,\"rejection_atr\":0.4}]})",
        "args": [
          {
            "value": {
              "source_confluence": 0.8,
              "zone_age_bars": 10,
              "half_life_bars": 20,
              "break_count": 0,
              "rejection_target_atr": 1,
              "touches": [
                {
                  "age_bars": 2,
                  "rejection_atr": 0.8
                },
                {
                  "age_bars": 8,
                  "rejection_atr": 1.4
                },
                {
                  "age_bars": 20,
                  "rejection_atr": 0.4
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "calculated",
          "score": 81.604861183733,
          "grade": "strong",
          "components": {
            "source": 24,
            "touch": 31.086403443236,
            "rejection": 19.447389928631,
            "durability": 7.071067811865,
            "break_penalty": 0
          },
          "decayed_touch_evidence": 2.190891274792,
          "touch_count": 3
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: state, score, grade, components, decayed_touch_evidence, touch_count"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a06/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Foundations of Technical Analysis: Computational Algorithms, Statistical Inference, and Empirical Implementation",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613"
        },
        {
          "key": "S2",
          "title": "Currency Orders and Exchange-Rate Dynamics: Explaining the Success of Technical Analysis",
          "author": "Carol L. Osler",
          "url": "https://www.newyorkfed.org/medialibrary/media/research/staff_reports/sr125.html"
        },
        {
          "key": "S3",
          "title": "Volume profile indicators: basic concepts",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502040-volume-profile-indicators-basic-concepts/"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/level-confluence-and-zone-scoring/support-resistance-zone-strength-decay-scoring/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/level-confluence-and-zone-scoring/support-resistance-zone-strength-decay-scoring/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F06-A07",
      "name": "Support/Resistance Role-Reversal State Machine",
      "headline": null,
      "slug": "support-resistance-role-reversal-state-machine",
      "path": "geometric-chart-patterns/level-confluence-and-zone-scoring/support-resistance-role-reversal-state-machine",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F06",
        "family": "Level Confluence and Zone Scoring",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/level-confluence-and-zone-scoring/support-resistance-role-reversal-state-machine",
        "entry": "supportResistanceRoleReversalStateMachine",
        "params": [
          "input"
        ],
        "exports": [
          "calculate",
          "priceByVolumeProfileConstruction",
          "pocValueAreaHvnLvnDetection",
          "fibonacciRetracementExtensionProjection",
          "psychologicalRoundNumberLevelGeneration",
          "multiSourceSupportResistanceZoneFusion",
          "supportResistanceZoneStrengthDecayScoring",
          "supportResistanceRoleReversalStateMachine",
          "breakoutAndRetestDetection",
          "marketWideZoneProximityScannerRanking"
        ],
        "archetype": "record-transform",
        "signature": "supportResistanceRoleReversalStateMachine(input)"
      },
      "api": {
        "summary": "Processes closes through active-role, break, retest, confirmation, and invalidation transitions for one zone.",
        "params": [
          {
            "name": "input",
            "type": "{ zone_lower: number; zone_upper: number; break_buffer: number; confirmation_closes: number; initial_role: string; closes: number[] }",
            "required": true,
            "description": "Record containing zone bounds, break buffer, required confirmation closes, initial role, and non-empty close observations.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, final_role, confirmed, retest_seen, transitions, observations }",
          "description": "One state-machine record with final role, confirmation flag, retest flag, observation count, and transition trace."
        },
        "warmup": null,
        "errors": [
          {
            "when": "zone bounds, role, confirmation count, buffer, or close observations are invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(transitions)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "supportResistanceRoleReversalStateMachine({\"zone_lower\":99.5,\"zone_upper\":100.5,\"break_buffer\":0.2,\"confirmation_closes\":2,\"initial_role\":\"support\",\"closes\":[101,100.2,99.2,99.1,99.8,99.1]})",
        "args": [
          {
            "value": {
              "zone_lower": 99.5,
              "zone_upper": 100.5,
              "break_buffer": 0.2,
              "confirmation_closes": 2,
              "initial_role": "support",
              "closes": [
                101,
                100.2,
                99.2,
                99.1,
                99.8,
                99.1
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "confirmed-resistance",
          "final_role": "resistance",
          "confirmed": true,
          "retest_seen": true,
          "transitions": [
            {
              "index": 3,
              "close": 99.1,
              "from": "active-support",
              "to": "awaiting-resistance-retest",
              "side": "below"
            },
            {
              "index": 5,
              "close": 99.1,
              "from": "awaiting-resistance-retest",
              "to": "confirmed-resistance",
              "side": "below"
            }
          ],
          "observations": 6
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: state, final_role, confirmed, retest_seen, transitions, observations"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a07/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Foundations of Technical Analysis: Computational Algorithms, Statistical Inference, and Empirical Implementation",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613"
        },
        {
          "key": "S2",
          "title": "Currency Orders and Exchange-Rate Dynamics: Explaining the Success of Technical Analysis",
          "author": "Carol L. Osler",
          "url": "https://www.newyorkfed.org/medialibrary/media/research/staff_reports/sr125.html"
        },
        {
          "key": "S3",
          "title": "Volume profile indicators: basic concepts",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502040-volume-profile-indicators-basic-concepts/"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/level-confluence-and-zone-scoring/support-resistance-role-reversal-state-machine/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/level-confluence-and-zone-scoring/support-resistance-role-reversal-state-machine/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F06-A08",
      "name": "Breakout and Retest Detection",
      "headline": null,
      "slug": "breakout-and-retest-detection",
      "path": "geometric-chart-patterns/level-confluence-and-zone-scoring/breakout-and-retest-detection",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F06",
        "family": "Level Confluence and Zone Scoring",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/level-confluence-and-zone-scoring/breakout-and-retest-detection",
        "entry": "breakoutAndRetestDetection",
        "params": [
          "input"
        ],
        "exports": [
          "calculate",
          "priceByVolumeProfileConstruction",
          "pocValueAreaHvnLvnDetection",
          "fibonacciRetracementExtensionProjection",
          "psychologicalRoundNumberLevelGeneration",
          "multiSourceSupportResistanceZoneFusion",
          "supportResistanceZoneStrengthDecayScoring",
          "supportResistanceRoleReversalStateMachine",
          "breakoutAndRetestDetection",
          "marketWideZoneProximityScannerRanking"
        ],
        "archetype": "record-transform",
        "signature": "breakoutAndRetestDetection(input)"
      },
      "api": {
        "summary": "Processes bars through breakout-pending, retest, confirmation, failure, and expiry states around one zone.",
        "params": [
          {
            "name": "input",
            "type": "{ zone_lower: number; zone_upper: number; break_buffer: number; retest_tolerance: number; breakout_closes: number; max_retest_bars: number; direction: string; bars: { high: number; low: number; close: number }[] }",
            "required": true,
            "description": "Record containing zone bounds, buffers/tolerance, breakout close count, retest horizon, direction, and non-empty bars.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, confirmed, direction, breakout_index, retest_index, confirmation_index, transitions }",
          "description": "One state-machine record with nullable event indexes and a complete transition trace; no positional warmup series is returned."
        },
        "warmup": {
          "count": "0",
          "value": "not emitted",
          "note": "This state machine has no warm-up output: an empty bar set is rejected and valid observations begin in searching state rather than a positional warm-up series."
        },
        "errors": [
          {
            "when": "zone, direction, buffer, count, horizon, or bar geometry input is invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n)\", space: \"O(transitions)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "breakoutAndRetestDetection({\"zone_lower\":99.5,\"zone_upper\":100.5,\"break_buffer\":0.2,\"retest_tolerance\":0.15,\"breakout_closes\":2,\"max_retest_bars\":5,\"direction\":\"up\",\"bars\":[{\"high\":100.5,\"low\":99.8,\"close\":100.2},{\"high\":101,\"low\":100.3,\"close\":100.8},{\"high\":101.3,\"low\":100.7,\"close\":101}]})",
        "args": [
          {
            "value": {
              "zone_lower": 99.5,
              "zone_upper": 100.5,
              "break_buffer": 0.2,
              "retest_tolerance": 0.15,
              "breakout_closes": 2,
              "max_retest_bars": 5,
              "direction": "up",
              "bars": [
                {
                  "high": 100.5,
                  "low": 99.8,
                  "close": 100.2
                },
                {
                  "high": 101,
                  "low": 100.3,
                  "close": 100.8
                },
                {
                  "high": 101.3,
                  "low": 100.7,
                  "close": 101
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "confirmed",
          "confirmed": true,
          "direction": "up",
          "breakout_index": 2,
          "retest_index": 3,
          "confirmation_index": 4,
          "transitions": [
            {
              "index": 1,
              "from": "searching",
              "to": "breakout-pending",
              "close": 100.8
            },
            {
              "index": 2,
              "from": "breakout-pending",
              "to": "awaiting-retest",
              "close": 101
            },
            {
              "index": 3,
              "from": "awaiting-retest",
              "to": "retest-contact",
              "close": 100.7
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: state, confirmed, direction, breakout_index, retest_index, confirmation_index, transitions"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a08/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Foundations of Technical Analysis: Computational Algorithms, Statistical Inference, and Empirical Implementation",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613"
        },
        {
          "key": "S2",
          "title": "Currency Orders and Exchange-Rate Dynamics: Explaining the Success of Technical Analysis",
          "author": "Carol L. Osler",
          "url": "https://www.newyorkfed.org/medialibrary/media/research/staff_reports/sr125.html"
        },
        {
          "key": "S3",
          "title": "Volume profile indicators: basic concepts",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502040-volume-profile-indicators-basic-concepts/"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/level-confluence-and-zone-scoring/breakout-and-retest-detection/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/level-confluence-and-zone-scoring/breakout-and-retest-detection/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D08-F06-A09",
      "name": "Market-Wide Zone-Proximity Scanner and Ranking",
      "headline": null,
      "slug": "market-wide-zone-proximity-scanner-ranking",
      "path": "geometric-chart-patterns/level-confluence-and-zone-scoring/market-wide-zone-proximity-scanner-ranking",
      "taxonomy": {
        "domainId": "D08",
        "domain": "Geometric Chart Patterns",
        "familyId": "D08-F06",
        "family": "Level Confluence and Zone Scoring",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/geometric-chart-patterns/level-confluence-and-zone-scoring/market-wide-zone-proximity-scanner-ranking",
        "entry": "marketWideZoneProximityScannerRanking",
        "params": [
          "input"
        ],
        "exports": [
          "calculate",
          "priceByVolumeProfileConstruction",
          "pocValueAreaHvnLvnDetection",
          "fibonacciRetracementExtensionProjection",
          "psychologicalRoundNumberLevelGeneration",
          "multiSourceSupportResistanceZoneFusion",
          "supportResistanceZoneStrengthDecayScoring",
          "supportResistanceRoleReversalStateMachine",
          "breakoutAndRetestDetection",
          "marketWideZoneProximityScannerRanking"
        ],
        "archetype": "record-transform",
        "signature": "marketWideZoneProximityScannerRanking(input)"
      },
      "api": {
        "summary": "Filters point-in-time zone records by proximity and ranks eligible instruments from proximity, strength, and freshness.",
        "params": [
          {
            "name": "input",
            "type": "{ as_of: string; max_distance_bps: number; freshness_half_life_hours: number; instruments: { instrument_id: string; current_price: number; zone_lower: number; zone_upper: number; zone_strength: number; observed_at: string }[] }",
            "required": true,
            "description": "Record containing zoned `as_of`, maximum distance, freshness half-life, and non-empty unique instrument records.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ state, as_of, eligible_count, ranked }",
          "description": "One `calculated` scanner record; eligible rows include inside-zone flag, distances, strength, freshness, score, and stable rank."
        },
        "warmup": null,
        "errors": [
          {
            "when": "as-of time, thresholds, instrument identity, zone geometry, price, strength, or observation time is invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": "{ time: \"O(n log n)\", space: \"O(n)\" }"
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "marketWideZoneProximityScannerRanking({\"as_of\":\"2026-08-03T12:00:00Z\",\"max_distance_bps\":40,\"freshness_half_life_hours\":12,\"instruments\":[{\"instrument_id\":\"SYN01\",\"current_price\":79.76,\"zone_lower\":79.82,\"zone_upper\":80.18,\"zone_strength\":55,\"observed_at\":\"2026-08-03T12:00:00Z\"},{\"instrument_id\":\"SYN02\",\"current_price\":83.84,\"zone_lower\":83.82,\"zone_upper\":84.18,\"zone_strength\":62,\"observed_at\":\"2026-08-03T11:00:00Z\"},{\"instrument_id\":\"SYN03\",\"current_price\":87.92,\"zone_lower\":87.82,\"zone_upper\":88.18,\"zone_strength\":69,\"observed_at\":\"2026-08-03T10:00:00Z\"}]})",
        "args": [
          {
            "value": {
              "as_of": "2026-08-03T12:00:00Z",
              "max_distance_bps": 40,
              "freshness_half_life_hours": 12,
              "instruments": [
                {
                  "instrument_id": "SYN01",
                  "current_price": 79.76,
                  "zone_lower": 79.82,
                  "zone_upper": 80.18,
                  "zone_strength": 55,
                  "observed_at": "2026-08-03T12:00:00Z"
                },
                {
                  "instrument_id": "SYN02",
                  "current_price": 83.84,
                  "zone_lower": 83.82,
                  "zone_upper": 84.18,
                  "zone_strength": 62,
                  "observed_at": "2026-08-03T11:00:00Z"
                },
                {
                  "instrument_id": "SYN03",
                  "current_price": 87.92,
                  "zone_lower": 87.82,
                  "zone_upper": 88.18,
                  "zone_strength": 69,
                  "observed_at": "2026-08-03T10:00:00Z"
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "state": "calculated",
          "as_of": "2026-08-03T12:00:00Z",
          "eligible_count": 24,
          "ranked": [
            {
              "instrument_id": "SYN24",
              "current_price": 171.92,
              "zone_lower": 171.82,
              "zone_upper": 172.18,
              "inside_zone": true,
              "distance": 0,
              "distance_bps": 0,
              "strength": 93,
              "freshness": 0.749153538438,
              "rank_score": 94.137303076575,
              "rank": 1
            },
            {
              "instrument_id": "SYN18",
              "current_price": 148,
              "zone_lower": 147.82,
              "zone_upper": 148.18,
              "inside_zone": true,
              "distance": 0,
              "distance_bps": 0,
              "strength": 92,
              "freshness": 0.749153538438,
              "rank_score": 93.837303076575,
              "rank": 2
            },
            {
              "instrument_id": "SYN12",
              "current_price": 124.08,
              "zone_lower": 123.82,
              "zone_upper": 124.18,
              "inside_zone": true,
              "distance": 0,
              "distance_bps": 0,
              "strength": 91,
              "freshness": 0.749153538438,
              "rank_score": 93.537303076575,
              "rank": 3
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 4 fields: state, as_of, eligible_count, ranked"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d08-f06-a09/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Foundations of Technical Analysis: Computational Algorithms, Statistical Inference, and Empirical Implementation",
          "author": "Andrew W. Lo, Harry Mamaysky, and Jiang Wang",
          "url": "https://www.nber.org/papers/w7613"
        },
        {
          "key": "S2",
          "title": "Currency Orders and Exchange-Rate Dynamics: Explaining the Success of Technical Analysis",
          "author": "Carol L. Osler",
          "url": "https://www.newyorkfed.org/medialibrary/media/research/staff_reports/sr125.html"
        },
        {
          "key": "S3",
          "title": "Volume profile indicators: basic concepts",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000502040-volume-profile-indicators-basic-concepts/"
        },
        {
          "key": "S4",
          "title": "Session volume profile charts explained",
          "author": "TradingView",
          "url": "https://www.tradingview.com/support/solutions/43000745275-session-volume-profile-charts-explained/"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/geometric-chart-patterns/level-confluence-and-zone-scoring/market-wide-zone-proximity-scanner-ranking/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/geometric-chart-patterns/level-confluence-and-zone-scoring/market-wide-zone-proximity-scanner-ranking/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F01-A01",
      "name": "ACF",
      "headline": null,
      "slug": "acf",
      "path": "statistical-time-series/diagnostics/acf",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F01",
        "family": "Diagnostics",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/diagnostics/acf",
        "entry": "acf",
        "params": [
          "values",
          "maxLag"
        ],
        "exports": [
          "acf",
          "pacf",
          "adf",
          "kpss",
          "ljungBox",
          "zivotAndrews",
          "runDiagnostic"
        ],
        "archetype": "record-transform",
        "signature": "acf(values, maxLag)"
      },
      "api": {
        "summary": "Autocorrelation at each lag. The first diagnostic to run on any series you intend to model: it shows whether there is structure to model at all, and slow decay is the classic signature of non-stationarity.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "maxLag",
            "type": "number",
            "required": true,
            "description": "Highest lag to compute. Beyond roughly n/4 the estimates are too noisy to read.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ method, variant, nobs, max_lag, mean, denominator, numerators, coefficients, confidence_bands }",
          "description": "Coefficients with the numerator and denominator used — estimators differ in whether the denominator varies with lag, and the two conventions give visibly different plots."
        },
        "warmup": null,
        "errors": [
          {
            "when": "maxLag is not less than the sample size",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × maxLag)",
          "space": "O(maxLag)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "acf([0.49366418,1.54242291,-0.82556495,0.47513288,0.50704417,-0.3816439], 12)",
        "args": [
          {
            "value": [
              0.49366418,
              1.54242291,
              -0.82556495,
              0.47513288,
              0.50704417,
              -0.3816439
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 96
            }
          },
          {
            "value": 12,
            "elided": null
          }
        ],
        "output": {
          "method": "acf",
          "variant": "centered-unadjusted-direct",
          "nobs": 96,
          "max_lag": 12,
          "mean": 0.29779557927083333,
          "denominator": 153.9714722414195,
          "numerators": [
            153.9714722414195,
            102.29629606088473,
            67.86612357881646,
            43.864068660314665,
            13.159013573869158,
            -12.01222465335103
          ],
          "coefficients": [
            1,
            0.6643847368068891,
            0.4407707648102877,
            0.28488438813871975,
            0.08546397187939134,
            -0.07801591085987973
          ],
          "confidence_95": 0.2000416623272929,
          "state": "estimated",
          "reason": "finite centered series with nonzero variance"
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: method, variant, nobs, max_lag, mean, denominator, numerators, coefficients, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "diagnostic-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d09-f01-a01/static/diagnostic-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SM-ACF",
          "title": "statsmodels.tsa.stattools.acf",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decisions",
          "title": "Evidence decisions",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/diagnostics/acf/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/diagnostics/acf/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F01-A02",
      "name": "PACF",
      "headline": null,
      "slug": "pacf",
      "path": "statistical-time-series/diagnostics/pacf",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F01",
        "family": "Diagnostics",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/diagnostics/pacf",
        "entry": "pacf",
        "params": [
          "values",
          "maxLag"
        ],
        "exports": [
          "acf",
          "pacf",
          "adf",
          "kpss",
          "ljungBox",
          "zivotAndrews",
          "runDiagnostic"
        ],
        "archetype": "record-transform",
        "signature": "pacf(values, maxLag)"
      },
      "api": {
        "summary": "Partial autocorrelation: correlation at each lag with the intervening lags removed. Read together with the ACF it identifies model order — a PACF cutting off after lag p suggests AR(p).",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "maxLag",
            "type": "number",
            "required": true,
            "description": "Highest lag to compute.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ method, variant, coefficients, acf_coefficients, recursion, confidence_95 }",
          "description": "Partial coefficients with the Durbin–Levinson recursion steps that produced them."
        },
        "warmup": null,
        "errors": [
          {
            "when": "maxLag is not less than the sample size",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(maxLag²)",
          "space": "O(maxLag)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "pacf([0.49366418,1.54242291,-0.82556495,0.47513288,0.50704417,-0.3816439], 12)",
        "args": [
          {
            "value": [
              0.49366418,
              1.54242291,
              -0.82556495,
              0.47513288,
              0.50704417,
              -0.3816439
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 96
            }
          },
          {
            "value": 12,
            "elided": null
          }
        ],
        "output": {
          "method": "pacf",
          "variant": "biased-yule-walker-levinson-durbin",
          "nobs": 96,
          "max_lag": 12,
          "coefficients": [
            1,
            0.6643847368068891,
            -0.0011391366900339354,
            -0.013487015741398519,
            -0.1763888054329689,
            -0.1217089519082119
          ],
          "acf_coefficients": [
            1,
            0.6643847368068891,
            0.4407707648102877,
            0.28488438813871975,
            0.08546397187939134,
            -0.07801591085987973
          ],
          "recursion": [
            {
              "lag": 1,
              "reflection": 0.6643847368068891,
              "prediction_variance": 0.5585929214980406
            },
            {
              "lag": 2,
              "reflection": -0.0011391366900339354,
              "prediction_variance": 0.5585921966497681
            },
            {
              "lag": 3,
              "reflection": -0.013487015741398519,
              "prediction_variance": 0.5584905889562045
            }
          ],
          "confidence_95": 0.2000416623272929,
          "state": "estimated",
          "reason": "positive prediction variance through requested lag"
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: method, variant, nobs, max_lag, coefficients, acf_coefficients, recursion, confidence_95, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "diagnostic-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d09-f01-a02/static/diagnostic-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SM-ACF",
          "title": "statsmodels.tsa.stattools.acf",
          "author": null,
          "url": null
        },
        {
          "key": "SM-PACF",
          "title": "statsmodels.tsa.stattools.pacf",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decisions",
          "title": "Evidence decisions",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/diagnostics/pacf/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/diagnostics/pacf/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F01-A03",
      "name": "Augmented Dickey-Fuller",
      "headline": null,
      "slug": "augmented-dickey-fuller",
      "path": "statistical-time-series/diagnostics/augmented-dickey-fuller",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F01",
        "family": "Diagnostics",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/diagnostics/augmented-dickey-fuller",
        "entry": "adf",
        "params": [
          "values",
          "lags",
          "criticalValue"
        ],
        "exports": [
          "acf",
          "pacf",
          "adf",
          "kpss",
          "ljungBox",
          "zivotAndrews",
          "runDiagnostic"
        ],
        "archetype": "record-transform",
        "signature": "adf(values, lags, criticalValue)"
      },
      "api": {
        "summary": "Tests for a unit root. The null is that the series *has* one — so failing to reject is not evidence of stationarity, merely absence of evidence against a unit root. That asymmetry is the most misread thing in applied time series.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "lags",
            "type": "number",
            "required": true,
            "description": "Number of lagged differences included to absorb serial correlation.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "criticalValue",
            "type": "number",
            "required": true,
            "description": "Critical value to compare the statistic against, at the chosen significance level.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ method, variant, nobs, lags, gamma, gamma_standard_error, statistic, decision, … }",
          "description": "The statistic, the coefficient and its standard error, and an explicit decision — so the conclusion is separable from the arithmetic."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the sample is too short for the requested lag order",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × lags²)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "adf([0.49366418,1.54242291,-0.82556495,0.47513288,0.50704417,-0.3816439], 1, -2.86)",
        "args": [
          {
            "value": [
              0.49366418,
              1.54242291,
              -0.82556495,
              0.47513288,
              0.50704417,
              -0.3816439
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 96
            }
          },
          {
            "value": 1,
            "elided": null
          },
          {
            "value": -2.86,
            "elided": null
          }
        ],
        "output": {
          "method": "adf",
          "variant": "constant-only-fixed-lag",
          "nobs": 96,
          "regression_nobs": 94,
          "lags": 1,
          "gamma": -0.3307327402574888,
          "gamma_standard_error": 0.08555486242368153,
          "statistic": -3.8657386721007945,
          "critical_value": -2.86,
          "reject_null": true,
          "state": "reject-unit-root",
          "reason": "statistic-below-boundary",
          "coefficients": [
            0.09192051133561,
            -0.3307327402574888,
            -0.0052913498392460345
          ],
          "residual_sse": 84.25503279621253
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 15
        },
        "outputShape": "object with 15 fields: method, variant, nobs, regression_nobs, lags, gamma, gamma_standard_error, statistic, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "diagnostic-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d09-f01-a03/static/diagnostic-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SM-ADF",
          "title": "statsmodels.tsa.stattools.adfuller",
          "author": null,
          "url": null
        },
        {
          "key": "DF-1979",
          "title": "Distribution of the Estimators for Autoregressive Time Series with a Unit Root",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decisions",
          "title": "Evidence decisions",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/diagnostics/augmented-dickey-fuller/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/diagnostics/augmented-dickey-fuller/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F01-A04",
      "name": "KPSS",
      "headline": null,
      "slug": "kpss",
      "path": "statistical-time-series/diagnostics/kpss",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F01",
        "family": "Diagnostics",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/diagnostics/kpss",
        "entry": "kpss",
        "params": [
          "values",
          "lags",
          "criticalValue"
        ],
        "exports": [
          "acf",
          "pacf",
          "adf",
          "kpss",
          "ljungBox",
          "zivotAndrews",
          "runDiagnostic"
        ],
        "archetype": "record-transform",
        "signature": "kpss(values, lags, criticalValue)"
      },
      "api": {
        "summary": "Tests stationarity with the null *reversed* relative to ADF: here the null is that the series is stationary. Running both is standard practice, because agreement is informative and disagreement tells you the sample cannot settle the question.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "lags",
            "type": "number",
            "required": true,
            "description": "Bandwidth for the long-run variance estimator.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "criticalValue",
            "type": "number",
            "required": true,
            "description": "Critical value at the chosen significance level.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ method, variant, residual_mean, partial_sum_numerator, long_run_variance, statistic, decision, … }",
          "description": "The statistic with the long-run variance behind it, which is where the bandwidth choice shows up."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the sample is shorter than the bandwidth requires",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × lags)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "kpss([0.49366418,1.54242291,-0.82556495,0.47513288,0.50704417,-0.3816439], 5, 0.463)",
        "args": [
          {
            "value": [
              0.49366418,
              1.54242291,
              -0.82556495,
              0.47513288,
              0.50704417,
              -0.3816439
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 96
            }
          },
          {
            "value": 5,
            "elided": null
          },
          {
            "value": 0.463,
            "elided": null
          }
        ],
        "output": {
          "method": "kpss",
          "variant": "level-stationary-fixed-bartlett-bandwidth",
          "nobs": 96,
          "lags": 5,
          "residual_mean": -2.0816681711721685e-17,
          "partial_sum_numerator": 0.2446756917455388,
          "long_run_variance": 4.82902222159472,
          "covariance_terms": [
            {
              "lag": 1,
              "weight": 0.8333333333333334,
              "cross_product": 102.29629606088473
            },
            {
              "lag": 2,
              "weight": 0.6666666666666667,
              "cross_product": 67.86612357881646
            },
            {
              "lag": 3,
              "weight": 0.5,
              "cross_product": 43.864068660314665
            }
          ],
          "statistic": 0.05066775022309546,
          "critical_value": 0.463,
          "reject_null": false,
          "state": "fail-to-reject-level-stationarity",
          "reason": "statistic-not-above-boundary"
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: method, variant, nobs, lags, residual_mean, partial_sum_numerator, long_run_variance, covariance_terms, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "diagnostic-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d09-f01-a04/static/diagnostic-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "KPSS-1992",
          "title": "Testing the null hypothesis of stationarity against the alternative of a unit root",
          "author": null,
          "url": null
        },
        {
          "key": "SM-KPSS",
          "title": "statsmodels.tsa.stattools.kpss",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decisions",
          "title": "Evidence decisions",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/diagnostics/kpss/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/diagnostics/kpss/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F01-A05",
      "name": "Ljung-Box",
      "headline": null,
      "slug": "ljung-box",
      "path": "statistical-time-series/diagnostics/ljung-box",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F01",
        "family": "Diagnostics",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/diagnostics/ljung-box",
        "entry": "ljungBox",
        "params": [
          "values",
          "lags",
          "modelDf",
          "alpha"
        ],
        "exports": [
          "acf",
          "pacf",
          "adf",
          "kpss",
          "ljungBox",
          "zivotAndrews",
          "runDiagnostic"
        ],
        "archetype": "record-transform",
        "signature": "ljungBox(values, lags, modelDf, alpha)"
      },
      "api": {
        "summary": "Tests whether a group of autocorrelations is jointly zero. Applied to model residuals it answers the question that matters after fitting: is there structure left that the model failed to capture?",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "lags",
            "type": "number",
            "required": true,
            "description": "Number of lags tested jointly.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "modelDf",
            "type": "number",
            "required": true,
            "description": "Parameters estimated by the model whose residuals these are. Omitting it inflates the degrees of freedom and makes a bad model look adequate.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "alpha",
            "type": "number",
            "required": true,
            "description": "Significance level.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ method, lags, model_df, degrees_of_freedom, terms, statistic, p_value, decision, … }",
          "description": "The statistic and p-value with the degrees-of-freedom adjustment shown."
        },
        "warmup": null,
        "errors": [
          {
            "when": "modelDf is not less than lags",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × lags)",
          "space": "O(lags)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "ljungBox([0.49366418,1.1869847,-1.93610944,1.06953965,0.16494849,-0.7467157], 12, 0, 0.05)",
        "args": [
          {
            "value": [
              0.49366418,
              1.1869847,
              -1.93610944,
              1.06953965,
              0.16494849,
              -0.7467157
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 96
            }
          },
          {
            "value": 12,
            "elided": null
          },
          {
            "value": 0,
            "elided": null
          },
          {
            "value": 0.05,
            "elided": null
          }
        ],
        "output": {
          "method": "ljung_box",
          "variant": "demeaned-residual-portmanteau",
          "nobs": 96,
          "lags": 12,
          "model_df": 0,
          "degrees_of_freedom": 12,
          "terms": [
            {
              "lag": 1,
              "acf": -0.0475050120854155,
              "term": 0.00002375501234984708
            },
            {
              "lag": 2,
              "acf": -0.01074438668394694,
              "term": 0.0000012281047363210248
            },
            {
              "lag": 3,
              "acf": 0.10423989737175164,
              "term": 0.00011683823875347651
            }
          ],
          "statistic": 11.395763774723312,
          "p_value": 0.49534027421087556,
          "alpha": 0.05,
          "reject_null": false,
          "state": "fail-to-reject-residual-whiteness",
          "reason": "p-value-not-below-alpha"
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: method, variant, nobs, lags, model_df, degrees_of_freedom, terms, statistic, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "diagnostic-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d09-f01-a05/static/diagnostic-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SM-ACF",
          "title": "statsmodels.tsa.stattools.acf",
          "author": null,
          "url": null
        },
        {
          "key": "LB-1978",
          "title": "On a measure of lack of fit in time series models",
          "author": null,
          "url": null
        },
        {
          "key": "SM-LB",
          "title": "statsmodels.stats.diagnostic.acorr_ljungbox",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decisions",
          "title": "Evidence decisions",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/diagnostics/ljung-box/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/diagnostics/ljung-box/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F01-A06",
      "name": "Zivot-Andrews Break Test",
      "headline": null,
      "slug": "zivot-andrews-break-test",
      "path": "statistical-time-series/diagnostics/zivot-andrews-break-test",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F01",
        "family": "Diagnostics",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/diagnostics/zivot-andrews-break-test",
        "entry": "zivotAndrews",
        "params": [
          "values",
          "lags",
          "trim",
          "criticalValue"
        ],
        "exports": [
          "acf",
          "pacf",
          "adf",
          "kpss",
          "ljungBox",
          "zivotAndrews",
          "runDiagnostic"
        ],
        "archetype": "record-transform",
        "signature": "zivotAndrews(values, lags, trim, criticalValue)"
      },
      "api": {
        "summary": "A unit-root test that allows one structural break at an unknown date, found by searching. Standard ADF frequently reports a unit root when the truth is a stationary series with a single level shift.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "lags",
            "type": "number",
            "required": true,
            "description": "Lagged differences included.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "trim",
            "type": "number",
            "required": true,
            "description": "Fraction of the sample trimmed at each end of the break search; the test is unreliable near the boundaries.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "criticalValue",
            "type": "number",
            "required": true,
            "description": "Critical value for the minimum statistic across candidate break dates.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ method, trim, candidate_start, candidate_end, scan, break_index, statistic, decision, … }",
          "description": "The chosen break date with the full scan across candidates, so a marginal choice between two dates is visible."
        },
        "warmup": null,
        "errors": [
          {
            "when": "trim leaves too few candidate break points",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n² × lags)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "zivotAndrews([10.34556492,11.02095,9.20624589,10.31211299,10.28712609,9.63521836], 1, 0.15, -4.8)",
        "args": [
          {
            "value": [
              10.34556492,
              11.02095,
              9.20624589,
              10.31211299,
              10.28712609,
              9.63521836
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 96
            }
          },
          {
            "value": 1,
            "elided": null
          },
          {
            "value": 0.15,
            "elided": null
          },
          {
            "value": -4.8,
            "elided": null
          }
        ],
        "output": {
          "method": "zivot_andrews",
          "variant": "intercept-break-fixed-lag",
          "nobs": 96,
          "lags": 1,
          "trim": 0.15,
          "candidate_start": 15,
          "candidate_end": 80,
          "scan": [
            {
              "break_index": 15,
              "statistic": -2.5968971047294005,
              "gamma": -0.16587948752228582,
              "gamma_standard_error": 0.06387603390992676,
              "level_shift": -0.04138705771243637,
              "residual_sse": 63.10830583976075
            },
            {
              "break_index": 16,
              "statistic": -2.5793149673915057,
              "gamma": -0.16477543600586345,
              "gamma_standard_error": 0.06388341016471631,
              "level_shift": -0.01654423349541098,
              "residual_sse": 63.11836401077814
            },
            {
              "break_index": 17,
              "statistic": -2.570119387857429,
              "gamma": -0.16400056863572565,
              "gamma_standard_error": 0.0638104865519279,
              "level_shift": 0.0005933378039946896,
              "residual_sse": 63.12032010539862
            }
          ],
          "break_index": 47,
          "statistic": -7.029594549659584,
          "gamma": -0.5990847849626595,
          "gamma_standard_error": 0.08522323453088355,
          "level_shift": 3.0605819661853846,
          "critical_value": -4.8
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: method, variant, nobs, lags, trim, candidate_start, candidate_end, scan, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "diagnostic-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d09-f01-a06/static/diagnostic-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "ZA-1992",
          "title": "Further Evidence on the Great Crash, the Oil-Price Shock, and the Unit-Root Hypothesis",
          "author": null,
          "url": null
        },
        {
          "key": "SM-ZA",
          "title": "statsmodels.tsa.stattools.zivot_andrews",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence decisions",
          "title": "Evidence decisions",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/diagnostics/zivot-andrews-break-test/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/diagnostics/zivot-andrews-break-test/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F02-A01",
      "name": "AutoReg",
      "headline": null,
      "slug": "autoreg",
      "path": "statistical-time-series/forecast-models/autoreg",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F02",
        "family": "Forecast Models",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/forecast-models/autoreg",
        "entry": "forecastAutoReg",
        "params": [
          "values",
          "ar",
          "intercept",
          "horizon"
        ],
        "exports": [
          "forecastAutoReg"
        ],
        "archetype": "record-transform",
        "signature": "forecastAutoReg(values, ar, intercept, horizon)"
      },
      "api": {
        "summary": "Forecasts from an autoregression with supplied coefficients. Estimation is deliberately separate: this evaluates a model you already have, which keeps the arithmetic checkable.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "ar",
            "type": "number[]",
            "required": true,
            "description": "Autoregressive coefficients, lag 1 first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "intercept",
            "type": "number",
            "required": true,
            "description": "Constant term.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "horizon",
            "type": "number",
            "required": true,
            "description": "Steps ahead to forecast. Beyond a few steps an AR forecast converges to the unconditional mean.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ forecast, fitted, residuals, state }",
          "description": "Forecasts with in-sample fitted values and residuals — the residuals are what Ljung-Box then tests."
        },
        "warmup": null,
        "errors": [
          {
            "when": "fewer observations are supplied than the AR order requires",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × p)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D09-F02-A01.json",
        "call": "forecastAutoReg([10,12,11], [0.5], 5, 2)",
        "args": [
          {
            "value": [
              10,
              12,
              11
            ],
            "elided": null
          },
          {
            "value": [
              0.5
            ],
            "elided": null
          },
          {
            "value": 5,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          }
        ],
        "output": {
          "forecast": [
            10.5,
            10.25
          ]
        },
        "outputElided": null,
        "outputShape": "object with 1 field: forecast"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "boundary-failure.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a01/static/boundary-failure.svg"
          },
          {
            "file": "diagnostic-workbench.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a01/static/diagnostic-workbench.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a01/static/family-handoff.svg"
          },
          {
            "file": "forecast-origin.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a01/static/forecast-origin.svg"
          },
          {
            "file": "recursion-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a01/static/recursion-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "STATSMODELS_AUTOREG",
          "title": "statsmodels.tsa.ar_model.AutoReg",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/generated/statsmodels.tsa.ar_model.AutoReg.html"
        },
        {
          "key": "FPP_ARIMA",
          "title": "Forecasting: Principles and Practice — ARIMA models",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/non-seasonal-arima.html"
        },
        {
          "key": "FPP_ACCURACY",
          "title": "Forecasting: Principles and Practice — Evaluating point forecast accuracy",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/accuracy.html"
        },
        {
          "key": "FPP_TSCV",
          "title": "Forecasting: Principles and Practice — Time series cross-validation",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/tscv.html"
        },
        {
          "key": "FPP_RESIDUALS",
          "title": "Forecasting: Principles and Practice — Evaluating regression and residual behavior",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/regression-evaluation.html"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/forecast-models/autoreg/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/forecast-models/autoreg/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F02-A02",
      "name": "ARMA",
      "headline": null,
      "slug": "arma",
      "path": "statistical-time-series/forecast-models/arma",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F02",
        "family": "Forecast Models",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/forecast-models/arma",
        "entry": "forecastARMA",
        "params": [
          "values",
          "ar",
          "ma",
          "intercept",
          "horizon"
        ],
        "exports": [
          "forecastARMA"
        ],
        "archetype": "record-transform",
        "signature": "forecastARMA(values, ar, ma, intercept, horizon)"
      },
      "api": {
        "summary": "ARMA forecasting with supplied coefficients: autoregressive terms on past values, moving-average terms on past errors.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "ar",
            "type": "number[]",
            "required": true,
            "description": "Autoregressive coefficients.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "ma",
            "type": "number[]",
            "required": true,
            "description": "Moving-average coefficients applied to past forecast errors.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "intercept",
            "type": "number",
            "required": true,
            "description": "Constant term.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "horizon",
            "type": "number",
            "required": true,
            "description": "Steps ahead.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ forecast, fitted, residuals, state }",
          "description": "Forecasts, fitted values and residuals."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the sample is shorter than the model order",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × (p + q))",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D09-F02-A02.json",
        "call": "forecastARMA([10,12,11], [0.5], [0.25], 5, 2)",
        "args": [
          {
            "value": [
              10,
              12,
              11
            ],
            "elided": null
          },
          {
            "value": [
              0.5
            ],
            "elided": null
          },
          {
            "value": [
              0.25
            ],
            "elided": null
          },
          {
            "value": 5,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          }
        ],
        "output": {
          "forecast": [
            10.375,
            10.1875
          ]
        },
        "outputElided": null,
        "outputShape": "object with 1 field: forecast"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "boundary-failure.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a02/static/boundary-failure.svg"
          },
          {
            "file": "diagnostic-workbench.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a02/static/diagnostic-workbench.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a02/static/family-handoff.svg"
          },
          {
            "file": "forecast-origin.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a02/static/forecast-origin.svg"
          },
          {
            "file": "recursion-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a02/static/recursion-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "STATSMODELS_ARIMA",
          "title": "statsmodels.tsa.arima.model.ARIMA",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/generated/statsmodels.tsa.arima.model.ARIMA.html"
        },
        {
          "key": "FPP_ARIMA",
          "title": "Forecasting: Principles and Practice — ARIMA models",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/non-seasonal-arima.html"
        },
        {
          "key": "FPP_ACCURACY",
          "title": "Forecasting: Principles and Practice — Evaluating point forecast accuracy",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/accuracy.html"
        },
        {
          "key": "FPP_TSCV",
          "title": "Forecasting: Principles and Practice — Time series cross-validation",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/tscv.html"
        },
        {
          "key": "FPP_RESIDUALS",
          "title": "Forecasting: Principles and Practice — Evaluating regression and residual behavior",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/regression-evaluation.html"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/forecast-models/arma/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/forecast-models/arma/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F02-A03",
      "name": "ARIMA",
      "headline": null,
      "slug": "arima",
      "path": "statistical-time-series/forecast-models/arima",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F02",
        "family": "Forecast Models",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/forecast-models/arima",
        "entry": "forecastARIMA",
        "params": [
          "values",
          "ar",
          "ma",
          "intercept",
          "differenceOrder",
          "horizon"
        ],
        "exports": [
          "forecastARIMA"
        ],
        "archetype": "record-transform",
        "signature": "forecastARIMA(values, ar, ma, intercept, differenceOrder, horizon)"
      },
      "api": {
        "summary": "ARMA on a differenced series, with forecasts integrated back to the original level. The integration step is where sign and level errors hide, so both the differenced and the level forecast are returned.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "ar",
            "type": "number[]",
            "required": true,
            "description": "Autoregressive coefficients.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "ma",
            "type": "number[]",
            "required": true,
            "description": "Moving-average coefficients.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "intercept",
            "type": "number",
            "required": true,
            "description": "Constant term.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "differenceOrder",
            "type": "number",
            "required": true,
            "description": "Number of differences applied. One is usual for prices; two is rarely justified.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "horizon",
            "type": "number",
            "required": true,
            "description": "Steps ahead.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ forecast, fitted, residuals, state, differenced_forecast }",
          "description": "Both the differenced forecast and the integrated one, so the reconstruction can be checked."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the sample is shorter than the differencing and model order require",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × (p + q))",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D09-F02-A03.json",
        "call": "forecastARIMA([100,102,105,109,114,120], [0.5], [], 1, 1, 2)",
        "args": [
          {
            "value": [
              100,
              102,
              105,
              109,
              114,
              120
            ],
            "elided": null
          },
          {
            "value": [
              0.5
            ],
            "elided": null
          },
          {
            "value": [],
            "elided": null
          },
          {
            "value": 1,
            "elided": null
          },
          {
            "value": 1,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          }
        ],
        "output": {
          "forecast": [
            124,
            127
          ]
        },
        "outputElided": null,
        "outputShape": "object with 1 field: forecast"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "boundary-failure.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a03/static/boundary-failure.svg"
          },
          {
            "file": "diagnostic-workbench.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a03/static/diagnostic-workbench.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a03/static/family-handoff.svg"
          },
          {
            "file": "forecast-origin.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a03/static/forecast-origin.svg"
          },
          {
            "file": "recursion-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a03/static/recursion-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "FPP_ARIMA",
          "title": "Forecasting: Principles and Practice — ARIMA models",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/non-seasonal-arima.html"
        },
        {
          "key": "STATSMODELS_ARIMA",
          "title": "statsmodels.tsa.arima.model.ARIMA",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/generated/statsmodels.tsa.arima.model.ARIMA.html"
        },
        {
          "key": "FPP_ACCURACY",
          "title": "Forecasting: Principles and Practice — Evaluating point forecast accuracy",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/accuracy.html"
        },
        {
          "key": "FPP_TSCV",
          "title": "Forecasting: Principles and Practice — Time series cross-validation",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/tscv.html"
        },
        {
          "key": "FPP_RESIDUALS",
          "title": "Forecasting: Principles and Practice — Evaluating regression and residual behavior",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/regression-evaluation.html"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/forecast-models/arima/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/forecast-models/arima/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F02-A04",
      "name": "SARIMA/SARIMAX",
      "headline": null,
      "slug": "sarima-sarimax",
      "path": "statistical-time-series/forecast-models/sarima-sarimax",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F02",
        "family": "Forecast Models",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/forecast-models/sarima-sarimax",
        "entry": "forecastSARIMAX",
        "params": [
          "values",
          "exog",
          "futureExog",
          "beta",
          "ar",
          "ma",
          "seasonalAr",
          "seasonalMa",
          "intercept",
          "differenceOrder",
          "seasonalDifferenceOrder",
          "period",
          "horizon"
        ],
        "exports": [
          "forecastSARIMAX"
        ],
        "archetype": "record-transform",
        "signature": "forecastSARIMAX(values, exog, futureExog, beta, ar, ma, seasonalAr, seasonalMa, intercept, differenceOrder, seasonalDifferenceOrder, period, horizon)"
      },
      "api": {
        "summary": "Seasonal ARIMA with optional exogenous regressors. Future exogenous values must be supplied for the whole horizon — if you do not know them, the forecast is conditional on a guess, and that dependency is worth being explicit about.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "exog",
            "type": "number[][]",
            "required": true,
            "description": "In-sample exogenous regressors, one row per observation.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "futureExog",
            "type": "number[][]",
            "required": true,
            "description": "Exogenous values over the forecast horizon. These are assumptions, not data.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "beta",
            "type": "number[]",
            "required": true,
            "description": "Coefficients on the exogenous regressors.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "ar",
            "type": "number[]",
            "required": true,
            "description": "Non-seasonal AR coefficients.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "ma",
            "type": "number[]",
            "required": true,
            "description": "Non-seasonal MA coefficients.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "seasonalAr",
            "type": "number[]",
            "required": true,
            "description": "Seasonal AR coefficients.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "seasonalMa",
            "type": "number[]",
            "required": true,
            "description": "Seasonal MA coefficients.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "intercept",
            "type": "number",
            "required": true,
            "description": "Constant term.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "differenceOrder",
            "type": "number",
            "required": true,
            "description": "Non-seasonal differencing order.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "seasonalDifferenceOrder",
            "type": "number",
            "required": true,
            "description": "Seasonal differencing order.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "period",
            "type": "number",
            "required": true,
            "description": "Seasonal period — 12 for monthly, 4 for quarterly, 5 for trading days in a week.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "horizon",
            "type": "number",
            "required": true,
            "description": "Steps ahead.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ forecast, fitted, residuals, state, transformed_forecast, residualized_forecast }",
          "description": "The final forecast plus the transformed and residualised intermediates."
        },
        "warmup": null,
        "errors": [
          {
            "when": "futureExog is shorter than the horizon",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × (p + q + P + Q))",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D09-F02-A04.json",
        "call": "forecastSARIMAX([12,15,18,21,24,27], [[1],[2],[3]], [[9],[10]], [2], [0.5], [], [0.25], [], 0, 1, 0, 2, 2)",
        "args": [
          {
            "value": [
              12,
              15,
              18,
              21,
              24,
              27
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 8
            }
          },
          {
            "value": [
              [
                1
              ],
              [
                2
              ],
              [
                3
              ]
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 8
            }
          },
          {
            "value": [
              [
                9
              ],
              [
                10
              ]
            ],
            "elided": null
          },
          {
            "value": [
              2
            ],
            "elided": null
          },
          {
            "value": [
              0.5
            ],
            "elided": null
          },
          {
            "value": [],
            "elided": null
          },
          {
            "value": [
              0.25
            ],
            "elided": null
          },
          {
            "value": [],
            "elided": null
          },
          {
            "value": 0,
            "elided": null
          },
          {
            "value": 1,
            "elided": null
          },
          {
            "value": 0,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          }
        ],
        "output": {
          "forecast": [
            35.625,
            38.0625
          ]
        },
        "outputElided": null,
        "outputShape": "object with 1 field: forecast"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "boundary-failure.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a04/static/boundary-failure.svg"
          },
          {
            "file": "diagnostic-workbench.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a04/static/diagnostic-workbench.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a04/static/family-handoff.svg"
          },
          {
            "file": "forecast-origin.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a04/static/forecast-origin.svg"
          },
          {
            "file": "recursion-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a04/static/recursion-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "STATSMODELS_SARIMAX",
          "title": "statsmodels.tsa.statespace.sarimax.SARIMAX",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/generated/statsmodels.tsa.statespace.sarimax.SARIMAX.html"
        },
        {
          "key": "FPP_SEASONAL",
          "title": "Forecasting: Principles and Practice — Seasonal ARIMA",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/seasonal-arima.html"
        },
        {
          "key": "STATSMODELS_ARIMA",
          "title": "statsmodels.tsa.arima.model.ARIMA",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/generated/statsmodels.tsa.arima.model.ARIMA.html"
        },
        {
          "key": "FPP_ACCURACY",
          "title": "Forecasting: Principles and Practice — Evaluating point forecast accuracy",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/accuracy.html"
        },
        {
          "key": "FPP_TSCV",
          "title": "Forecasting: Principles and Practice — Time series cross-validation",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/tscv.html"
        },
        {
          "key": "FPP_RESIDUALS",
          "title": "Forecasting: Principles and Practice — Evaluating regression and residual behavior",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/regression-evaluation.html"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/forecast-models/sarima-sarimax/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/forecast-models/sarima-sarimax/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F02-A05",
      "name": "Holt-Winters",
      "headline": null,
      "slug": "holt-winters",
      "path": "statistical-time-series/forecast-models/holt-winters",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F02",
        "family": "Forecast Models",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/forecast-models/holt-winters",
        "entry": "forecastHoltWintersAdditive",
        "params": [
          "values",
          "alpha",
          "beta",
          "gamma",
          "period",
          "horizon",
          "initialLevel",
          "initialTrend",
          "initialSeasonals"
        ],
        "exports": [
          "forecastHoltWintersAdditive"
        ],
        "archetype": "record-transform",
        "signature": "forecastHoltWintersAdditive(values, alpha, beta, gamma, period, horizon, initialLevel, initialTrend, initialSeasonals)"
      },
      "api": {
        "summary": "Additive Holt-Winters: exponential smoothing of level, trend and seasonality. Unfashionable and frequently competitive with far more complex methods on short seasonal series.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "alpha",
            "type": "number",
            "required": true,
            "description": "Level smoothing factor, 0…1.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "beta",
            "type": "number",
            "required": true,
            "description": "Trend smoothing factor, 0…1.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "gamma",
            "type": "number",
            "required": true,
            "description": "Seasonal smoothing factor, 0…1.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "period",
            "type": "number",
            "required": true,
            "description": "Seasonal period.",
            "constraints": {
              "min": 2,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "horizon",
            "type": "number",
            "required": true,
            "description": "Steps ahead.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "initialLevel",
            "type": "number",
            "required": true,
            "description": "Starting level.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "initialTrend",
            "type": "number",
            "required": true,
            "description": "Starting trend.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "initialSeasonals",
            "type": "number[]",
            "required": true,
            "description": "Starting seasonal factors, one per period step. Additive factors should sum to approximately zero.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ forecast, fitted, residuals, trace, state }",
          "description": "Forecasts with a `trace` of level, trend and seasonal components at each step."
        },
        "warmup": null,
        "errors": [
          {
            "when": "any smoothing factor falls outside 0…1, or initialSeasonals is not of length period",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D09-F02-A05.json",
        "call": "forecastHoltWintersAdditive([10,12,11,13], 0.5, 0.5, 0.5, 2, 2, 9, 1, [-1,1])",
        "args": [
          {
            "value": [
              10,
              12,
              11,
              13
            ],
            "elided": null
          },
          {
            "value": 0.5,
            "elided": null
          },
          {
            "value": 0.5,
            "elided": null
          },
          {
            "value": 0.5,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          },
          {
            "value": 9,
            "elided": null
          },
          {
            "value": 1,
            "elided": null
          },
          {
            "value": [
              -1,
              1
            ],
            "elided": null
          }
        ],
        "output": {
          "forecast": [
            12.35546875,
            14.58203125
          ]
        },
        "outputElided": null,
        "outputShape": "object with 1 field: forecast"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "boundary-failure.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a05/static/boundary-failure.svg"
          },
          {
            "file": "diagnostic-workbench.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a05/static/diagnostic-workbench.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a05/static/family-handoff.svg"
          },
          {
            "file": "forecast-origin.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a05/static/forecast-origin.svg"
          },
          {
            "file": "recursion-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a05/static/recursion-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "FPP_HW",
          "title": "Forecasting: Principles and Practice — Holt-Winters",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/holt-winters.html"
        },
        {
          "key": "STATSMODELS_HW",
          "title": "Exponential smoothing examples",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/examples/notebooks/generated/exponential_smoothing.html"
        },
        {
          "key": "FPP_ACCURACY",
          "title": "Forecasting: Principles and Practice — Evaluating point forecast accuracy",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/accuracy.html"
        },
        {
          "key": "FPP_TSCV",
          "title": "Forecasting: Principles and Practice — Time series cross-validation",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/tscv.html"
        },
        {
          "key": "FPP_RESIDUALS",
          "title": "Forecasting: Principles and Practice — Evaluating regression and residual behavior",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/regression-evaluation.html"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/forecast-models/holt-winters/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/forecast-models/holt-winters/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F02-A06",
      "name": "Theta Forecast",
      "headline": null,
      "slug": "theta-forecast",
      "path": "statistical-time-series/forecast-models/theta-forecast",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F02",
        "family": "Forecast Models",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/forecast-models/theta-forecast",
        "entry": "forecastTheta",
        "params": [
          "values",
          "alpha",
          "horizon"
        ],
        "exports": [
          "forecastTheta"
        ],
        "archetype": "record-transform",
        "signature": "forecastTheta(values, alpha, horizon)"
      },
      "api": {
        "summary": "The Theta method: decompose, extrapolate, recombine. It won the M3 forecasting competition and is roughly equivalent to simple exponential smoothing with drift — a useful benchmark precisely because it is so simple.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series in chronological order, oldest first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "alpha",
            "type": "number",
            "required": true,
            "description": "Smoothing factor for the exponential component, 0…1.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "horizon",
            "type": "number",
            "required": true,
            "description": "Steps ahead.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ forecast, fitted, state }",
          "description": "Forecasts and fitted values."
        },
        "warmup": null,
        "errors": [
          {
            "when": "alpha falls outside 0…1",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D09-F02-A06.json",
        "call": "forecastTheta([10,12,14,16], 0.5, 2)",
        "args": [
          {
            "value": [
              10,
              12,
              14,
              16
            ],
            "elided": null
          },
          {
            "value": 0.5,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          }
        ],
        "output": {
          "forecast": [
            16.125,
            17.125
          ]
        },
        "outputElided": null,
        "outputShape": "object with 1 field: forecast"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "boundary-failure.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a06/static/boundary-failure.svg"
          },
          {
            "file": "diagnostic-workbench.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a06/static/diagnostic-workbench.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a06/static/family-handoff.svg"
          },
          {
            "file": "forecast-origin.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a06/static/forecast-origin.svg"
          },
          {
            "file": "recursion-anatomy.svg",
            "url": "https://thefintechbuilder.com/content/d09-f02-a06/static/recursion-anatomy.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "THETA_ORIGINAL",
          "title": "The theta model: a decomposition approach to forecasting",
          "author": "V. Assimakopoulos and K. Nikolopoulos",
          "url": "https://doi.org/10.1016/S0169-2070(00)00066-2"
        },
        {
          "key": "THETA_UNMASKED",
          "title": "Unmasking the Theta method",
          "author": "Rob J. Hyndman and Md Baki Billah",
          "url": "https://doi.org/10.1016/S0169-2070(01)00143-1"
        },
        {
          "key": "STATSMODELS_THETA",
          "title": "The Theta Model",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/examples/notebooks/generated/theta-model.html"
        },
        {
          "key": "FPP_ACCURACY",
          "title": "Forecasting: Principles and Practice — Evaluating point forecast accuracy",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/accuracy.html"
        },
        {
          "key": "FPP_TSCV",
          "title": "Forecasting: Principles and Practice — Time series cross-validation",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/tscv.html"
        },
        {
          "key": "FPP_RESIDUALS",
          "title": "Forecasting: Principles and Practice — Evaluating regression and residual behavior",
          "author": "Rob J. Hyndman and George Athanasopoulos",
          "url": "https://otexts.com/fpp3/regression-evaluation.html"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/forecast-models/theta-forecast/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/forecast-models/theta-forecast/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F03-A01",
      "name": "VAR",
      "headline": null,
      "slug": "var",
      "path": "statistical-time-series/multivariate-systems/var",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F03",
        "family": "Multivariate Systems",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/multivariate-systems/var",
        "entry": "fitVAR",
        "params": [
          "values",
          "lags",
          "includeIntercept"
        ],
        "exports": [
          "companionMatrix",
          "companionSpectralRadius",
          "fitVAR",
          "choleskyLower",
          "fitRecursiveSVAR",
          "fitVECMFixedBeta",
          "movingAverageMatrices",
          "impulseResponses",
          "forecastErrorVarianceDecomposition"
        ],
        "archetype": "record-transform",
        "signature": "fitVAR(values, lags, includeIntercept)"
      },
      "api": {
        "summary": "Vector autoregression: every series regressed on lags of all of them. The natural model when variables move together, and the base every impulse-response and variance-decomposition result is computed from.",
        "params": [
          {
            "name": "values",
            "type": "number[][]",
            "required": true,
            "description": "Multivariate series, one row per observation and one column per variable. Column order is meaningful — everything downstream refers to variables by position.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "lags",
            "type": "number",
            "required": true,
            "description": "Lag order. Parameters grow with the square of the number of variables, so this is where a VAR runs out of data.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "includeIntercept",
            "type": "boolean",
            "required": false,
            "description": "Whether to fit a constant term.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ intercept, coefficients, sigma_u_mle, residuals, fitted, one_step_forecast, effective_observations, … }",
          "description": "Coefficients and the residual covariance, which is the input to structural identification."
        },
        "warmup": null,
        "errors": [
          {
            "when": "observations are fewer than the parameters to estimate",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × (k × lags)²)",
          "space": "O((k × lags)²)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "fitVAR([[-1.4163056264,-0.7075620912],[-1.4144491277,-0.24959813],[-1.915874322,-0.31233481]], 1)",
        "args": [
          {
            "value": [
              [
                -1.4163056264,
                -0.7075620912
              ],
              [
                -1.4144491277,
                -0.24959813
              ],
              [
                -1.915874322,
                -0.31233481
              ]
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 120
            }
          },
          {
            "value": 1,
            "elided": null
          }
        ],
        "output": {
          "intercept": [
            -0.070907764383,
            -0.013615076949
          ],
          "coefficients": [
            [
              [
                0.555831819774,
                0.20542641337
              ],
              [
                -0.118628539474,
                0.408179850969
              ]
            ]
          ],
          "sigma_u_mle": [
            [
              0.726815513707,
              0.33092608263
            ],
            [
              0.33092608263,
              0.420249111781
            ]
          ],
          "residuals": [
            [
              -0.410961687007,
              -0.115184732022
            ],
            [
              -1.00749667636,
              -0.364632839724
            ],
            [
              -0.403977225473,
              -0.149480679886
            ]
          ],
          "fitted": [
            [
              -1.003487440693,
              -0.134413397978
            ],
            [
              -0.90837764564,
              0.052298029724
            ],
            [
              -1.199973495027,
              0.086173519486
            ]
          ],
          "one_step_forecast": [
            0.452328292866,
            -0.113742494174
          ],
          "effective_observations": 119,
          "variables": 2,
          "lags": 1,
          "row_sum_stability_bound": 0.761258233144,
          "companion_spectral_radius": 0.501247229166,
          "stability_state": "stable",
          "stability_boundary": 1,
          "near_boundary_threshold": 0.9
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 16
        },
        "outputShape": "object with 16 fields: intercept, coefficients, sigma_u_mle, residuals, fitted, one_step_forecast, effective_observations, variables, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f03-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SM-VAR",
          "title": "statsmodels vector autoregression documentation",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/vector_ar.html"
        },
        {
          "key": "SM-TOPIC",
          "title": "statsmodels VAR API documentation",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/generated/statsmodels.tsa.vector_ar.var_model.VAR.html"
        },
        {
          "key": "HAMILTON-1994",
          "title": "Time Series Analysis",
          "author": "James D. Hamilton",
          "url": "https://press.princeton.edu/books/hardcover/9780691042893/time-series-analysis"
        },
        {
          "key": "LUT-2005",
          "title": "New Introduction to Multiple Time Series Analysis",
          "author": "Helmut Lütkepohl",
          "url": "https://doi.org/10.1007/978-3-540-27752-1"
        },
        {
          "key": "SIMS-1980",
          "title": "Macroeconomics and Reality",
          "author": "Christopher A. Sims",
          "url": "https://doi.org/10.2307/1912017"
        },
        {
          "key": "JOH-1988",
          "title": "Statistical Analysis of Cointegration Vectors",
          "author": "Søren Johansen",
          "url": "https://doi.org/10.1016/0165-1889(88)90041-3"
        },
        {
          "key": "Publication boundary",
          "title": "Publication boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/multivariate-systems/var/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/multivariate-systems/var/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F03-A02",
      "name": "Structural VAR",
      "headline": null,
      "slug": "structural-var",
      "path": "statistical-time-series/multivariate-systems/structural-var",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F03",
        "family": "Multivariate Systems",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/multivariate-systems/structural-var",
        "entry": "fitRecursiveSVAR",
        "params": [
          "values",
          "lags"
        ],
        "exports": [
          "companionMatrix",
          "companionSpectralRadius",
          "fitVAR",
          "choleskyLower",
          "fitRecursiveSVAR",
          "fitVECMFixedBeta",
          "movingAverageMatrices",
          "impulseResponses",
          "forecastErrorVarianceDecomposition"
        ],
        "archetype": "record-transform",
        "signature": "fitRecursiveSVAR(values, lags)"
      },
      "api": {
        "summary": "Identifies structural shocks by Cholesky decomposition of the residual covariance. The identification is recursive, which means **variable ordering is an economic assumption**: the first variable is assumed unaffected contemporaneously by the others, and reordering changes the results.",
        "params": [
          {
            "name": "values",
            "type": "number[][]",
            "required": true,
            "description": "Multivariate series. Column order encodes the identifying assumption, not merely a layout choice.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "lags",
            "type": "number",
            "required": true,
            "description": "Lag order.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ coefficients, sigma_u_mle, impact_matrix, structural_shocks, reconstructed_shocks, … }",
          "description": "The impact matrix and structural shocks, with reconstructed shocks so the decomposition can be verified rather than trusted."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the residual covariance is not positive definite",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × (k × lags)² + k³)",
          "space": "O((k × lags)²)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "fitRecursiveSVAR([[-1.4163056264,-0.7075620912],[-1.4144491277,-0.24959813],[-1.915874322,-0.31233481]], 1)",
        "args": [
          {
            "value": [
              [
                -1.4163056264,
                -0.7075620912
              ],
              [
                -1.4144491277,
                -0.24959813
              ],
              [
                -1.915874322,
                -0.31233481
              ]
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 120
            }
          },
          {
            "value": 1,
            "elided": null
          }
        ],
        "output": {
          "coefficients": [
            [
              [
                0.555831819774,
                0.20542641337
              ],
              [
                -0.118628539474,
                0.408179850969
              ]
            ]
          ],
          "intercept": [
            -0.070907764383,
            -0.013615076949
          ],
          "sigma_u_mle": [
            [
              0.726815513707,
              0.33092608263
            ],
            [
              0.33092608263,
              0.420249111781
            ]
          ],
          "impact_matrix": [
            [
              0.852534758064,
              0
            ],
            [
              0.388167261804,
              0.519206402739
            ]
          ],
          "structural_shocks": [
            [
              -0.482046841046,
              0.138538488641
            ],
            [
              -1.181766100244,
              0.181219012332
            ],
            [
              -0.473854258318,
              0.066359023845
            ]
          ],
          "reconstructed_sigma_u": [
            [
              0.726815513707,
              0.33092608263
            ],
            [
              0.33092608263,
              0.420249111782
            ]
          ],
          "covariance_reconstruction_max_error": 1e-12,
          "structural_shock_covariance_mle": [
            [
              1,
              -1e-12
            ],
            [
              -1e-12,
              0.999999999999
            ]
          ],
          "structural_shock_identity_max_error": 1e-12,
          "ordering": [
            0,
            1
          ],
          "companion_spectral_radius": 0.501247229166,
          "stability_state": "stable",
          "state": "identified-recursively",
          "reason": "lower-cholesky-ordering"
        },
        "outputElided": null,
        "outputShape": "object with 14 fields: coefficients, intercept, sigma_u_mle, impact_matrix, structural_shocks, reconstructed_sigma_u, covariance_reconstruction_max_error, structural_shock_covariance_mle, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f03-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SM-VAR",
          "title": "statsmodels vector autoregression documentation",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/vector_ar.html"
        },
        {
          "key": "SM-TOPIC",
          "title": "statsmodels Structural VAR API documentation",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/generated/statsmodels.tsa.vector_ar.svar_model.SVAR.html"
        },
        {
          "key": "SIMS-1986",
          "title": "Are Forecasting Models Usable for Policy Analysis?",
          "author": "Christopher A. Sims",
          "url": "https://www.minneapolisfed.org/research/quarterly-review/are-forecasting-models-usable-for-policy-analysis"
        },
        {
          "key": "LUT-2005",
          "title": "New Introduction to Multiple Time Series Analysis",
          "author": "Helmut Lütkepohl",
          "url": "https://doi.org/10.1007/978-3-540-27752-1"
        },
        {
          "key": "SIMS-1980",
          "title": "Macroeconomics and Reality",
          "author": "Christopher A. Sims",
          "url": "https://doi.org/10.2307/1912017"
        },
        {
          "key": "JOH-1988",
          "title": "Statistical Analysis of Cointegration Vectors",
          "author": "Søren Johansen",
          "url": "https://doi.org/10.1016/0165-1889(88)90041-3"
        },
        {
          "key": "Publication boundary",
          "title": "Publication boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/multivariate-systems/structural-var/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/multivariate-systems/structural-var/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F03-A03",
      "name": "VECM",
      "headline": null,
      "slug": "vecm",
      "path": "statistical-time-series/multivariate-systems/vecm",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F03",
        "family": "Multivariate Systems",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/multivariate-systems/vecm",
        "entry": "fitVECMFixedBeta",
        "params": [
          "values",
          "beta",
          "differenceLags",
          "includeIntercept"
        ],
        "exports": [
          "companionMatrix",
          "companionSpectralRadius",
          "fitVAR",
          "choleskyLower",
          "fitRecursiveSVAR",
          "fitVECMFixedBeta",
          "movingAverageMatrices",
          "impulseResponses",
          "forecastErrorVarianceDecomposition"
        ],
        "archetype": "record-transform",
        "signature": "fitVECMFixedBeta(values, beta, differenceLags, includeIntercept)"
      },
      "api": {
        "summary": "Vector error correction with a fixed cointegrating vector. For series that wander individually but not apart: differencing them separately would throw away the long-run relationship, which is usually the thing of interest.",
        "params": [
          {
            "name": "values",
            "type": "number[][]",
            "required": true,
            "description": "Multivariate series believed to be cointegrated.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "beta",
            "type": "number[]",
            "required": true,
            "description": "The cointegrating vector, supplied rather than estimated so the arithmetic stays checkable.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "differenceLags",
            "type": "number",
            "required": true,
            "description": "Lags of the differenced series included.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "includeIntercept",
            "type": "boolean",
            "required": false,
            "description": "Whether to fit a constant.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ beta, alpha, gamma, intercept, sigma_u_mle, error_correction, pi, adjustment_root, … }",
          "description": "The adjustment coefficients `alpha` and the error-correction term. `adjustment_root` indicates whether the system actually returns to equilibrium."
        },
        "warmup": null,
        "errors": [
          {
            "when": "beta length does not match the number of variables",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × (k × lags)²)",
          "space": "O((k × lags)²)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "fitVECMFixedBeta([[57.3488705363,57.391383279],[57.9060942406,57.7180113466],[57.8301951168,57.7940655992]], [1,-1], 1)",
        "args": [
          {
            "value": [
              [
                57.3488705363,
                57.391383279
              ],
              [
                57.9060942406,
                57.7180113466
              ],
              [
                57.8301951168,
                57.7940655992
              ]
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 120
            }
          },
          {
            "value": [
              1,
              -1
            ],
            "elided": null
          },
          {
            "value": 1,
            "elided": null
          }
        ],
        "output": {
          "beta": [
            1,
            -1
          ],
          "alpha": [
            -0.03243684502,
            0.406805203364
          ],
          "gamma": [
            [
              [
                0.041044635794,
                -0.023887057656
              ],
              [
                -0.069691641426,
                0.155827060535
              ]
            ]
          ],
          "intercept": [
            0.004904479316,
            0.007790140091
          ],
          "sigma_u_mle": [
            [
              0.115776128937,
              0.119483748379
            ],
            [
              0.119483748379,
              0.19954598501
            ]
          ],
          "error_correction": [
            0.188082894,
            0.0361295176,
            -0.620844851,
            -0.6261144079,
            -0.5222041208,
            -0.7533463451
          ],
          "pi": [
            [
              -0.03243684502,
              0.03243684502
            ],
            [
              0.406805203364,
              -0.406805203364
            ]
          ],
          "adjustment_root": 0.560757951616,
          "error_correction_loading_root": 0.560757951616,
          "half_life": null,
          "exact_half_life": null,
          "half_life_scope": "not-reported-short-run-gamma-present",
          "effective_observations": 118,
          "rank": 1
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: beta, alpha, gamma, intercept, sigma_u_mle, error_correction, pi, adjustment_root, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f03-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SM-VAR",
          "title": "statsmodels vector autoregression documentation",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/vector_ar.html"
        },
        {
          "key": "SM-TOPIC",
          "title": "statsmodels VECM API documentation",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/generated/statsmodels.tsa.vector_ar.vecm.VECM.html"
        },
        {
          "key": "ENGLE-GRANGER-1987",
          "title": "Co-integration and Error Correction: Representation, Estimation, and Testing",
          "author": "Robert F. Engle and Clive W. J. Granger",
          "url": "https://doi.org/10.2307/1913236"
        },
        {
          "key": "LUT-2005",
          "title": "New Introduction to Multiple Time Series Analysis",
          "author": "Helmut Lütkepohl",
          "url": "https://doi.org/10.1007/978-3-540-27752-1"
        },
        {
          "key": "SIMS-1980",
          "title": "Macroeconomics and Reality",
          "author": "Christopher A. Sims",
          "url": "https://doi.org/10.2307/1912017"
        },
        {
          "key": "JOH-1988",
          "title": "Statistical Analysis of Cointegration Vectors",
          "author": "Søren Johansen",
          "url": "https://doi.org/10.1016/0165-1889(88)90041-3"
        },
        {
          "key": "Publication boundary",
          "title": "Publication boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/multivariate-systems/vecm/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/multivariate-systems/vecm/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F03-A04",
      "name": "Impulse-Response Analysis",
      "headline": null,
      "slug": "impulse-response-analysis",
      "path": "statistical-time-series/multivariate-systems/impulse-response-analysis",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F03",
        "family": "Multivariate Systems",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/multivariate-systems/impulse-response-analysis",
        "entry": "impulseResponses",
        "params": [
          "coefficients",
          "horizon"
        ],
        "exports": [
          "companionMatrix",
          "companionSpectralRadius",
          "fitVAR",
          "choleskyLower",
          "fitRecursiveSVAR",
          "fitVECMFixedBeta",
          "movingAverageMatrices",
          "impulseResponses",
          "forecastErrorVarianceDecomposition"
        ],
        "archetype": "record-transform",
        "signature": "impulseResponses(coefficients, horizon)"
      },
      "api": {
        "summary": "Traces how a one-off shock to one variable propagates through the system over time. The headline output of any VAR — and only interpretable given the identifying assumption that produced the impact matrix.",
        "params": [
          {
            "name": "coefficients",
            "type": "number[][]",
            "required": true,
            "description": "VAR coefficient matrices.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "horizon",
            "type": "number",
            "required": true,
            "description": "Periods to trace.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ responses, cumulative_responses, horizon, impact_matrix, companion_spectral_radius, stability_state, … }",
          "description": "Responses and their cumulative sums, plus the companion spectral radius — above 1 the system is explosive and the responses diverge rather than decay, which is stated instead of silently plotted."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the coefficient matrices are not square or are inconsistent in dimension",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(horizon × k³)",
          "space": "O(horizon × k²)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "impulseResponses([[[0.55,0.18],[-0.12,0.42]]], 8, [[0.8,0],[0.35,0.55]])",
        "args": [
          {
            "value": [
              [
                [
                  0.55,
                  0.18
                ],
                [
                  -0.12,
                  0.42
                ]
              ]
            ],
            "elided": null
          },
          {
            "value": 8,
            "elided": null
          },
          {
            "value": [
              [
                0.8,
                0
              ],
              [
                0.35,
                0.55
              ]
            ],
            "elided": null
          }
        ],
        "output": {
          "responses": [
            [
              [
                0.8,
                0
              ],
              [
                0.35,
                0.55
              ]
            ],
            [
              [
                0.503,
                0.099
              ],
              [
                0.051,
                0.231
              ]
            ],
            [
              [
                0.28583,
                0.09603
              ],
              [
                -0.03894,
                0.08514
              ]
            ]
          ],
          "cumulative_responses": [
            [
              [
                0.8,
                0
              ],
              [
                0.35,
                0.55
              ]
            ],
            [
              [
                1.303,
                0.099
              ],
              [
                0.401,
                0.781
              ]
            ],
            [
              [
                1.58883,
                0.19503
              ],
              [
                0.36206,
                0.86614
              ]
            ]
          ],
          "horizon": 8,
          "impact_matrix": [
            [
              0.8,
              0
            ],
            [
              0.35,
              0.55
            ]
          ],
          "companion_spectral_radius": 0.502593274925,
          "stability_state": "stable",
          "stability_boundary": 1,
          "near_boundary_threshold": 0.9,
          "state": "computed",
          "reason": "ma-recursion-times-declared-impact"
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: responses, cumulative_responses, horizon, impact_matrix, companion_spectral_radius, stability_state, stability_boundary, near_boundary_threshold, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f03-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SM-VAR",
          "title": "statsmodels vector autoregression documentation",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/vector_ar.html"
        },
        {
          "key": "SM-TOPIC",
          "title": "statsmodels Impulse-Response Analysis API documentation",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/vector_ar.html#impulse-response-analysis"
        },
        {
          "key": "PESARAN-SHIN-1998",
          "title": "Generalized Impulse Response Analysis in Linear Multivariate Models",
          "author": "M. Hashem Pesaran and Yongcheol Shin",
          "url": "https://doi.org/10.1016/S0165-1765(97)00214-0"
        },
        {
          "key": "LUT-2005",
          "title": "New Introduction to Multiple Time Series Analysis",
          "author": "Helmut Lütkepohl",
          "url": "https://doi.org/10.1007/978-3-540-27752-1"
        },
        {
          "key": "SIMS-1980",
          "title": "Macroeconomics and Reality",
          "author": "Christopher A. Sims",
          "url": "https://doi.org/10.2307/1912017"
        },
        {
          "key": "JOH-1988",
          "title": "Statistical Analysis of Cointegration Vectors",
          "author": "Søren Johansen",
          "url": "https://doi.org/10.1016/0165-1889(88)90041-3"
        },
        {
          "key": "Publication boundary",
          "title": "Publication boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/multivariate-systems/impulse-response-analysis/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/multivariate-systems/impulse-response-analysis/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F03-A05",
      "name": "Forecast-Error Variance Decomposition",
      "headline": null,
      "slug": "forecast-error-variance-decomposition",
      "path": "statistical-time-series/multivariate-systems/forecast-error-variance-decomposition",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F03",
        "family": "Multivariate Systems",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/multivariate-systems/forecast-error-variance-decomposition",
        "entry": "forecastErrorVarianceDecomposition",
        "params": [
          "coefficients",
          "sigmaU",
          "horizon"
        ],
        "exports": [
          "companionMatrix",
          "companionSpectralRadius",
          "fitVAR",
          "choleskyLower",
          "fitRecursiveSVAR",
          "fitVECMFixedBeta",
          "movingAverageMatrices",
          "impulseResponses",
          "forecastErrorVarianceDecomposition"
        ],
        "archetype": "record-transform",
        "signature": "forecastErrorVarianceDecomposition(coefficients, sigmaU, horizon)"
      },
      "api": {
        "summary": "Attributes each variable's forecast error variance to the structural shocks, by horizon. Answers 'how much of the movement in this variable is explained by that one' — subject, again, to the identification.",
        "params": [
          {
            "name": "coefficients",
            "type": "number[][]",
            "required": true,
            "description": "VAR coefficient matrices.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "sigmaU",
            "type": "number[][]",
            "required": true,
            "description": "Residual covariance matrix.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "horizon",
            "type": "number",
            "required": true,
            "description": "Periods to decompose.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ shares, impact_matrix, horizon, row_sums, companion_spectral_radius, stability_state, … }",
          "description": "Variance shares with `row_sums` — each row should sum to 1, and reporting it makes a broken decomposition obvious rather than plausible."
        },
        "warmup": null,
        "errors": [
          {
            "when": "sigmaU is not symmetric positive definite",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(horizon × k³)",
          "space": "O(horizon × k²)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "forecastErrorVarianceDecomposition([[[0.55,0.18],[-0.12,0.42]]], [[0.64,0.28],[0.28,0.425]], 8, [[0.8,0],[0.35,0.55]])",
        "args": [
          {
            "value": [
              [
                [
                  0.55,
                  0.18
                ],
                [
                  -0.12,
                  0.42
                ]
              ]
            ],
            "elided": null
          },
          {
            "value": [
              [
                0.64,
                0.28
              ],
              [
                0.28,
                0.425
              ]
            ],
            "elided": null
          },
          {
            "value": 8,
            "elided": null
          },
          {
            "value": [
              [
                0.8,
                0
              ],
              [
                0.35,
                0.55
              ]
            ],
            "elided": null
          }
        ],
        "output": {
          "shares": [
            [
              [
                1,
                0
              ],
              [
                0.288235294118,
                0.711764705882
              ]
            ],
            [
              [
                0.989143895172,
                0.010856104828
              ],
              [
                0.260105787983,
                0.739894212017
              ]
            ],
            [
              [
                0.980857224422,
                0.019142775578
              ],
              [
                0.258546673098,
                0.741453326902
              ]
            ]
          ],
          "impact_matrix": [
            [
              0.8,
              0
            ],
            [
              0.35,
              0.55
            ]
          ],
          "horizon": 8,
          "row_sums": [
            [
              1,
              1
            ],
            [
              1,
              1
            ],
            [
              1,
              1
            ]
          ],
          "companion_spectral_radius": 0.502593274925,
          "stability_state": "stable",
          "stability_boundary": 1,
          "near_boundary_threshold": 0.9,
          "state": "computed",
          "reason": "orthogonalized-squared-response-share"
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: shares, impact_matrix, horizon, row_sums, companion_spectral_radius, stability_state, stability_boundary, near_boundary_threshold, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f03-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SM-VAR",
          "title": "statsmodels vector autoregression documentation",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/vector_ar.html"
        },
        {
          "key": "SM-TOPIC",
          "title": "statsmodels Forecast-Error Variance Decomposition API documentation",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/generated/statsmodels.tsa.vector_ar.var_model.VARResults.fevd.html"
        },
        {
          "key": "LANNE-NYBERG-2016",
          "title": "Generalized Forecast Error Variance Decomposition for Linear and Nonlinear Multivariate Models",
          "author": "Markku Lanne and Henri Nyberg",
          "url": "https://doi.org/10.1111/obes.12125"
        },
        {
          "key": "LUT-2005",
          "title": "New Introduction to Multiple Time Series Analysis",
          "author": "Helmut Lütkepohl",
          "url": "https://doi.org/10.1007/978-3-540-27752-1"
        },
        {
          "key": "SIMS-1980",
          "title": "Macroeconomics and Reality",
          "author": "Christopher A. Sims",
          "url": "https://doi.org/10.2307/1912017"
        },
        {
          "key": "JOH-1988",
          "title": "Statistical Analysis of Cointegration Vectors",
          "author": "Søren Johansen",
          "url": "https://doi.org/10.1016/0165-1889(88)90041-3"
        },
        {
          "key": "Publication boundary",
          "title": "Publication boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/multivariate-systems/forecast-error-variance-decomposition/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/multivariate-systems/forecast-error-variance-decomposition/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F04-A01",
      "name": "Kalman Filter",
      "headline": null,
      "slug": "kalman-filter",
      "path": "statistical-time-series/state-and-regime-models/kalman-filter",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F04",
        "family": "State and Regime Models",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/state-and-regime-models/kalman-filter",
        "entry": "runFilter",
        "params": [
          "observations",
          "config"
        ],
        "exports": [
          "runFilter"
        ],
        "archetype": "record-transform",
        "signature": "runFilter(observations, config)"
      },
      "api": {
        "summary": "Optimal recursive estimation of a hidden state from noisy observations in a linear Gaussian system. In markets the hidden state is often the thing you actually want — a fair value, a slowly moving beta — and the observation is a noisy proxy for it.",
        "params": [
          {
            "name": "observations",
            "type": "number[]",
            "required": true,
            "description": "Noisy observations in chronological order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ a: number; h: number; q: number; r: number; initial_mean: number; initial_variance: number }",
            "required": true,
            "description": "`a` is the state transition and `h` the observation mapping. `q` and `r` are the process and observation noise variances — their **ratio** is what determines how quickly the filter trusts new data, so scaling both changes nothing.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ index, predicted_mean, predicted_variance, innovation, kalman_gain, filtered_mean, filtered_variance }[]",
          "description": "Every intermediate per step, including the Kalman gain and the innovation. A filter that behaves oddly is diagnosed from the gain path, not from the output."
        },
        "warmup": null,
        "errors": [
          {
            "when": "r is not positive, or q or the initial variance is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D09-F04-A01.json",
        "call": "runFilter([0.1740371542,0.7180296431,0.0364260071], {\"a\":0.96,\"h\":1,\"q\":0.08,\"r\":0.64,\"initial_mean\":0,\"initial_variance\":2})",
        "args": [
          {
            "value": [
              0.1740371542,
              0.7180296431,
              0.0364260071
            ],
            "elided": null
          },
          {
            "value": {
              "a": 0.96,
              "h": 1,
              "q": 0.08,
              "r": 0.64,
              "initial_mean": 0,
              "initial_variance": 2
            },
            "elided": null
          }
        ],
        "output": {
          "2": {
            "index": 2,
            "predicted_mean": 0.376086443860437,
            "predicted_variance": 0.3451182399024169,
            "predicted_observation": 0.376086443860437,
            "innovation": -0.339660436760437,
            "innovation_variance": 0.985118239902417,
            "kalman_gain": 0.350331793609469,
            "filtered_mean": 0.25709259383197747,
            "filtered_variance": 0.22421234791006017
          }
        },
        "outputElided": null,
        "outputShape": "object with 1 field: 2"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "diagnostic-scorecard.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a01/static/diagnostic-scorecard.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a01/static/failure-boundary.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a01/static/family-handoff.svg"
          },
          {
            "file": "scenario-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a01/static/scenario-comparison.svg"
          },
          {
            "file": "state-update.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a01/static/state-update.svg"
          },
          {
            "file": "uncertainty-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a01/static/uncertainty-ledger.svg"
          }
        ],
        "mermaid": [
          {
            "file": "causal-update-flow.md",
            "caption": "Kalman Filter Causal Update Flow",
            "source": "flowchart LR\n    A[\"Filtered state at t-1\"] --> B[\"Predict state at t\"]\n    B --> C[\"Read observation available at t\"]\n    C --> D[\"Compute evidence or innovation\"]\n    D --> E[\"Normalize or gain-weight update\"]\n    E --> F[\"Filtered state at t\"]\n    F --> G[\"Publish diagnostics\"]\n    F --> A"
          }
        ]
      },
      "references": [
        {
          "key": "KALMAN1960",
          "title": "A New Approach to Linear Filtering and Prediction Problems",
          "author": "R. E. Kalman",
          "url": "https://doi.org/10.1115/1.3662552"
        },
        {
          "key": "WELCH2006",
          "title": "An Introduction to the Kalman Filter",
          "author": "Greg Welch and Gary Bishop",
          "url": "https://www.cs.unc.edu/~welch/media/pdf/kalman_intro.pdf"
        },
        {
          "key": "SARKKA2023",
          "title": "Bayesian Filtering and Smoothing",
          "author": "Simo Särkkä and Lennart Svensson",
          "url": "https://doi.org/10.1017/9781108917407"
        },
        {
          "key": "STATSMODELS_STATE",
          "title": "Time Series Analysis by State Space Methods",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/statespace.html"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/state-and-regime-models/kalman-filter/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/state-and-regime-models/kalman-filter/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F04-A02",
      "name": "Extended Kalman Filter",
      "headline": null,
      "slug": "extended-kalman-filter",
      "path": "statistical-time-series/state-and-regime-models/extended-kalman-filter",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F04",
        "family": "State and Regime Models",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/state-and-regime-models/extended-kalman-filter",
        "entry": "runFilter",
        "params": [
          "observations",
          "config"
        ],
        "exports": [
          "runFilter"
        ],
        "archetype": "record-transform",
        "signature": "runFilter(observations, config)"
      },
      "api": {
        "summary": "The Kalman filter for non-linear systems, linearised at each step. The approximation is local, so strong non-linearity can make it diverge — quietly, while still producing plausible-looking numbers.",
        "params": [
          {
            "name": "observations",
            "type": "number[]",
            "required": true,
            "description": "Noisy observations.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ a, b, c, q, r, initial_mean, initial_variance }",
            "required": true,
            "description": "`a`, `b` and `c` parameterise the non-linear transition and observation functions; `q` and `r` are the noise variances.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ …per-step estimates }[]",
          "description": "Per-step predicted and filtered estimates with the gain, as for the linear filter."
        },
        "warmup": null,
        "errors": [
          {
            "when": "r is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D09-F04-A02.json",
        "call": "runFilter([0.1740564489,0.7180957323,0.0365723689], {\"a\":0.9,\"b\":0.22,\"c\":0.04,\"q\":0.06,\"r\":0.49,\"initial_mean\":0,\"initial_variance\":1.5})",
        "args": [
          {
            "value": [
              0.1740564489,
              0.7180957323,
              0.0365723689
            ],
            "elided": null
          },
          {
            "value": {
              "a": 0.9,
              "b": 0.22,
              "c": 0.04,
              "q": 0.06,
              "r": 0.49,
              "initial_mean": 0,
              "initial_variance": 1.5
            },
            "elided": null
          }
        ],
        "output": {
          "2": {
            "index": 2,
            "transition_jacobian": 1.0979025313193456,
            "measurement_jacobian": 1.040234775932769,
            "predicted_mean": 0.5029346991596126,
            "predicted_variance": 0.36799793432466277,
            "predicted_observation": 0.5130524316243634,
            "innovation": -0.47648006272436344,
            "innovation_variance": 0.8882062919307445,
            "kalman_gain": 0.4309857431023305,
            "filtered_mean": 0.2975785852529078,
            "filtered_variance": 0.20301476071185573
          }
        },
        "outputElided": null,
        "outputShape": "object with 1 field: 2"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "diagnostic-scorecard.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a02/static/diagnostic-scorecard.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a02/static/failure-boundary.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a02/static/family-handoff.svg"
          },
          {
            "file": "scenario-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a02/static/scenario-comparison.svg"
          },
          {
            "file": "state-update.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a02/static/state-update.svg"
          },
          {
            "file": "uncertainty-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a02/static/uncertainty-ledger.svg"
          }
        ],
        "mermaid": [
          {
            "file": "causal-update-flow.md",
            "caption": "Extended Kalman Filter Causal Update Flow",
            "source": "flowchart LR\n    A[\"Filtered state at t-1\"] --> B[\"Predict state at t\"]\n    B --> C[\"Read observation available at t\"]\n    C --> D[\"Compute evidence or innovation\"]\n    D --> E[\"Normalize or gain-weight update\"]\n    E --> F[\"Filtered state at t\"]\n    F --> G[\"Publish diagnostics\"]\n    F --> A"
          }
        ]
      },
      "references": [
        {
          "key": "WELCH2006",
          "title": "An Introduction to the Kalman Filter",
          "author": "Greg Welch and Gary Bishop",
          "url": "https://www.cs.unc.edu/~welch/media/pdf/kalman_intro.pdf"
        },
        {
          "key": "KALMAN1960",
          "title": "A New Approach to Linear Filtering and Prediction Problems",
          "author": "R. E. Kalman",
          "url": "https://doi.org/10.1115/1.3662552"
        },
        {
          "key": "SARKKA2023",
          "title": "Bayesian Filtering and Smoothing",
          "author": "Simo Särkkä and Lennart Svensson",
          "url": "https://doi.org/10.1017/9781108917407"
        },
        {
          "key": "STATSMODELS_STATE",
          "title": "Time Series Analysis by State Space Methods",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/statespace.html"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/state-and-regime-models/extended-kalman-filter/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/state-and-regime-models/extended-kalman-filter/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F04-A03",
      "name": "Unscented Kalman Filter",
      "headline": null,
      "slug": "unscented-kalman-filter",
      "path": "statistical-time-series/state-and-regime-models/unscented-kalman-filter",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F04",
        "family": "State and Regime Models",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/state-and-regime-models/unscented-kalman-filter",
        "entry": "runFilter",
        "params": [
          "observations",
          "config"
        ],
        "exports": [
          "runFilter"
        ],
        "archetype": "record-transform",
        "signature": "runFilter(observations, config)"
      },
      "api": {
        "summary": "Propagates a set of deterministically chosen sigma points through the non-linearity instead of linearising it. More robust than the extended filter for the same cost order, and the usual answer when the EKF diverges.",
        "params": [
          {
            "name": "observations",
            "type": "number[]",
            "required": true,
            "description": "Noisy observations.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ a, b, c, q, r, alpha, beta, kappa, initial_mean, initial_variance }",
            "required": true,
            "description": "`alpha`, `beta` and `kappa` control the sigma-point spread. `beta = 2` is optimal for Gaussian state distributions; `alpha` is normally small.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ …per-step estimates }[]",
          "description": "Per-step estimates with the sigma-point statistics behind them."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the sigma-point parameters produce a non-positive-definite covariance",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D09-F04-A03.json",
        "call": "runFilter([0.1740564489,0.7180957323,0.0365723689], {\"a\":0.9,\"b\":0.22,\"c\":0.04,\"q\":0.06,\"r\":0.49,\"alpha\":1,\"beta\":2,\"kappa\":0,\"initial_mean\":0,\"initial_variance\":1.5})",
        "args": [
          {
            "value": [
              0.1740564489,
              0.7180957323,
              0.0365723689
            ],
            "elided": null
          },
          {
            "value": {
              "a": 0.9,
              "b": 0.22,
              "c": 0.04,
              "q": 0.06,
              "r": 0.49,
              "alpha": 1,
              "beta": 2,
              "kappa": 0,
              "initial_mean": 0,
              "initial_variance": 1.5
            },
            "elided": null
          }
        ],
        "output": {
          "2": {
            "index": 2,
            "sigma_left": -0.0995315114397366,
            "sigma_center": 0.4049746384367636,
            "sigma_right": 0.9094807883132638,
            "predicted_mean": 0.4403571228780741,
            "predicted_variance": 0.36471237345744356,
            "predicted_measurement": 0.46270219364315,
            "innovation": -0.42612982474315003,
            "innovation_variance": 0.8812872395279235,
            "kalman_gain": 0.4284195343347881,
            "filtered_mean": 0.2577947817954489,
            "filtered_variance": 0.20295800755826507
          }
        },
        "outputElided": null,
        "outputShape": "object with 1 field: 2"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "diagnostic-scorecard.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a03/static/diagnostic-scorecard.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a03/static/failure-boundary.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a03/static/family-handoff.svg"
          },
          {
            "file": "scenario-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a03/static/scenario-comparison.svg"
          },
          {
            "file": "state-update.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a03/static/state-update.svg"
          },
          {
            "file": "uncertainty-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a03/static/uncertainty-ledger.svg"
          }
        ],
        "mermaid": [
          {
            "file": "causal-update-flow.md",
            "caption": "Unscented Kalman Filter Causal Update Flow",
            "source": "flowchart LR\n    A[\"Filtered state at t-1\"] --> B[\"Predict state at t\"]\n    B --> C[\"Read observation available at t\"]\n    C --> D[\"Compute evidence or innovation\"]\n    D --> E[\"Normalize or gain-weight update\"]\n    E --> F[\"Filtered state at t\"]\n    F --> G[\"Publish diagnostics\"]\n    F --> A"
          }
        ]
      },
      "references": [
        {
          "key": "JULIER2004",
          "title": "Unscented Filtering and Nonlinear Estimation",
          "author": "Simon J. Julier and Jeffrey K. Uhlmann",
          "url": "https://doi.org/10.1109/JPROC.2003.823141"
        },
        {
          "key": "SARKKA2023",
          "title": "Bayesian Filtering and Smoothing",
          "author": "Simo Särkkä and Lennart Svensson",
          "url": "https://doi.org/10.1017/9781108917407"
        },
        {
          "key": "KALMAN1960",
          "title": "A New Approach to Linear Filtering and Prediction Problems",
          "author": "R. E. Kalman",
          "url": "https://doi.org/10.1115/1.3662552"
        },
        {
          "key": "STATSMODELS_STATE",
          "title": "Time Series Analysis by State Space Methods",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/statespace.html"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/state-and-regime-models/unscented-kalman-filter/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/state-and-regime-models/unscented-kalman-filter/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F04-A04",
      "name": "Hidden Markov Model",
      "headline": null,
      "slug": "hidden-markov-model",
      "path": "statistical-time-series/state-and-regime-models/hidden-markov-model",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F04",
        "family": "State and Regime Models",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/state-and-regime-models/hidden-markov-model",
        "entry": "runFilter",
        "params": [
          "observations",
          "config"
        ],
        "exports": [
          "runFilter"
        ],
        "archetype": "record-transform",
        "signature": "runFilter(observations, config)"
      },
      "api": {
        "summary": "Infers a discrete hidden regime from observations. Where the Kalman filter tracks a continuous state, this asks which of a small number of *regimes* the market is in — and returns a probability rather than a label.",
        "params": [
          {
            "name": "observations",
            "type": "number[]",
            "required": true,
            "description": "Observations in chronological order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ transition: number[][]; means: number[]; stds: number[]; initial: number[] }",
            "required": true,
            "description": "`transition` holds the regime switching probabilities, each row summing to 1. `means` and `stds` are the emission parameters per regime. Regime **order is arbitrary** — label switching means 'regime 0' has no intrinsic meaning across fits.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ …per-step filtered probabilities }[]",
          "description": "Filtered regime probabilities per observation. Probabilities, not a hard classification: a 55/45 split is a genuinely uncertain moment and rounding it to a label discards that."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a transition row does not sum to 1, or a standard deviation is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × states²)",
          "space": "O(n × states)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D09-F04-A04.json",
        "call": "runFilter([-0.9183368993,-0.5364890278,-0.550167602], {\"transition\":[[0.94,0.06],[0.12,0.88]],\"means\":[-0.15,0.25],\"stds\":[0.55,1.45],\"initial\":[0.8,0.2]})",
        "args": [
          {
            "value": [
              -0.9183368993,
              -0.5364890278,
              -0.550167602
            ],
            "elided": null
          },
          {
            "value": {
              "transition": [
                [
                  0.94,
                  0.06
                ],
                [
                  0.12,
                  0.88
                ]
              ],
              "means": [
                -0.15,
                0.25
              ],
              "stds": [
                0.55,
                1.45
              ],
              "initial": [
                0.8,
                0.2
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "2": {
            "index": 2,
            "predicted_state_0": 0.8612154040743613,
            "predicted_state_1": 0.13878459592563866,
            "posterior_state_0": 0.9359801579550974,
            "posterior_state_1": 0.0640198420449025,
            "most_likely_state": 0,
            "log_predictive_density": -0.6690356366768324
          }
        },
        "outputElided": null,
        "outputShape": "object with 1 field: 2"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "diagnostic-scorecard.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a04/static/diagnostic-scorecard.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a04/static/failure-boundary.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a04/static/family-handoff.svg"
          },
          {
            "file": "scenario-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a04/static/scenario-comparison.svg"
          },
          {
            "file": "state-update.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a04/static/state-update.svg"
          },
          {
            "file": "uncertainty-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a04/static/uncertainty-ledger.svg"
          }
        ],
        "mermaid": [
          {
            "file": "causal-update-flow.md",
            "caption": "Hidden Markov Model Causal Update Flow",
            "source": "flowchart LR\n    A[\"Filtered state at t-1\"] --> B[\"Predict state at t\"]\n    B --> C[\"Read observation available at t\"]\n    C --> D[\"Compute evidence or innovation\"]\n    D --> E[\"Normalize or gain-weight update\"]\n    E --> F[\"Filtered state at t\"]\n    F --> G[\"Publish diagnostics\"]\n    F --> A"
          }
        ]
      },
      "references": [
        {
          "key": "RABINER1989",
          "title": "A Tutorial on Hidden Markov Models and Selected Applications in Speech Recognition",
          "author": "Lawrence R. Rabiner",
          "url": "https://doi.org/10.1109/5.18626"
        },
        {
          "key": "GNEITING2007",
          "title": "Strictly Proper Scoring Rules, Prediction, and Estimation",
          "author": "Tilmann Gneiting and Adrian E. Raftery",
          "url": "https://doi.org/10.1198/016214506000001437"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/state-and-regime-models/hidden-markov-model/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/state-and-regime-models/hidden-markov-model/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F04-A05",
      "name": "Markov-Switching Autoregression",
      "headline": null,
      "slug": "markov-switching-autoregression",
      "path": "statistical-time-series/state-and-regime-models/markov-switching-autoregression",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F04",
        "family": "State and Regime Models",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/state-and-regime-models/markov-switching-autoregression",
        "entry": "runFilter",
        "params": [
          "observations",
          "config"
        ],
        "exports": [
          "runFilter"
        ],
        "archetype": "record-transform",
        "signature": "runFilter(observations, config)"
      },
      "api": {
        "summary": "An autoregression whose coefficients switch with a hidden regime. Captures the common situation where a series is persistent in calm conditions and mean-reverting in stressed ones — one AR fit across both describes neither.",
        "params": [
          {
            "name": "observations",
            "type": "number[]",
            "required": true,
            "description": "Observations in chronological order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ transition: number[][]; intercepts: number[]; phis: number[]; stds: number[]; initial: number[] }",
            "required": true,
            "description": "One intercept, AR coefficient and standard deviation per regime, plus the transition matrix.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ …per-step filtered probabilities and predictions }[]",
          "description": "Regime probabilities alongside the regime-weighted prediction at each step."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the parameter arrays differ in length from the number of regimes",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × states²)",
          "space": "O(n × states)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D09-F04-A05.json",
        "call": "runFilter([-0.0710447869,0.2119198541,0.4036856432], {\"transition\":[[0.95,0.05],[0.1,0.9]],\"intercepts\":[0.12,-0.18],\"phis\":[0.72,-0.3],\"stds\":[0.35,1.05],\"initial\":[0.85,0.15]})",
        "args": [
          {
            "value": [
              -0.0710447869,
              0.2119198541,
              0.4036856432
            ],
            "elided": null
          },
          {
            "value": {
              "transition": [
                [
                  0.95,
                  0.05
                ],
                [
                  0.1,
                  0.9
                ]
              ],
              "intercepts": [
                0.12,
                -0.18
              ],
              "phis": [
                0.72,
                -0.3
              ],
              "stds": [
                0.35,
                1.05
              ],
              "initial": [
                0.85,
                0.15
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "2": {
            "index": 2,
            "regime_0_forecast": 0.272582294952,
            "regime_1_forecast": -0.24357595623,
            "predicted_state_0": 0.8867587273436667,
            "predicted_state_1": 0.11324127265633334,
            "posterior_state_0": 0.9636140438968227,
            "posterior_state_1": 0.03638595610317732,
            "most_likely_state": 0,
            "next_mixture_forecast": 0.3530523573178951,
            "log_predictive_density": -0.022389779102029245
          }
        },
        "outputElided": null,
        "outputShape": "object with 1 field: 2"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "diagnostic-scorecard.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a05/static/diagnostic-scorecard.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a05/static/failure-boundary.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a05/static/family-handoff.svg"
          },
          {
            "file": "scenario-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a05/static/scenario-comparison.svg"
          },
          {
            "file": "state-update.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a05/static/state-update.svg"
          },
          {
            "file": "uncertainty-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a05/static/uncertainty-ledger.svg"
          }
        ],
        "mermaid": [
          {
            "file": "causal-update-flow.md",
            "caption": "Markov-Switching Autoregression Causal Update Flow",
            "source": "flowchart LR\n    A[\"Filtered state at t-1\"] --> B[\"Predict state at t\"]\n    B --> C[\"Read observation available at t\"]\n    C --> D[\"Compute evidence or innovation\"]\n    D --> E[\"Normalize or gain-weight update\"]\n    E --> F[\"Filtered state at t\"]\n    F --> G[\"Publish diagnostics\"]\n    F --> A"
          }
        ]
      },
      "references": [
        {
          "key": "HAMILTON1989",
          "title": "A New Approach to the Economic Analysis of Nonstationary Time Series and the Business Cycle",
          "author": "James D. Hamilton",
          "url": "https://doi.org/10.2307/1912559"
        },
        {
          "key": "STATSMODELS_MSAR",
          "title": "MarkovAutoregression",
          "author": "statsmodels developers",
          "url": "https://www.statsmodels.org/stable/generated/statsmodels.tsa.regime_switching.markov_autoregression.MarkovAutoregression.html"
        },
        {
          "key": "GNEITING2007",
          "title": "Strictly Proper Scoring Rules, Prediction, and Estimation",
          "author": "Tilmann Gneiting and Adrian E. Raftery",
          "url": "https://doi.org/10.1198/016214506000001437"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/state-and-regime-models/markov-switching-autoregression/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/state-and-regime-models/markov-switching-autoregression/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F04-A06",
      "name": "Bayesian Change-Point Detection",
      "headline": null,
      "slug": "bayesian-change-point-detection",
      "path": "statistical-time-series/state-and-regime-models/bayesian-change-point-detection",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F04",
        "family": "State and Regime Models",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/state-and-regime-models/bayesian-change-point-detection",
        "entry": "runFilter",
        "params": [
          "observations",
          "config"
        ],
        "exports": [
          "runFilter"
        ],
        "archetype": "record-transform",
        "signature": "runFilter(observations, config)"
      },
      "api": {
        "summary": "Online detection of structural breaks by tracking the posterior over run length — how long since the last change. Unlike a regime model it does not need the number of regimes specified in advance.",
        "params": [
          {
            "name": "observations",
            "type": "number[]",
            "required": true,
            "description": "Observations in chronological order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "{ hazard: number; observation_variance: number; prior_mean: number; prior_variance: number }",
            "required": true,
            "description": "`hazard` is the prior probability of a change at any step — its reciprocal is the expected run length, which is the more intuitive way to set it. The priors describe beliefs about a segment's mean before seeing data.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ …per-step run-length posterior }[]",
          "description": "The run-length distribution per observation. Being online, an apparent change point can be revised by later data — the posterior shows that, a hard list of breaks would not."
        },
        "warmup": null,
        "errors": [
          {
            "when": "hazard falls outside 0…1, or a variance is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n²)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "fixture",
        "verified": true,
        "source": "fixture:D09-F04-A06.json",
        "call": "runFilter([-0.3275053489,0.2452664583,0.224748597], {\"hazard\":0.025,\"observation_variance\":0.36,\"prior_mean\":0,\"prior_variance\":4})",
        "args": [
          {
            "value": [
              -0.3275053489,
              0.2452664583,
              0.224748597
            ],
            "elided": null
          },
          {
            "value": {
              "hazard": 0.025,
              "observation_variance": 0.36,
              "prior_mean": 0,
              "prior_variance": 4
            },
            "elided": null
          }
        ],
        "output": {
          "2": {
            "index": 2,
            "change_probability": 0.00942784148480789,
            "map_run_length": 3,
            "expected_run_length": 2.9241612404581354,
            "active_hypotheses": 4,
            "map_mean": 0.04611964608414239,
            "log_predictive_density": -0.6857585614486436
          }
        },
        "outputElided": null,
        "outputShape": "object with 1 field: 2"
      },
      "verification": {
        "tier": "verified",
        "via": "input-expected"
      },
      "assets": {
        "diagrams": [
          {
            "file": "diagnostic-scorecard.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a06/static/diagnostic-scorecard.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a06/static/failure-boundary.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a06/static/family-handoff.svg"
          },
          {
            "file": "scenario-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a06/static/scenario-comparison.svg"
          },
          {
            "file": "state-update.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a06/static/state-update.svg"
          },
          {
            "file": "uncertainty-ledger.svg",
            "url": "https://thefintechbuilder.com/content/d09-f04-a06/static/uncertainty-ledger.svg"
          }
        ],
        "mermaid": [
          {
            "file": "causal-update-flow.md",
            "caption": "Bayesian Change-Point Detection Causal Update Flow",
            "source": "flowchart LR\n    A[\"Filtered state at t-1\"] --> B[\"Predict state at t\"]\n    B --> C[\"Read observation available at t\"]\n    C --> D[\"Compute evidence or innovation\"]\n    D --> E[\"Normalize or gain-weight update\"]\n    E --> F[\"Filtered state at t\"]\n    F --> G[\"Publish diagnostics\"]\n    F --> A"
          }
        ]
      },
      "references": [
        {
          "key": "ADAMS2007",
          "title": "Bayesian Online Changepoint Detection",
          "author": "Ryan Prescott Adams and David J. C. MacKay",
          "url": "https://arxiv.org/abs/0710.3742"
        },
        {
          "key": "GNEITING2007",
          "title": "Strictly Proper Scoring Rules, Prediction, and Estimation",
          "author": "Tilmann Gneiting and Adrian E. Raftery",
          "url": "https://doi.org/10.1198/016214506000001437"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/state-and-regime-models/bayesian-change-point-detection/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/state-and-regime-models/bayesian-change-point-detection/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F05-A01",
      "name": "STL Decomposition",
      "headline": null,
      "slug": "stl-decomposition",
      "path": "statistical-time-series/decomposition-and-cycles/stl-decomposition",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F05",
        "family": "Decomposition and Cycles",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/decomposition-and-cycles/stl-decomposition",
        "entry": "stlDecompose",
        "params": [
          "values",
          "period",
          "seasonalWindow",
          "trendWindow",
          "robustIterations"
        ],
        "exports": [
          "stlDecompose",
          "hpFilter",
          "bkFilter",
          "cfFilter",
          "fftPeriodogram",
          "haarWavelet",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "stlDecompose(values, period, seasonalWindow, trendWindow, robustIterations)"
      },
      "api": {
        "summary": "Seasonal-trend decomposition by loess: splits a series into seasonal, trend and remainder. Unlike a fixed seasonal index it lets the seasonal shape evolve, which is why it survives series where the pattern drifts.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "period",
            "type": "number",
            "required": true,
            "description": "Seasonal period — 12 for monthly, 5 for a trading week.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "seasonalWindow",
            "type": "number",
            "required": true,
            "description": "Loess span for the seasonal component. Larger holds the seasonal shape more constant across cycles.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "trendWindow",
            "type": "number",
            "required": true,
            "description": "Loess span for the trend.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "robustIterations",
            "type": "number",
            "required": true,
            "description": "Robustness passes that downweight outliers. Zero gives the non-robust fit.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ seasonal, trend, remainder, … }",
          "description": "The three components, which sum back to the original series."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the series is shorter than two full periods",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × window × iterations)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "stlDecompose([100.0901805654,101.3367333472,102.4083163971,102.9128416721,103.198587938,102.4311805579], 12, 7, 19, 2)",
        "args": [
          {
            "value": [
              100.0901805654,
              101.3367333472,
              102.4083163971,
              102.9128416721,
              103.198587938,
              102.4311805579
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 192
            }
          },
          {
            "value": 12,
            "elided": null
          },
          {
            "value": 7,
            "elided": null
          },
          {
            "value": 19,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          }
        ],
        "output": {
          "observed": [
            100.0901805654,
            101.3367333472,
            102.4083163971,
            102.9128416721,
            103.198587938,
            102.4311805579
          ],
          "trend": [
            101.80653184631831,
            101.74335719017421,
            101.68290299767973,
            101.62622211934938,
            101.5743610938178,
            101.52818917545937
          ],
          "seasonal": [
            -1.675059270552302,
            -0.37793707310334934,
            0.5876119710645483,
            1.128755113942449,
            1.414763613255315,
            0.6984276428857473
          ],
          "residual": [
            -0.041292010366001275,
            -0.028686769870863493,
            0.13780142835571352,
            0.15786443880817314,
            0.20946323092688846,
            0.20456373955488483
          ],
          "robust_weights": [
            0.9997399824592482,
            0.9998384208965301,
            0.9966750447871305,
            0.9957359792237003,
            0.9926684141414982,
            0.9930448769484919
          ],
          "period": 12,
          "seasonal_window": 7,
          "trend_window": 19,
          "robust_iterations": 2,
          "reconstruction_max_error": 0
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: observed, trend, seasonal, residual, robust_weights, period, seasonal_window, trend_window, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "decomposition-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a01/static/decomposition-map.svg"
          },
          {
            "file": "endpoint-risk.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a01/static/endpoint-risk.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a01/static/family-handoff.svg"
          },
          {
            "file": "parameter-effect.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a01/static/parameter-effect.svg"
          },
          {
            "file": "scenario-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a01/static/scenario-comparison.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Evidence table",
          "title": "Evidence table",
          "author": null,
          "url": null
        },
        {
          "key": "Source records",
          "title": "Source records",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence policy",
          "title": "Evidence policy",
          "author": null,
          "url": null
        },
        {
          "key": "Version notes",
          "title": "Version notes",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/decomposition-and-cycles/stl-decomposition/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/decomposition-and-cycles/stl-decomposition/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F05-A02",
      "name": "Hodrick-Prescott Filter",
      "headline": null,
      "slug": "hodrick-prescott-filter",
      "path": "statistical-time-series/decomposition-and-cycles/hodrick-prescott-filter",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F05",
        "family": "Decomposition and Cycles",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/decomposition-and-cycles/hodrick-prescott-filter",
        "entry": "hpFilter",
        "params": [
          "values",
          "smoothing"
        ],
        "exports": [
          "stlDecompose",
          "hpFilter",
          "bkFilter",
          "cfFilter",
          "fftPeriodogram",
          "haarWavelet",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "hpFilter(values, smoothing)"
      },
      "api": {
        "summary": "Separates trend from cycle by penalising trend curvature. Ubiquitous in macro and heavily criticised: it produces spurious cycles at the ends of the sample, so the most recent values — the ones you care about — are the least reliable.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "smoothing",
            "type": "number",
            "required": true,
            "description": "The λ penalty. Convention is 1600 for quarterly, 129600 for monthly — the choice largely determines the answer.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ trend, cycle }",
          "description": "Trend and cycle components summing to the input."
        },
        "warmup": null,
        "errors": [
          {
            "when": "smoothing is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "hpFilter([100.0901805654,101.3367333472,102.4083163971,102.9128416721,103.198587938,102.4311805579], 1600)",
        "args": [
          {
            "value": [
              100.0901805654,
              101.3367333472,
              102.4083163971,
              102.9128416721,
              103.198587938,
              102.4311805579
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 192
            }
          },
          {
            "value": 1600,
            "elided": null
          }
        ],
        "output": {
          "trend": [
            101.84532271785126,
            101.7763438481692,
            101.70626801464202,
            101.63372349686104,
            101.55777735465698,
            101.47829609671997
          ],
          "cycle": [
            -1.7551421524512563,
            -0.4396105009692093,
            0.7020483824579742,
            1.2791181752389633,
            1.6408105833430255,
            0.9528844611800338
          ],
          "lambda": 1600,
          "iterations": 637,
          "normal_equation_residual": 5.744738005865808e-10,
          "reconstruction_max_error": 0
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: trend, cycle, lambda, iterations, normal_equation_residual, reconstruction_max_error"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "decomposition-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a02/static/decomposition-map.svg"
          },
          {
            "file": "endpoint-risk.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a02/static/endpoint-risk.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a02/static/family-handoff.svg"
          },
          {
            "file": "parameter-effect.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a02/static/parameter-effect.svg"
          },
          {
            "file": "scenario-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a02/static/scenario-comparison.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Evidence table",
          "title": "Evidence table",
          "author": null,
          "url": null
        },
        {
          "key": "Source records",
          "title": "Source records",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence policy",
          "title": "Evidence policy",
          "author": null,
          "url": null
        },
        {
          "key": "Version notes",
          "title": "Version notes",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/decomposition-and-cycles/hodrick-prescott-filter/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/decomposition-and-cycles/hodrick-prescott-filter/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F05-A03",
      "name": "Baxter-King Filter",
      "headline": null,
      "slug": "baxter-king-filter",
      "path": "statistical-time-series/decomposition-and-cycles/baxter-king-filter",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F05",
        "family": "Decomposition and Cycles",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/decomposition-and-cycles/baxter-king-filter",
        "entry": "bkFilter",
        "params": [
          "values",
          "low",
          "high",
          "K"
        ],
        "exports": [
          "stlDecompose",
          "hpFilter",
          "bkFilter",
          "cfFilter",
          "fftPeriodogram",
          "haarWavelet",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "bkFilter(values, low, high, K)"
      },
      "api": {
        "summary": "A band-pass filter isolating fluctuations between two periodicities. Being a symmetric moving average it consumes K observations at **each** end, so the filtered series is shorter than the input at both.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number",
            "required": true,
            "description": "Shortest cycle length to retain, in periods.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "high",
            "type": "number",
            "required": true,
            "description": "Longest cycle length to retain.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "K",
            "type": "number",
            "required": true,
            "description": "Filter half-length. Larger sharpens the band and costs more observations at each end.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ cycle, weights, trimmed }",
          "description": "The band-passed series with the weights used and how many observations were trimmed from each end."
        },
        "warmup": null,
        "errors": [
          {
            "when": "low ≥ high, or the series is shorter than 2K + 1",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × K)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "bkFilter([100.0901805654,101.3367333472,102.4083163971,102.9128416721,103.198587938,102.4311805579], 6, 32, 12)",
        "args": [
          {
            "value": [
              100.0901805654,
              101.3367333472,
              102.4083163971,
              102.9128416721,
              103.198587938,
              102.4311805579
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 192
            }
          },
          {
            "value": 6,
            "elided": null
          },
          {
            "value": 32,
            "elided": null
          },
          {
            "value": 12,
            "elided": null
          }
        ],
        "output": {
          "cycle": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "trend": [
            null,
            null,
            null,
            null,
            null,
            null
          ],
          "weights": [
            -0.011925074099926311,
            -0.042289342849822956,
            -0.050142927835196305,
            -0.02785666762175208,
            0.0015008360109016001,
            0.0016130582107286165
          ],
          "low_period": 6,
          "high_period": 32,
          "K": 12,
          "edge_loss_each_side": 12,
          "weight_sum": 9.71445146547012e-17
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: cycle, trend, weights, low_period, high_period, K, edge_loss_each_side, weight_sum"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "decomposition-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a03/static/decomposition-map.svg"
          },
          {
            "file": "endpoint-risk.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a03/static/endpoint-risk.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a03/static/family-handoff.svg"
          },
          {
            "file": "parameter-effect.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a03/static/parameter-effect.svg"
          },
          {
            "file": "scenario-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a03/static/scenario-comparison.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Evidence table",
          "title": "Evidence table",
          "author": null,
          "url": null
        },
        {
          "key": "Source records",
          "title": "Source records",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence policy",
          "title": "Evidence policy",
          "author": null,
          "url": null
        },
        {
          "key": "Version notes",
          "title": "Version notes",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/decomposition-and-cycles/baxter-king-filter/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/decomposition-and-cycles/baxter-king-filter/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F05-A04",
      "name": "Christiano-Fitzgerald Filter",
      "headline": null,
      "slug": "christiano-fitzgerald-filter",
      "path": "statistical-time-series/decomposition-and-cycles/christiano-fitzgerald-filter",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F05",
        "family": "Decomposition and Cycles",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/decomposition-and-cycles/christiano-fitzgerald-filter",
        "entry": "cfFilter",
        "params": [
          "values",
          "low",
          "high",
          "drift"
        ],
        "exports": [
          "stlDecompose",
          "hpFilter",
          "bkFilter",
          "cfFilter",
          "fftPeriodogram",
          "haarWavelet",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "cfFilter(values, low, high, drift)"
      },
      "api": {
        "summary": "An asymmetric band-pass filter that uses the whole sample, so unlike Baxter-King it produces values at the ends. The trade is that the filter weights differ at each observation, which makes it non-stationary by construction.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number",
            "required": true,
            "description": "Shortest cycle length to retain.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "high",
            "type": "number",
            "required": true,
            "description": "Longest cycle length to retain.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "drift",
            "type": "boolean",
            "required": false,
            "description": "Whether to remove a linear drift before filtering.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ cycle, trend }",
          "description": "The cycle component over the full sample length."
        },
        "warmup": null,
        "errors": [
          {
            "when": "low ≥ high",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n²)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "cfFilter([100.0901805654,101.3367333472,102.4083163971,102.9128416721,103.198587938,102.4311805579], 6, 32, true)",
        "args": [
          {
            "value": [
              100.0901805654,
              101.3367333472,
              102.4083163971,
              102.9128416721,
              103.198587938,
              102.4311805579
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 192
            }
          },
          {
            "value": 6,
            "elided": null
          },
          {
            "value": 32,
            "elided": null
          },
          {
            "value": true,
            "elided": null
          }
        ],
        "output": {
          "cycle": [
            -0.9710232193903039,
            -0.24888106131204424,
            0.6369705111805075,
            1.3312619134532966,
            1.5158058129594352,
            1.0859129088320714
          ],
          "trend": [
            101.06120378479031,
            101.58561440851204,
            101.77134588591949,
            101.58157975864671,
            101.68278212504057,
            101.34526764906794
          ],
          "drift_line": [
            0,
            0.03320258794921465,
            0.0664051758984293,
            0.09960776384764396,
            0.1328103517968586,
            0.16601293974607326
          ],
          "low_period": 6,
          "high_period": 32,
          "drift_removed_before_filtering": true,
          "reconstruction_max_error": 7.105427357601002e-15
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: cycle, trend, drift_line, low_period, high_period, drift_removed_before_filtering, reconstruction_max_error"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "decomposition-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a04/static/decomposition-map.svg"
          },
          {
            "file": "endpoint-risk.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a04/static/endpoint-risk.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a04/static/family-handoff.svg"
          },
          {
            "file": "parameter-effect.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a04/static/parameter-effect.svg"
          },
          {
            "file": "scenario-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a04/static/scenario-comparison.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Evidence table",
          "title": "Evidence table",
          "author": null,
          "url": null
        },
        {
          "key": "Source records",
          "title": "Source records",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence policy",
          "title": "Evidence policy",
          "author": null,
          "url": null
        },
        {
          "key": "Version notes",
          "title": "Version notes",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/decomposition-and-cycles/christiano-fitzgerald-filter/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/decomposition-and-cycles/christiano-fitzgerald-filter/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F05-A05",
      "name": "Fast Fourier Transform Periodogram",
      "headline": null,
      "slug": "fast-fourier-transform-periodogram",
      "path": "statistical-time-series/decomposition-and-cycles/fast-fourier-transform-periodogram",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F05",
        "family": "Decomposition and Cycles",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/decomposition-and-cycles/fast-fourier-transform-periodogram",
        "entry": "fftPeriodogram",
        "params": [
          "values",
          "sampleFrequency",
          "detrend",
          "window"
        ],
        "exports": [
          "stlDecompose",
          "hpFilter",
          "bkFilter",
          "cfFilter",
          "fftPeriodogram",
          "haarWavelet",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "fftPeriodogram(values, sampleFrequency, detrend, window)"
      },
      "api": {
        "summary": "Estimates spectral power by frequency. Peaks suggest periodicity — but a trend leaks power across every frequency, which is why detrending is a parameter here rather than an afterthought.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "sampleFrequency",
            "type": "number",
            "required": true,
            "description": "Observations per unit time, which sets the units of the returned frequencies.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "detrend",
            "type": "boolean",
            "required": true,
            "description": "Remove a linear trend before transforming. Leaving a trend in produces a spurious peak at the lowest frequency.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "window",
            "type": "string",
            "required": true,
            "description": "Taper applied before the transform, reducing spectral leakage at the cost of resolution.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ frequencies, power, dominant_frequency, … }",
          "description": "Power per frequency with the dominant one identified."
        },
        "warmup": null,
        "errors": [
          {
            "when": "sampleFrequency is not positive, or the window is unrecognised",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n log n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "fftPeriodogram([100.0901805654,101.3367333472,102.4083163971,102.9128416721,103.198587938,102.4311805579], 1, \"linear\", \"boxcar\")",
        "args": [
          {
            "value": [
              100.0901805654,
              101.3367333472,
              102.4083163971,
              102.9128416721,
              103.198587938,
              102.4311805579
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 192
            }
          },
          {
            "value": 1,
            "elided": null
          },
          {
            "value": "linear",
            "elided": null
          },
          {
            "value": "boxcar",
            "elided": null
          }
        ],
        "output": {
          "frequency": [
            0,
            0.00390625,
            0.0078125,
            0.01171875,
            0.015625,
            0.01953125
          ],
          "power_density": [
            1.0488462970643929e-25,
            1.6358893918182345,
            4.265767680939771,
            5.308886555246375,
            0.7314454315603167,
            3.8642684877953584
          ],
          "nfft": 256,
          "sample_frequency": 1,
          "window": "boxcar",
          "detrend": "linear",
          "removed_mean": 103.83348592556456,
          "removed_slope_per_observation": 0.03635627769934048,
          "dominant_index": 21,
          "dominant_frequency": 0.08203125,
          "dominant_period": 12.19047619047619,
          "peak_power_share": 0.4300600995492311
        },
        "outputElided": null,
        "outputShape": "object with 12 fields: frequency, power_density, nfft, sample_frequency, window, detrend, removed_mean, removed_slope_per_observation, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "decomposition-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a05/static/decomposition-map.svg"
          },
          {
            "file": "endpoint-risk.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a05/static/endpoint-risk.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a05/static/family-handoff.svg"
          },
          {
            "file": "parameter-effect.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a05/static/parameter-effect.svg"
          },
          {
            "file": "scenario-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a05/static/scenario-comparison.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Evidence table",
          "title": "Evidence table",
          "author": null,
          "url": null
        },
        {
          "key": "Source records",
          "title": "Source records",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence policy",
          "title": "Evidence policy",
          "author": null,
          "url": null
        },
        {
          "key": "Version notes",
          "title": "Version notes",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/decomposition-and-cycles/fast-fourier-transform-periodogram/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/decomposition-and-cycles/fast-fourier-transform-periodogram/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D09-F05-A06",
      "name": "Wavelet Decomposition",
      "headline": null,
      "slug": "wavelet-decomposition",
      "path": "statistical-time-series/decomposition-and-cycles/wavelet-decomposition",
      "taxonomy": {
        "domainId": "D09",
        "domain": "Statistical Time Series",
        "familyId": "D09-F05",
        "family": "Decomposition and Cycles",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/statistical-time-series/decomposition-and-cycles/wavelet-decomposition",
        "entry": "haarWavelet",
        "params": [
          "values",
          "levels"
        ],
        "exports": [
          "stlDecompose",
          "hpFilter",
          "bkFilter",
          "cfFilter",
          "fftPeriodogram",
          "haarWavelet",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "haarWavelet(values, levels)"
      },
      "api": {
        "summary": "Haar wavelet decomposition: splits the series into detail at successive scales plus a residual approximation. Unlike Fourier it localises in *time* as well as frequency, so it can say when a frequency was present.",
        "params": [
          {
            "name": "values",
            "type": "number[]",
            "required": true,
            "description": "Observation series. Haar works on powers of two; a shorter series is padded.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "levels",
            "type": "number",
            "required": true,
            "description": "Number of decomposition levels. Each halves the resolution of the approximation.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ details, approximation, levels }",
          "description": "Detail coefficients per level plus the final approximation."
        },
        "warmup": null,
        "errors": [
          {
            "when": "levels exceeds what the series length supports",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "haarWavelet([100.0901805654,101.3367333472,102.4083163971,102.9128416721,103.198587938,102.4311805579], 4)",
        "args": [
          {
            "value": [
              100.0901805654,
              101.3367333472,
              102.4083163971,
              102.9128416721,
              103.198587938,
              102.4311805579
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 192
            }
          },
          {
            "value": 4,
            "elided": null
          }
        ],
        "output": {
          "approximation_coefficients": [
            406.2370710410249,
            400.6458644165249,
            408.18250013307494,
            406.58956430514996,
            415.4042925955248,
            408.8285391202
          ],
          "detail_coefficients": [
            [
              -0.8814459251177285,
              -0.35675324323251195,
              0.5426389624013097,
              0.7206078638433713,
              0.22202008434506101,
              -0.6488746408711917
            ],
            [
              -1.9471220782999858,
              1.5938553549500085,
              -0.32437943830000726,
              -0.7441778894000111,
              2.4193453339000146,
              -0.5144175941000312
            ],
            [
              -0.46801782111276313,
              -3.419692948980583,
              4.169455460606318,
              0.2223496978931099,
              -5.578639117285321,
              3.8376397376595466
            ]
          ],
          "approximation_component": [
            101.55926776025618,
            101.55926776025618,
            101.55926776025618,
            101.55926776025618,
            101.55926776025618,
            101.55926776025618
          ],
          "detail_components": [
            [
              -0.6232763908999955,
              0.6232763908999955,
              -0.252262637500003,
              0.252262637500003,
              0.38370369004999805,
              -0.38370369004999805
            ],
            [
              -0.9735610391499928,
              -0.9735610391499928,
              0.9735610391499928,
              0.9735610391499928,
              0.7969276774750041,
              0.7969276774750041
            ],
            [
              -0.16546928751249362,
              -0.16546928751249362,
              -0.16546928751249362,
              -0.16546928751249362,
              0.16546928751249362,
              0.16546928751249362
            ]
          ],
          "reconstructed": [
            100.09018056539995,
            101.33673334719994,
            102.40831639709995,
            102.91284167209994,
            103.19858793799993,
            102.43118055789995
          ],
          "levels": 4,
          "wavelet": "haar",
          "boundary_mode": "periodization",
          "approximation_energy_fraction": 0.999765090759817,
          "detail_energy_fractions": [
            0.000018209004639336907,
            0.00005361952217361794,
            0.0001317428663664597,
            0.00003133784700365802
          ],
          "reconstruction_max_error": 9.947598300641403e-14
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: approximation_coefficients, detail_coefficients, approximation_component, detail_components, reconstructed, levels, wavelet, boundary_mode, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "decomposition-map.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a06/static/decomposition-map.svg"
          },
          {
            "file": "endpoint-risk.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a06/static/endpoint-risk.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a06/static/family-handoff.svg"
          },
          {
            "file": "parameter-effect.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a06/static/parameter-effect.svg"
          },
          {
            "file": "scenario-comparison.svg",
            "url": "https://thefintechbuilder.com/content/d09-f05-a06/static/scenario-comparison.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Evidence table",
          "title": "Evidence table",
          "author": null,
          "url": null
        },
        {
          "key": "Source records",
          "title": "Source records",
          "author": null,
          "url": null
        },
        {
          "key": "Evidence policy",
          "title": "Evidence policy",
          "author": null,
          "url": null
        },
        {
          "key": "Version notes",
          "title": "Version notes",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/statistical-time-series/decomposition-and-cycles/wavelet-decomposition/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/statistical-time-series/decomposition-and-cycles/wavelet-decomposition/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F01-A01",
      "name": "Tick Test",
      "headline": null,
      "slug": "tick-test",
      "path": "market-microstructure/trade-classification/tick-test",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F01",
        "family": "Trade Classification",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/trade-classification/tick-test",
        "entry": "tickTest",
        "params": [
          "data",
          "config"
        ],
        "exports": [
          "tickTest",
          "quoteTest",
          "leeReady",
          "studentTCdf",
          "bulkVolumeClassification",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "tickTest(data, config)"
      },
      "api": {
        "summary": "Signs a trade buyer- or seller-initiated by comparing its price with the previous trade. The cheapest classifier and the least accurate — it needs no quote data, which is exactly why it is still used on historical tapes that have none.",
        "params": [
          {
            "name": "data",
            "type": "ClassificationInput",
            "required": true,
            "description": "Trades with prices, and where the rule needs them, the prevailing quotes.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "ClassificationConfig",
            "required": true,
            "description": "Tolerances and tie-breaking rules. Trades exactly at a quote or unchanged in price are the cases where classifiers differ, so the tie rule is part of the contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ classifications, summary, diagnostics }",
          "description": "Per-trade sign with the rule that produced it, plus counts of the unclassifiable cases. Tick test disagrees with its siblings on exactly those, and hiding them would hide the disagreement."
        },
        "warmup": null,
        "errors": [
          {
            "when": "required quote data is absent for a rule that needs it",
            "behaviour": "reported per trade rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "tickTest({\"trades\":[{\"id\":\"T001\",\"sequence\":1,\"session\":\"S1\",\"event_time_ms\":1000,\"available_time_ms\":1025,\"price\":100,\"size\":100,\"status\":\"valid\",\"condition\":\"regular\"},{\"id\":\"T002\",\"sequence\":2,\"session\":\"S1\",\"event_time_ms\":2000,\"available_time_ms\":2025,\"price\":100.01,\"size\":125,\"status\":\"valid\",\"condition\":\"regular\"},{\"id\":\"T003\",\"sequence\":3,\"session\":\"S1\",\"event_time_ms\":3000,\"available_time_ms\":3025,\"price\":100.01,\"size\":150,\"status\":\"valid\",\"condition\":\"regular\"}]}, {\"zero_tick_mode\":\"carry\",\"reset_on_session\":true})",
        "args": [
          {
            "value": {
              "trades": [
                {
                  "id": "T001",
                  "sequence": 1,
                  "session": "S1",
                  "event_time_ms": 1000,
                  "available_time_ms": 1025,
                  "price": 100,
                  "size": 100,
                  "status": "valid",
                  "condition": "regular"
                },
                {
                  "id": "T002",
                  "sequence": 2,
                  "session": "S1",
                  "event_time_ms": 2000,
                  "available_time_ms": 2025,
                  "price": 100.01,
                  "size": 125,
                  "status": "valid",
                  "condition": "regular"
                },
                {
                  "id": "T003",
                  "sequence": 3,
                  "session": "S1",
                  "event_time_ms": 3000,
                  "available_time_ms": 3025,
                  "price": 100.01,
                  "size": 150,
                  "status": "valid",
                  "condition": "regular"
                }
              ]
            },
            "elided": null
          },
          {
            "value": {
              "zero_tick_mode": "carry",
              "reset_on_session": true
            },
            "elided": null
          }
        ],
        "output": {
          "state": "ok",
          "method": "tick-test",
          "trace": [
            {
              "id": "T001",
              "sequence": 1,
              "event_time_ms": 1000,
              "price": 100,
              "volume": 100,
              "sign": 0,
              "side": "unknown",
              "reason": "no-prior-trade",
              "reference_price": null,
              "cumulative_signed_volume": 0
            },
            {
              "id": "T002",
              "sequence": 2,
              "event_time_ms": 2000,
              "price": 100.01,
              "volume": 125,
              "sign": 1,
              "side": "buy",
              "reason": "uptick",
              "reference_price": 100,
              "cumulative_signed_volume": 125
            },
            {
              "id": "T003",
              "sequence": 3,
              "event_time_ms": 3000,
              "price": 100.01,
              "volume": 150,
              "sign": 1,
              "side": "buy",
              "reason": "zero-uptick",
              "reference_price": 100.01,
              "cumulative_signed_volume": 275
            }
          ],
          "total_valid": 60,
          "classified_count": 58,
          "unknown_count": 2,
          "buy_count": 23,
          "sell_count": 35,
          "buy_volume": 3875,
          "sell_volume": 6200,
          "unknown_volume": 275,
          "signed_volume": -2325,
          "total_volume": 10350,
          "coverage": 0.9666666667
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 16
        },
        "outputShape": "object with 16 fields: state, method, trace, total_valid, classified_count, unknown_count, buy_count, sell_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a01/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a01/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a01/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a01/static/scenario-matrix.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a01/static/worked-example.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "LEE_READY",
          "title": "Inferring Trade Direction from Intraday Data",
          "author": "Charles M. C. Lee and Mark J. Ready",
          "url": "https://doi.org/10.1111/j.1540-6261.1991.tb02683.x"
        },
        {
          "key": "SEC_TICK",
          "title": "Short Sales: Rule 10a-1 Tick Test Discussion",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/rules-regulations/1999/10/short-sales"
        },
        {
          "key": "NASDAQ_ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHspecification.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/trade-classification/tick-test/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/trade-classification/tick-test/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F01-A02",
      "name": "Quote Test",
      "headline": null,
      "slug": "quote-test",
      "path": "market-microstructure/trade-classification/quote-test",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F01",
        "family": "Trade Classification",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/trade-classification/quote-test",
        "entry": "quoteTest",
        "params": [
          "data",
          "config"
        ],
        "exports": [
          "tickTest",
          "quoteTest",
          "leeReady",
          "studentTCdf",
          "bulkVolumeClassification",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "quoteTest(data, config)"
      },
      "api": {
        "summary": "Signs a trade by which side of the prevailing midpoint it executed on. More accurate than the tick test where quotes exist, and undefined for trades exactly at the midpoint — which is where the Lee-Ready hybrid earns its place.",
        "params": [
          {
            "name": "data",
            "type": "ClassificationInput",
            "required": true,
            "description": "Trades with prices, and where the rule needs them, the prevailing quotes.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "ClassificationConfig",
            "required": true,
            "description": "Tolerances and tie-breaking rules. Trades exactly at a quote or unchanged in price are the cases where classifiers differ, so the tie rule is part of the contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ classifications, summary, diagnostics }",
          "description": "Per-trade sign with the rule that produced it, plus counts of the unclassifiable cases. Quote test disagrees with its siblings on exactly those, and hiding them would hide the disagreement."
        },
        "warmup": null,
        "errors": [
          {
            "when": "required quote data is absent for a rule that needs it",
            "behaviour": "reported per trade rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "quoteTest({\"trades\":[{\"id\":\"T001\",\"sequence\":1,\"session\":\"S1\",\"event_time_ms\":1000,\"available_time_ms\":1025,\"price\":100.01,\"size\":100,\"status\":\"valid\",\"condition\":\"regular\"},{\"id\":\"T002\",\"sequence\":2,\"session\":\"S1\",\"event_time_ms\":2000,\"available_time_ms\":2025,\"price\":99.99,\"size\":125,\"status\":\"valid\",\"condition\":\"regular\"},{\"id\":\"T003\",\"sequence\":3,\"session\":\"S1\",\"event_time_ms\":3000,\"available_time_ms\":3025,\"price\":100,\"size\":150,\"status\":\"valid\",\"condition\":\"regular\"}],\"quotes\":[{\"id\":\"Q001\",\"sequence\":1,\"event_time_ms\":500,\"available_time_ms\":520,\"bid\":99.99,\"ask\":100.01,\"status\":\"valid\",\"source\":\"SYNTH-NBBO\"},{\"id\":\"Q002\",\"sequence\":2,\"event_time_ms\":1500,\"available_time_ms\":1520,\"bid\":99.99,\"ask\":100.01,\"status\":\"valid\",\"source\":\"SYNTH-NBBO\"},{\"id\":\"Q003\",\"sequence\":3,\"event_time_ms\":2500,\"available_time_ms\":2520,\"bid\":99.99,\"ask\":100.01,\"status\":\"valid\",\"source\":\"SYNTH-NBBO\"}]}, {\"quote_lag_ms\":0,\"midpoint_tolerance\":0})",
        "args": [
          {
            "value": {
              "trades": [
                {
                  "id": "T001",
                  "sequence": 1,
                  "session": "S1",
                  "event_time_ms": 1000,
                  "available_time_ms": 1025,
                  "price": 100.01,
                  "size": 100,
                  "status": "valid",
                  "condition": "regular"
                },
                {
                  "id": "T002",
                  "sequence": 2,
                  "session": "S1",
                  "event_time_ms": 2000,
                  "available_time_ms": 2025,
                  "price": 99.99,
                  "size": 125,
                  "status": "valid",
                  "condition": "regular"
                },
                {
                  "id": "T003",
                  "sequence": 3,
                  "session": "S1",
                  "event_time_ms": 3000,
                  "available_time_ms": 3025,
                  "price": 100,
                  "size": 150,
                  "status": "valid",
                  "condition": "regular"
                }
              ],
              "quotes": [
                {
                  "id": "Q001",
                  "sequence": 1,
                  "event_time_ms": 500,
                  "available_time_ms": 520,
                  "bid": 99.99,
                  "ask": 100.01,
                  "status": "valid",
                  "source": "SYNTH-NBBO"
                },
                {
                  "id": "Q002",
                  "sequence": 2,
                  "event_time_ms": 1500,
                  "available_time_ms": 1520,
                  "bid": 99.99,
                  "ask": 100.01,
                  "status": "valid",
                  "source": "SYNTH-NBBO"
                },
                {
                  "id": "Q003",
                  "sequence": 3,
                  "event_time_ms": 2500,
                  "available_time_ms": 2520,
                  "bid": 99.99,
                  "ask": 100.01,
                  "status": "valid",
                  "source": "SYNTH-NBBO"
                }
              ]
            },
            "elided": null
          },
          {
            "value": {
              "quote_lag_ms": 0,
              "midpoint_tolerance": 0
            },
            "elided": null
          }
        ],
        "output": {
          "state": "ok",
          "method": "quote-test",
          "trace": [
            {
              "id": "T001",
              "sequence": 1,
              "event_time_ms": 1000,
              "price": 100.01,
              "volume": 100,
              "sign": 1,
              "side": "buy",
              "reason": "above-midpoint",
              "midpoint": 100,
              "bid": 99.99,
              "ask": 100.01,
              "quote_id": "Q001",
              "cumulative_signed_volume": 100
            },
            {
              "id": "T002",
              "sequence": 2,
              "event_time_ms": 2000,
              "price": 99.99,
              "volume": 125,
              "sign": -1,
              "side": "sell",
              "reason": "below-midpoint",
              "midpoint": 100,
              "bid": 99.99,
              "ask": 100.01,
              "quote_id": "Q002",
              "cumulative_signed_volume": -25
            },
            {
              "id": "T003",
              "sequence": 3,
              "event_time_ms": 3000,
              "price": 100,
              "volume": 150,
              "sign": 0,
              "side": "unknown",
              "reason": "midpoint-or-tolerance-band",
              "midpoint": 100,
              "bid": 99.99,
              "ask": 100.01,
              "quote_id": "Q003",
              "cumulative_signed_volume": -25
            }
          ],
          "total_valid": 60,
          "classified_count": 55,
          "unknown_count": 5,
          "buy_count": 35,
          "sell_count": 20,
          "buy_volume": 5950,
          "sell_volume": 3425,
          "unknown_volume": 975,
          "signed_volume": 2525,
          "total_volume": 10350,
          "coverage": 0.9166666667
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 19
        },
        "outputShape": "object with 19 fields: state, method, trace, total_valid, classified_count, unknown_count, buy_count, sell_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a02/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a02/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a02/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a02/static/scenario-matrix.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a02/static/worked-example.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "LEE_READY",
          "title": "Inferring Trade Direction from Intraday Data",
          "author": "Charles M. C. Lee and Mark J. Ready",
          "url": "https://doi.org/10.1111/j.1540-6261.1991.tb02683.x"
        },
        {
          "key": "NYSE_TAQ",
          "title": "Daily TAQ Client Specification",
          "author": "NYSE / ICE Data Services",
          "url": "https://www.nyse.com/publicdocs/nyse/data/Daily_TAQ_Client_Spec_v3.0b.pdf"
        },
        {
          "key": "NASDAQ_ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHspecification.pdf"
        },
        {
          "key": "FAST_MARKETS",
          "title": "Liquidity Measurement Problems in Fast, Competitive Markets",
          "author": "Craig W. Holden and Stacey Jacobsen",
          "url": "https://doi.org/10.1111/jofi.12127"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/trade-classification/quote-test/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/trade-classification/quote-test/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F01-A03",
      "name": "Lee-Ready Trade Signing",
      "headline": null,
      "slug": "lee-ready-trade-signing",
      "path": "market-microstructure/trade-classification/lee-ready-trade-signing",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F01",
        "family": "Trade Classification",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/trade-classification/lee-ready-trade-signing",
        "entry": "leeReady",
        "params": [
          "data",
          "config"
        ],
        "exports": [
          "tickTest",
          "quoteTest",
          "leeReady",
          "studentTCdf",
          "bulkVolumeClassification",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "leeReady(data, config)"
      },
      "api": {
        "summary": "The standard hybrid: quote test where the trade is away from the midpoint, tick test at it. The classification most empirical microstructure results are built on, so reproducing them requires this rule specifically.",
        "params": [
          {
            "name": "data",
            "type": "ClassificationInput",
            "required": true,
            "description": "Trades with prices, and where the rule needs them, the prevailing quotes.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "ClassificationConfig",
            "required": true,
            "description": "Tolerances and tie-breaking rules. Trades exactly at a quote or unchanged in price are the cases where classifiers differ, so the tie rule is part of the contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ classifications, summary, diagnostics }",
          "description": "Per-trade sign with the rule that produced it, plus counts of the unclassifiable cases. Lee-Ready disagrees with its siblings on exactly those, and hiding them would hide the disagreement."
        },
        "warmup": null,
        "errors": [
          {
            "when": "required quote data is absent for a rule that needs it",
            "behaviour": "reported per trade rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "leeReady({\"trades\":[{\"id\":\"T001\",\"sequence\":1,\"session\":\"S1\",\"event_time_ms\":1000,\"available_time_ms\":1025,\"price\":100.01,\"size\":100,\"status\":\"valid\",\"condition\":\"regular\"},{\"id\":\"T002\",\"sequence\":2,\"session\":\"S1\",\"event_time_ms\":2000,\"available_time_ms\":2025,\"price\":99.99,\"size\":125,\"status\":\"valid\",\"condition\":\"regular\"},{\"id\":\"T003\",\"sequence\":3,\"session\":\"S1\",\"event_time_ms\":3000,\"available_time_ms\":3025,\"price\":100,\"size\":150,\"status\":\"valid\",\"condition\":\"regular\"}],\"quotes\":[{\"id\":\"Q001\",\"sequence\":1,\"event_time_ms\":500,\"available_time_ms\":520,\"bid\":99.99,\"ask\":100.01,\"status\":\"valid\",\"source\":\"SYNTH-NBBO\"},{\"id\":\"Q002\",\"sequence\":2,\"event_time_ms\":1500,\"available_time_ms\":1520,\"bid\":99.99,\"ask\":100.01,\"status\":\"valid\",\"source\":\"SYNTH-NBBO\"},{\"id\":\"Q003\",\"sequence\":3,\"event_time_ms\":2500,\"available_time_ms\":2520,\"bid\":99.99,\"ask\":100.01,\"status\":\"valid\",\"source\":\"SYNTH-NBBO\"}]}, {\"quote_lag_ms\":0,\"midpoint_tolerance\":0,\"zero_tick_mode\":\"carry\"})",
        "args": [
          {
            "value": {
              "trades": [
                {
                  "id": "T001",
                  "sequence": 1,
                  "session": "S1",
                  "event_time_ms": 1000,
                  "available_time_ms": 1025,
                  "price": 100.01,
                  "size": 100,
                  "status": "valid",
                  "condition": "regular"
                },
                {
                  "id": "T002",
                  "sequence": 2,
                  "session": "S1",
                  "event_time_ms": 2000,
                  "available_time_ms": 2025,
                  "price": 99.99,
                  "size": 125,
                  "status": "valid",
                  "condition": "regular"
                },
                {
                  "id": "T003",
                  "sequence": 3,
                  "session": "S1",
                  "event_time_ms": 3000,
                  "available_time_ms": 3025,
                  "price": 100,
                  "size": 150,
                  "status": "valid",
                  "condition": "regular"
                }
              ],
              "quotes": [
                {
                  "id": "Q001",
                  "sequence": 1,
                  "event_time_ms": 500,
                  "available_time_ms": 520,
                  "bid": 99.99,
                  "ask": 100.01,
                  "status": "valid",
                  "source": "SYNTH-NBBO"
                },
                {
                  "id": "Q002",
                  "sequence": 2,
                  "event_time_ms": 1500,
                  "available_time_ms": 1520,
                  "bid": 99.99,
                  "ask": 100.01,
                  "status": "valid",
                  "source": "SYNTH-NBBO"
                },
                {
                  "id": "Q003",
                  "sequence": 3,
                  "event_time_ms": 2500,
                  "available_time_ms": 2520,
                  "bid": 99.99,
                  "ask": 100.01,
                  "status": "valid",
                  "source": "SYNTH-NBBO"
                }
              ]
            },
            "elided": null
          },
          {
            "value": {
              "quote_lag_ms": 0,
              "midpoint_tolerance": 0,
              "zero_tick_mode": "carry"
            },
            "elided": null
          }
        ],
        "output": {
          "state": "ok",
          "method": "lee-ready",
          "trace": [
            {
              "id": "T001",
              "sequence": 1,
              "event_time_ms": 1000,
              "price": 100.01,
              "volume": 100,
              "sign": 1,
              "side": "buy",
              "reason": "above-midpoint",
              "rule": "quote",
              "midpoint": 100,
              "quote_id": "Q001",
              "cumulative_signed_volume": 100
            },
            {
              "id": "T002",
              "sequence": 2,
              "event_time_ms": 2000,
              "price": 99.99,
              "volume": 125,
              "sign": -1,
              "side": "sell",
              "reason": "below-midpoint",
              "rule": "quote",
              "midpoint": 100,
              "quote_id": "Q002",
              "cumulative_signed_volume": -25
            },
            {
              "id": "T003",
              "sequence": 3,
              "event_time_ms": 3000,
              "price": 100,
              "volume": 150,
              "sign": 1,
              "side": "buy",
              "reason": "midpoint-fallback:uptick",
              "rule": "tick-fallback",
              "midpoint": 100,
              "quote_id": "Q003",
              "cumulative_signed_volume": 125
            }
          ],
          "total_valid": 60,
          "classified_count": 60,
          "unknown_count": 0,
          "buy_count": 40,
          "sell_count": 20,
          "buy_volume": 6925,
          "sell_volume": 3425,
          "unknown_volume": 0,
          "signed_volume": 3500,
          "total_volume": 10350,
          "coverage": 1
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 20
        },
        "outputShape": "object with 20 fields: state, method, trace, total_valid, classified_count, unknown_count, buy_count, sell_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a03/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a03/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a03/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a03/static/scenario-matrix.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a03/static/worked-example.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "LEE_READY",
          "title": "Inferring Trade Direction from Intraday Data",
          "author": "Charles M. C. Lee and Mark J. Ready",
          "url": "https://doi.org/10.1111/j.1540-6261.1991.tb02683.x"
        },
        {
          "key": "NYSE_TAQ",
          "title": "Daily TAQ Client Specification",
          "author": "NYSE / ICE Data Services",
          "url": "https://www.nyse.com/publicdocs/nyse/data/Daily_TAQ_Client_Spec_v3.0b.pdf"
        },
        {
          "key": "NASDAQ_ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHspecification.pdf"
        },
        {
          "key": "FAST_MARKETS",
          "title": "Liquidity Measurement Problems in Fast, Competitive Markets",
          "author": "Craig W. Holden and Stacey Jacobsen",
          "url": "https://doi.org/10.1111/jofi.12127"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/trade-classification/lee-ready-trade-signing/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/trade-classification/lee-ready-trade-signing/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F01-A04",
      "name": "Bulk Volume Classification",
      "headline": null,
      "slug": "bulk-volume-classification",
      "path": "market-microstructure/trade-classification/bulk-volume-classification",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F01",
        "family": "Trade Classification",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/trade-classification/bulk-volume-classification",
        "entry": "bulkVolumeClassification",
        "params": [
          "data",
          "config"
        ],
        "exports": [
          "tickTest",
          "quoteTest",
          "leeReady",
          "studentTCdf",
          "bulkVolumeClassification",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "bulkVolumeClassification(data, config)"
      },
      "api": {
        "summary": "Assigns a *fraction* of each volume bar to buyers rather than signing individual trades. Designed for aggregated data where trade-level signing is impossible, and the input to VPIN.",
        "params": [
          {
            "name": "data",
            "type": "ClassificationInput",
            "required": true,
            "description": "Trades with prices, and where the rule needs them, the prevailing quotes.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "ClassificationConfig",
            "required": true,
            "description": "Tolerances and tie-breaking rules. Trades exactly at a quote or unchanged in price are the cases where classifiers differ, so the tie rule is part of the contract.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ classifications, summary, diagnostics }",
          "description": "Per-trade sign with the rule that produced it, plus counts of the unclassifiable cases. Bulk volume classification disagrees with its siblings on exactly those, and hiding them would hide the disagreement."
        },
        "warmup": null,
        "errors": [
          {
            "when": "required quote data is absent for a rule that needs it",
            "behaviour": "reported per trade rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "bulkVolumeClassification({\"starting_price\":100,\"bars\":[{\"id\":\"B001\",\"sequence\":1,\"event_time_ms\":1000,\"close\":100.05,\"volume\":1000,\"status\":\"valid\"},{\"id\":\"B002\",\"sequence\":2,\"event_time_ms\":61000,\"close\":100.05,\"volume\":1125,\"status\":\"valid\"},{\"id\":\"B003\",\"sequence\":3,\"event_time_ms\":121000,\"close\":100.025,\"volume\":1250,\"status\":\"valid\"}]}, {\"sigma\":0.05,\"degrees_of_freedom\":1})",
        "args": [
          {
            "value": {
              "starting_price": 100,
              "bars": [
                {
                  "id": "B001",
                  "sequence": 1,
                  "event_time_ms": 1000,
                  "close": 100.05,
                  "volume": 1000,
                  "status": "valid"
                },
                {
                  "id": "B002",
                  "sequence": 2,
                  "event_time_ms": 61000,
                  "close": 100.05,
                  "volume": 1125,
                  "status": "valid"
                },
                {
                  "id": "B003",
                  "sequence": 3,
                  "event_time_ms": 121000,
                  "close": 100.025,
                  "volume": 1250,
                  "status": "valid"
                }
              ]
            },
            "elided": null
          },
          {
            "value": {
              "sigma": 0.05,
              "degrees_of_freedom": 1
            },
            "elided": null
          }
        ],
        "output": {
          "state": "ok",
          "method": "bulk-volume-classification",
          "trace": [
            {
              "id": "B001",
              "sequence": 1,
              "event_time_ms": 1000,
              "price": 100.05,
              "volume": 1000,
              "sign": 1,
              "side": "buy-leaning",
              "reason": "student-t-volume-split",
              "price_change": 0.05,
              "z_score": 1,
              "buy_fraction": 0.75,
              "buy_volume": 750,
              "sell_volume": 250,
              "cumulative_signed_volume": 500
            },
            {
              "id": "B002",
              "sequence": 2,
              "event_time_ms": 61000,
              "price": 100.05,
              "volume": 1125,
              "sign": 0,
              "side": "balanced",
              "reason": "student-t-volume-split",
              "price_change": 0,
              "z_score": 0,
              "buy_fraction": 0.5,
              "buy_volume": 562.5,
              "sell_volume": 562.5,
              "cumulative_signed_volume": 500
            },
            {
              "id": "B003",
              "sequence": 3,
              "event_time_ms": 121000,
              "price": 100.025,
              "volume": 1250,
              "sign": -1,
              "side": "sell-leaning",
              "reason": "student-t-volume-split",
              "price_change": -0.025,
              "z_score": -0.5,
              "buy_fraction": 0.3524163823,
              "buy_volume": 440.520477937,
              "sell_volume": 809.479522063,
              "cumulative_signed_volume": 131.040955874
            }
          ],
          "total_valid": 60,
          "classified_count": 60,
          "unknown_count": 0,
          "buy_count": 24,
          "sell_count": 24,
          "buy_volume": 47435.5504890151,
          "sell_volume": 41439.4495109849,
          "unknown_volume": 0,
          "signed_volume": 5996.1009780303,
          "total_volume": 88875,
          "coverage": 1
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: state, method, trace, total_valid, classified_count, unknown_count, buy_count, sell_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a04/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a04/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a04/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a04/static/scenario-matrix.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d11-f01-a04/static/worked-example.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "BVC",
          "title": "Discerning Information from Trade Data",
          "author": "David Easley, Marcos Lopez de Prado, and Maureen O'Hara",
          "url": "https://doi.org/10.1016/j.jfineco.2016.01.018"
        },
        {
          "key": "NASDAQ_ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHspecification.pdf"
        },
        {
          "key": "NYSE_TAQ",
          "title": "Daily TAQ Client Specification",
          "author": "NYSE / ICE Data Services",
          "url": "https://www.nyse.com/publicdocs/nyse/data/Daily_TAQ_Client_Spec_v3.0b.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/trade-classification/bulk-volume-classification/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/trade-classification/bulk-volume-classification/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F02-A01",
      "name": "Quoted Spread",
      "headline": null,
      "slug": "quoted-spread",
      "path": "market-microstructure/liquidity-and-spreads/quoted-spread",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F02",
        "family": "Liquidity and Spreads",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/liquidity-and-spreads/quoted-spread",
        "entry": "quotedSpread",
        "params": [
          "bid",
          "ask"
        ],
        "exports": [
          "quotedSpread",
          "effectiveSpread",
          "realizedSpread",
          "rollSpread",
          "amihudIlliquidity",
          "corwinSchultzSpread",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "quotedSpread(bid, ask)"
      },
      "api": {
        "summary": "Ask minus bid — what the book advertises. The upper bound on what a small marketable order costs, and routinely wider than what trades actually pay.",
        "params": [
          {
            "name": "bid",
            "type": "number",
            "required": true,
            "description": "Best bid price.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "ask",
            "type": "number",
            "required": true,
            "description": "Best ask price; must not be below the bid.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ spread, relative_spread, midpoint, … }",
          "description": "The absolute spread with its relative form in basis points, which is the comparable one across instruments."
        },
        "warmup": null,
        "errors": [
          {
            "when": "ask is below bid, or either is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "quotedSpread(100, 100.08)",
        "args": [
          {
            "value": 100,
            "elided": null
          },
          {
            "value": 100.08,
            "elided": null
          }
        ],
        "output": {
          "model": "quoted-spread",
          "bid": 100,
          "ask": 100.08,
          "midpoint": 100.03999999999999,
          "quoted_spread": 0.0799999999999983,
          "quoted_spread_relative": 0.0007996801279488034,
          "quoted_spread_bps": 7.996801279488034,
          "state": "two-sided"
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: model, bid, ask, midpoint, quoted_spread, quoted_spread_relative, quoted_spread_bps, state"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a01/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a01/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a01/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a01/static/scenario-matrix.svg"
          },
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "SEC Rule 605 adopting release",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "SRC-02",
          "title": "NYSE Daily TAQ product description",
          "author": "New York Stock Exchange",
          "url": null
        },
        {
          "key": "SRC-03",
          "title": "2024 Rule 605 Amendments adopting release",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "SRC-04",
          "title": "Rule 605 staff frequently asked questions",
          "author": "U.S. Securities and Exchange Commission, Division of Trading and Markets staff",
          "url": null
        },
        {
          "key": "SEC-2026",
          "title": "Rule 605 staff FAQ transition",
          "author": "U.S. Securities and Exchange Commission, Division of Trading and Markets staff",
          "url": "https://www.sec.gov/rules-regulations/staff-guidance/trading-markets-frequently-asked-questions/frequently-asked-questions-rule-605-regulation-nms"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/liquidity-and-spreads/quoted-spread/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/liquidity-and-spreads/quoted-spread/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F02-A02",
      "name": "Effective Spread",
      "headline": null,
      "slug": "effective-spread",
      "path": "market-microstructure/liquidity-and-spreads/effective-spread",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F02",
        "family": "Liquidity and Spreads",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/liquidity-and-spreads/effective-spread",
        "entry": "effectiveSpread",
        "params": [
          "bid",
          "ask",
          "tradePrice",
          "side"
        ],
        "exports": [
          "quotedSpread",
          "effectiveSpread",
          "realizedSpread",
          "rollSpread",
          "amihudIlliquidity",
          "corwinSchultzSpread",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "effectiveSpread(bid, ask, tradePrice, side)"
      },
      "api": {
        "summary": "Twice the signed distance from the midpoint to the trade price — what the trade actually paid. Narrower than the quoted spread when trades execute inside it, wider when they sweep.",
        "params": [
          {
            "name": "bid",
            "type": "number",
            "required": true,
            "description": "Best bid at the time of the trade.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "ask",
            "type": "number",
            "required": true,
            "description": "Best ask at the time of the trade.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "tradePrice",
            "type": "number",
            "required": true,
            "description": "Executed price.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "side",
            "type": "\"buy\" | \"sell\"",
            "required": true,
            "description": "Trade direction, usually from a classifier in D11-F01.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ effective_spread, relative, midpoint, price_improvement }",
          "description": "The effective spread and the price improvement against the quote."
        },
        "warmup": null,
        "errors": [
          {
            "when": "side is not buy or sell, or ask is below bid",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "effectiveSpread(100, 100.08, 100.07, \"buy\")",
        "args": [
          {
            "value": 100,
            "elided": null
          },
          {
            "value": 100.08,
            "elided": null
          },
          {
            "value": 100.07,
            "elided": null
          },
          {
            "value": "buy",
            "elided": null
          }
        ],
        "output": {
          "model": "effective-spread",
          "bid": 100,
          "ask": 100.08,
          "midpoint": 100.03999999999999,
          "quoted_spread": 0.0799999999999983,
          "quoted_spread_relative": 0.0007996801279488034,
          "quoted_spread_bps": 7.996801279488034,
          "state": "inside-quote",
          "trade_price": 100.07,
          "side": "buy",
          "direction": 1,
          "effective_spread": 0.060000000000002274,
          "effective_spread_relative": 0.0005997600959616381,
          "effective_spread_bps": 5.997600959616381
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: model, bid, ask, midpoint, quoted_spread, quoted_spread_relative, quoted_spread_bps, state, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a02/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a02/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a02/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a02/static/scenario-matrix.svg"
          },
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "SEC Rule 605 adopting release",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "SRC-02",
          "title": "NYSE Daily TAQ product description",
          "author": "New York Stock Exchange",
          "url": null
        },
        {
          "key": "SRC-03",
          "title": "2024 Rule 605 Amendments adopting release",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "SRC-04",
          "title": "Rule 605 staff frequently asked questions",
          "author": "U.S. Securities and Exchange Commission, Division of Trading and Markets staff",
          "url": null
        },
        {
          "key": "SEC-2026",
          "title": "Rule 605 staff FAQ transition",
          "author": "U.S. Securities and Exchange Commission, Division of Trading and Markets staff",
          "url": "https://www.sec.gov/rules-regulations/staff-guidance/trading-markets-frequently-asked-questions/frequently-asked-questions-rule-605-regulation-nms"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/liquidity-and-spreads/effective-spread/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/liquidity-and-spreads/effective-spread/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F02-A03",
      "name": "Realized Spread",
      "headline": null,
      "slug": "realized-spread",
      "path": "market-microstructure/liquidity-and-spreads/realized-spread",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F02",
        "family": "Liquidity and Spreads",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/liquidity-and-spreads/realized-spread",
        "entry": "realizedSpread",
        "params": [
          "bidAtTrade",
          "askAtTrade",
          "tradePrice",
          "side",
          "bidAfter",
          "askAfter",
          "horizonSeconds"
        ],
        "exports": [
          "quotedSpread",
          "effectiveSpread",
          "realizedSpread",
          "rollSpread",
          "amihudIlliquidity",
          "corwinSchultzSpread",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "realizedSpread(bidAtTrade, askAtTrade, tradePrice, side, bidAfter, askAfter, horizonSeconds)"
      },
      "api": {
        "summary": "The effective spread measured against the midpoint *after* a horizon, which strips out the permanent price impact and leaves what the liquidity provider actually earned. The horizon choice is a modelling decision, not a detail.",
        "params": [
          {
            "name": "bidAtTrade",
            "type": "number",
            "required": true,
            "description": "Best bid at execution.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "askAtTrade",
            "type": "number",
            "required": true,
            "description": "Best ask at execution.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "tradePrice",
            "type": "number",
            "required": true,
            "description": "Executed price.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "side",
            "type": "\"buy\" | \"sell\"",
            "required": true,
            "description": "Trade direction.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "bidAfter",
            "type": "number",
            "required": true,
            "description": "Best bid after the horizon.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "askAfter",
            "type": "number",
            "required": true,
            "description": "Best ask after the horizon.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "horizonSeconds",
            "type": "number",
            "required": true,
            "description": "Seconds after the trade at which the later midpoint is taken. Five minutes is conventional; shorter horizons attribute more of the move to impact.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ realized_spread, price_impact, effective_spread, … }",
          "description": "The realized spread with the price impact it decomposes against — the two sum to the effective spread."
        },
        "warmup": null,
        "errors": [
          {
            "when": "horizonSeconds is negative, or a quote is invalid",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "realizedSpread(100, 100.08, 100.07, \"buy\", 100.11, 100.19, 300)",
        "args": [
          {
            "value": 100,
            "elided": null
          },
          {
            "value": 100.08,
            "elided": null
          },
          {
            "value": 100.07,
            "elided": null
          },
          {
            "value": "buy",
            "elided": null
          },
          {
            "value": 100.11,
            "elided": null
          },
          {
            "value": 100.19,
            "elided": null
          },
          {
            "value": 300,
            "elided": null
          }
        ],
        "output": {
          "model": "realized-spread",
          "side": "buy",
          "direction": 1,
          "trade_price": 100.07,
          "midpoint_at_trade": 100.03999999999999,
          "midpoint_after": 100.15,
          "bid_after": 100.11,
          "ask_after": 100.19,
          "horizon_seconds": 300,
          "effective_spread": 0.060000000000002274,
          "realized_spread": -0.160000000000025,
          "realized_spread_relative": -0.0015993602558978912,
          "realized_spread_bps": -15.993602558978912,
          "price_impact": 0.22000000000002728
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 18
        },
        "outputShape": "object with 18 fields: model, side, direction, trade_price, midpoint_at_trade, midpoint_after, bid_after, ask_after, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a03/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a03/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a03/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a03/static/scenario-matrix.svg"
          },
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "SEC Rule 605 adopting release and current FAQ",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "SRC-02",
          "title": "NYSE Daily TAQ product description",
          "author": "New York Stock Exchange",
          "url": null
        },
        {
          "key": "SRC-03",
          "title": "2024 Rule 605 Amendments adopting release",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "SRC-04",
          "title": "Rule 605 staff frequently asked questions",
          "author": "U.S. Securities and Exchange Commission, Division of Trading and Markets staff",
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/liquidity-and-spreads/realized-spread/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/liquidity-and-spreads/realized-spread/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F02-A04",
      "name": "Roll Spread Estimator",
      "headline": null,
      "slug": "roll-spread-estimator",
      "path": "market-microstructure/liquidity-and-spreads/roll-spread-estimator",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F02",
        "family": "Liquidity and Spreads",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/liquidity-and-spreads/roll-spread-estimator",
        "entry": "rollSpread",
        "params": [
          "prices"
        ],
        "exports": [
          "quotedSpread",
          "effectiveSpread",
          "realizedSpread",
          "rollSpread",
          "amihudIlliquidity",
          "corwinSchultzSpread",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "rollSpread(prices)"
      },
      "api": {
        "summary": "Infers the effective spread from the negative serial covariance of price changes alone — no quote data required. When the covariance comes out positive the model is contradicted, and reporting zero rather than an imaginary number is the honest handling.",
        "params": [
          {
            "name": "prices",
            "type": "number[]",
            "required": true,
            "description": "Trade price series, chronological.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ spread, covariance, valid, … }",
          "description": "The implied spread with the covariance behind it and a validity flag for the positive-covariance case."
        },
        "warmup": null,
        "errors": [
          {
            "when": "fewer than three prices are supplied",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "rollSpread([100,100.05,100.01,100.06,100.02,100.07])",
        "args": [
          {
            "value": [
              100,
              100.05,
              100.01,
              100.06,
              100.02,
              100.07
            ],
            "elided": null
          }
        ],
        "output": {
          "model": "roll-spread",
          "observation_count": 6,
          "change_count": 5,
          "covariance_pair_count": 4,
          "lag1_price_change_covariance": -0.0026999999999997785,
          "covariance_tolerance": 1e-15,
          "mean_price": 100.03500000000001,
          "spread_estimate": 0.10392304845412838,
          "spread_estimate_relative": 0.0010388668811328872,
          "spread_estimate_bps": 10.388668811328872,
          "state": "estimated"
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: model, observation_count, change_count, covariance_pair_count, lag1_price_change_covariance, covariance_tolerance, mean_price, spread_estimate, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a04/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a04/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a04/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a04/static/scenario-matrix.svg"
          },
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "Roll (1984), A Simple Implicit Measure of the Effective Bid-Ask Spread",
          "author": "The Journal of Finance",
          "url": null
        },
        {
          "key": "SRC-02",
          "title": "NYSE Daily TAQ product description",
          "author": "New York Stock Exchange",
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/liquidity-and-spreads/roll-spread-estimator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/liquidity-and-spreads/roll-spread-estimator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F02-A05",
      "name": "Amihud Illiquidity Ratio",
      "headline": null,
      "slug": "amihud-illiquidity-ratio",
      "path": "market-microstructure/liquidity-and-spreads/amihud-illiquidity-ratio",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F02",
        "family": "Liquidity and Spreads",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/liquidity-and-spreads/amihud-illiquidity-ratio",
        "entry": "amihudIlliquidity",
        "params": [
          "closes",
          "dollarVolumes",
          "scale"
        ],
        "exports": [
          "quotedSpread",
          "effectiveSpread",
          "realizedSpread",
          "rollSpread",
          "amihudIlliquidity",
          "corwinSchultzSpread",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "amihudIlliquidity(closes, dollarVolumes, scale)"
      },
      "api": {
        "summary": "Average absolute return per unit of dollar volume — how much price moves per dollar traded. The most widely used low-frequency illiquidity proxy precisely because it needs only daily data.",
        "params": [
          {
            "name": "closes",
            "type": "number[]",
            "required": true,
            "description": "Daily closing prices.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "dollarVolumes",
            "type": "number[]",
            "required": true,
            "description": "Daily traded value, aligned index-for-index with the closes.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "scale",
            "type": "number",
            "required": true,
            "description": "Scaling applied to the raw ratio. The unscaled value is tiny, so published figures are almost always scaled — and papers differ on by how much.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ratio, daily_ratios, observations, scale }",
          "description": "The averaged ratio with the daily series and the scale applied, since a figure quoted without its scale is not comparable."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a dollar volume is zero, making the daily ratio undefined",
            "behaviour": "excluded from the average and reported"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "amihudIlliquidity([100,101,100.5,102,101.5,103], [1000000,1200000,900000,1500000,1100000,1400000], 1000000)",
        "args": [
          {
            "value": [
              100,
              101,
              100.5,
              102,
              101.5,
              103
            ],
            "elided": null
          },
          {
            "value": [
              1000000,
              1200000,
              900000,
              1500000,
              1100000,
              1400000
            ],
            "elided": null
          },
          {
            "value": 1000000,
            "elided": null
          }
        ],
        "output": {
          "model": "amihud-illiquidity",
          "observation_count": 6,
          "return_count": 5,
          "returns": [
            0.010000000000000009,
            -0.004950495049504955,
            0.014925373134328401,
            -0.004901960784313708,
            0.014778325123152802
          ],
          "daily_illiquidity": [
            8.33333333333334e-9,
            5.500550055005505e-9,
            9.950248756218935e-9,
            4.4563279857397345e-9,
            1.0555946516537716e-8
          ],
          "illiquidity_per_currency_unit": 7.759281329367046e-9,
          "scale": 1000000,
          "illiquidity_per_scaled_volume": 0.0077592813293670465,
          "state": "estimated"
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: model, observation_count, return_count, returns, daily_illiquidity, illiquidity_per_currency_unit, scale, illiquidity_per_scaled_volume, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a05/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a05/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a05/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a05/static/scenario-matrix.svg"
          },
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "Amihud (2002), Illiquidity and Stock Returns",
          "author": "Journal of Financial Markets",
          "url": null
        },
        {
          "key": "SRC-02",
          "title": "NYSE Daily TAQ product description",
          "author": "New York Stock Exchange",
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/liquidity-and-spreads/amihud-illiquidity-ratio/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/liquidity-and-spreads/amihud-illiquidity-ratio/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F02-A06",
      "name": "Corwin-Schultz Spread Estimator",
      "headline": null,
      "slug": "corwin-schultz-spread-estimator",
      "path": "market-microstructure/liquidity-and-spreads/corwin-schultz-spread-estimator",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F02",
        "family": "Liquidity and Spreads",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/liquidity-and-spreads/corwin-schultz-spread-estimator",
        "entry": "corwinSchultzSpread",
        "params": [
          "highDay1",
          "lowDay1",
          "highDay2",
          "lowDay2",
          "clipNegative"
        ],
        "exports": [
          "quotedSpread",
          "effectiveSpread",
          "realizedSpread",
          "rollSpread",
          "amihudIlliquidity",
          "corwinSchultzSpread",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "corwinSchultzSpread(highDay1, lowDay1, highDay2, lowDay2, clipNegative)"
      },
      "api": {
        "summary": "Estimates the spread from daily high-low ranges over two days, exploiting that the range reflects both volatility and spread while volatility scales with time and the spread does not. Frequently returns negative values, which are theoretically impossible.",
        "params": [
          {
            "name": "highDay1",
            "type": "number",
            "required": true,
            "description": "First day's high.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "lowDay1",
            "type": "number",
            "required": true,
            "description": "First day's low.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "highDay2",
            "type": "number",
            "required": true,
            "description": "Second day's high.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "lowDay2",
            "type": "number",
            "required": true,
            "description": "Second day's low.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "clipNegative",
            "type": "boolean",
            "required": true,
            "description": "Whether to clip negative estimates to zero. Corwin and Schultz recommend it; leaving them visible is more honest when averaging across a sample.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ spread, raw_spread, beta, gamma, alpha, clipped }",
          "description": "The estimate with every intermediate, and whether clipping was applied."
        },
        "warmup": null,
        "errors": [
          {
            "when": "any high is below its low",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "corwinSchultzSpread(101, 99, 101.5, 99.5, true)",
        "args": [
          {
            "value": 101,
            "elided": null
          },
          {
            "value": 99,
            "elided": null
          },
          {
            "value": 101.5,
            "elided": null
          },
          {
            "value": 99.5,
            "elided": null
          },
          {
            "value": true,
            "elided": null
          }
        ],
        "output": {
          "model": "corwin-schultz-spread",
          "beta": 0.0007960826118720654,
          "gamma": 0.0006219511446669105,
          "alpha_raw": 0.007908933752463966,
          "alpha_used": 0.007908933752463966,
          "spread_estimate_relative": 0.007908892526591878,
          "spread_estimate_bps": 79.08892526591879,
          "clip_negative": true,
          "state": "estimated"
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: model, beta, gamma, alpha_raw, alpha_used, spread_estimate_relative, spread_estimate_bps, clip_negative, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a06/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a06/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a06/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a06/static/scenario-matrix.svg"
          },
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f02-a06/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "Corwin and Schultz (2012), A Simple Way to Estimate Bid-Ask Spreads",
          "author": "The Journal of Finance",
          "url": null
        },
        {
          "key": "SRC-02",
          "title": "NYSE Daily TAQ product description",
          "author": "New York Stock Exchange",
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/liquidity-and-spreads/corwin-schultz-spread-estimator/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/liquidity-and-spreads/corwin-schultz-spread-estimator/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F03-A01",
      "name": "Order Flow Imbalance",
      "headline": null,
      "slug": "order-flow-imbalance",
      "path": "market-microstructure/order-flow-and-impact/order-flow-imbalance",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F03",
        "family": "Order-Flow and Impact",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/order-flow-and-impact/order-flow-imbalance",
        "entry": "orderFlowImbalance",
        "params": [
          "inputRows",
          "resetOnSession",
          "normalizeByDepth"
        ],
        "exports": [
          "orderFlowImbalance",
          "queueImbalance",
          "kyleLambda",
          "hasbrouckPriceImpact",
          "pin",
          "vpin",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "orderFlowImbalance(inputRows, resetOnSession, normalizeByDepth)"
      },
      "api": {
        "summary": "Net signed change in depth at the touch — the quantity that best explains short-horizon price moves in the microstructure literature. It counts additions and cancellations, not just trades.",
        "params": [
          {
            "name": "inputRows",
            "type": "Row[]",
            "required": true,
            "description": "Sequential top-of-book observations with prices and sizes on both sides.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "resetOnSession",
            "type": "boolean",
            "required": true,
            "description": "Whether the cumulative measure restarts each session. Carrying it overnight mixes regimes.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "normalizeByDepth",
            "type": "boolean",
            "required": true,
            "description": "Divide by prevailing depth, which makes the measure comparable across instruments of different thickness.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ ofi, cumulative, rows, … }",
          "description": "Per-observation imbalance and its cumulative path."
        },
        "warmup": null,
        "errors": [
          {
            "when": "rows are not in sequence order",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "orderFlowImbalance([{\"id\":\"E001\",\"session\":\"S1\",\"event_time_ns\":0,\"bid_price\":100,\"bid_size\":500,\"ask_price\":100.02,\"ask_size\":520},{\"id\":\"E002\",\"session\":\"S1\",\"event_time_ns\":1000000,\"bid_price\":100,\"bid_size\":573,\"ask_price\":100.02,\"ask_size\":567},{\"id\":\"E003\",\"session\":\"S1\",\"event_time_ns\":2000000,\"bid_price\":100,\"bid_size\":996,\"ask_price\":100.02,\"ask_size\":614}], true, false)",
        "args": [
          {
            "value": [
              {
                "id": "E001",
                "session": "S1",
                "event_time_ns": 0,
                "bid_price": 100,
                "bid_size": 500,
                "ask_price": 100.02,
                "ask_size": 520
              },
              {
                "id": "E002",
                "session": "S1",
                "event_time_ns": 1000000,
                "bid_price": 100,
                "bid_size": 573,
                "ask_price": 100.02,
                "ask_size": 567
              },
              {
                "id": "E003",
                "session": "S1",
                "event_time_ns": 2000000,
                "bid_price": 100,
                "bid_size": 996,
                "ask_price": 100.02,
                "ask_size": 614
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 60
            }
          },
          {
            "value": true,
            "elided": null
          },
          {
            "value": false,
            "elided": null
          }
        ],
        "output": {
          "model": "cont-best-quote-ofi",
          "state": "estimated",
          "reset_on_session": true,
          "normalize_by_depth": false,
          "event_count": 60,
          "classified_event_count": 59,
          "positive_event_count": 34,
          "negative_event_count": 25,
          "zero_event_count": 0,
          "cumulative_ofi": 58,
          "mean_absolute_event_ofi": 440.5762711864,
          "trace": [
            {
              "id": "E001",
              "index": 0,
              "session": "S1",
              "bid_price": 100,
              "bid_size": 500,
              "ask_price": 100.02,
              "ask_size": 520,
              "event_ofi": 0,
              "cumulative_ofi": 0,
              "side": "balanced",
              "reason": "seed"
            },
            {
              "id": "E002",
              "index": 1,
              "session": "S1",
              "bid_price": 100,
              "bid_size": 573,
              "ask_price": 100.02,
              "ask_size": 567,
              "event_ofi": 26,
              "cumulative_ofi": 26,
              "side": "buy-pressure",
              "reason": "best-quote-event"
            },
            {
              "id": "E003",
              "index": 2,
              "session": "S1",
              "bid_price": 100,
              "bid_size": 996,
              "ask_price": 100.02,
              "ask_size": 614,
              "event_ofi": 376,
              "cumulative_ofi": 402,
              "side": "buy-pressure",
              "reason": "best-quote-event"
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 12 fields: model, state, reset_on_session, normalize_by_depth, event_count, classified_event_count, positive_event_count, negative_event_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a01/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a01/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a01/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a01/static/scenario-matrix.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a01/static/worked-example.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "OFI",
          "title": "The Price Impact of Order Book Events",
          "author": null,
          "url": "https://doi.org/10.1093/jjfinec/nbt003"
        },
        {
          "key": "ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": null,
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/order-flow-and-impact/order-flow-imbalance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/order-flow-and-impact/order-flow-imbalance/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F03-A02",
      "name": "Queue Imbalance",
      "headline": null,
      "slug": "queue-imbalance",
      "path": "market-microstructure/order-flow-and-impact/queue-imbalance",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F03",
        "family": "Order-Flow and Impact",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/order-flow-and-impact/queue-imbalance",
        "entry": "queueImbalance",
        "params": [
          "inputRows",
          "levels",
          "decay"
        ],
        "exports": [
          "orderFlowImbalance",
          "queueImbalance",
          "kyleLambda",
          "hasbrouckPriceImpact",
          "pin",
          "vpin",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "queueImbalance(inputRows, levels, decay)"
      },
      "api": {
        "summary": "The share of depth resting on the bid versus the ask. A simple, strongly predictive feature for the direction of the next price move at very short horizons.",
        "params": [
          {
            "name": "inputRows",
            "type": "Row[]",
            "required": true,
            "description": "Book observations with per-level sizes.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "levels",
            "type": "number",
            "required": true,
            "description": "How many levels deep to include. One level is the classic definition; more captures a broader picture and dilutes the signal.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "decay",
            "type": "number",
            "required": true,
            "description": "Weight decay applied to deeper levels, so a size far from the touch counts for less.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ imbalance, rows, levels, … }",
          "description": "Imbalance per observation, ranging from −1 (all ask) to +1 (all bid)."
        },
        "warmup": null,
        "errors": [
          {
            "when": "levels exceeds the depth supplied",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × levels)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "queueImbalance([{\"id\":\"Q001\",\"event_time_ns\":0,\"bid_sizes\":[600,900,1100],\"ask_sizes\":[600,900,1100]},{\"id\":\"Q002\",\"event_time_ns\":1000000,\"bid_sizes\":[680.3444,862.918,1124.7214],\"ask_sizes\":[519.6556,937.082,1075.2786]},{\"id\":\"Q003\",\"event_time_ns\":2000000,\"bid_sizes\":[752.8242,829.4658,1147.0228],\"ask_sizes\":[447.1758,970.5342,1052.9772]}], 1, 1)",
        "args": [
          {
            "value": [
              {
                "id": "Q001",
                "event_time_ns": 0,
                "bid_sizes": [
                  600,
                  900,
                  1100
                ],
                "ask_sizes": [
                  600,
                  900,
                  1100
                ]
              },
              {
                "id": "Q002",
                "event_time_ns": 1000000,
                "bid_sizes": [
                  680.3444,
                  862.918,
                  1124.7214
                ],
                "ask_sizes": [
                  519.6556,
                  937.082,
                  1075.2786
                ]
              },
              {
                "id": "Q003",
                "event_time_ns": 2000000,
                "bid_sizes": [
                  752.8242,
                  829.4658,
                  1147.0228
                ],
                "ask_sizes": [
                  447.1758,
                  970.5342,
                  1052.9772
                ]
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 60
            }
          },
          {
            "value": 1,
            "elided": null
          },
          {
            "value": 1,
            "elided": null
          }
        ],
        "output": {
          "model": "signed-queue-imbalance",
          "state": "estimated",
          "levels": 1,
          "decay": 1,
          "observation_count": 60,
          "valid_count": 60,
          "unknown_count": 0,
          "mean_imbalance": 0,
          "last_imbalance": -0.1339073333,
          "max_absolute_imbalance": 0.4333333333,
          "trace": [
            {
              "id": "Q001",
              "index": 0,
              "bid_depth": 600,
              "ask_depth": 600,
              "total_depth": 1200,
              "imbalance": 0,
              "side": "balanced",
              "reason": "normalized-depth"
            },
            {
              "id": "Q002",
              "index": 1,
              "bid_depth": 680.3444,
              "ask_depth": 519.6556,
              "total_depth": 1200,
              "imbalance": 0.1339073333,
              "side": "bid-heavy",
              "reason": "normalized-depth"
            },
            {
              "id": "Q003",
              "index": 2,
              "bid_depth": 752.8242,
              "ask_depth": 447.1758,
              "total_depth": 1200,
              "imbalance": 0.254707,
              "side": "bid-heavy",
              "reason": "normalized-depth"
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: model, state, levels, decay, observation_count, valid_count, unknown_count, mean_imbalance, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a02/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a02/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a02/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a02/static/scenario-matrix.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a02/static/worked-example.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "QUEUE",
          "title": "Queue Imbalance as a One-Tick-Ahead Price Predictor in a Limit Order Book",
          "author": null,
          "url": "https://arxiv.org/abs/1512.03492"
        },
        {
          "key": "ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": null,
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/order-flow-and-impact/queue-imbalance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/order-flow-and-impact/queue-imbalance/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F03-A03",
      "name": "Kyle Lambda",
      "headline": null,
      "slug": "kyle-lambda",
      "path": "market-microstructure/order-flow-and-impact/kyle-lambda",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F03",
        "family": "Order-Flow and Impact",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/order-flow-and-impact/kyle-lambda",
        "entry": "kyleLambda",
        "params": [
          "inputRows",
          "volumeTransform",
          "intercept"
        ],
        "exports": [
          "orderFlowImbalance",
          "queueImbalance",
          "kyleLambda",
          "hasbrouckPriceImpact",
          "pin",
          "vpin",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "kyleLambda(inputRows, volumeTransform, intercept)"
      },
      "api": {
        "summary": "The price-impact coefficient from regressing price change on signed order flow. Lambda *is* the illiquidity parameter in Kyle's model — higher means each unit of flow moves price more.",
        "params": [
          {
            "name": "inputRows",
            "type": "Row[]",
            "required": true,
            "description": "Interval observations of price change and signed volume.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "volumeTransform",
            "type": "string",
            "required": true,
            "description": "How signed volume enters the regression — raw, or square-rooted for the concave impact many studies find.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "intercept",
            "type": "boolean",
            "required": true,
            "description": "Whether to fit an intercept. Theory says zero; fitting one and finding it non-zero is diagnostic.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ lambda, r_squared, intercept, observations, … }",
          "description": "The coefficient with its fit quality — a lambda from a regression that explains nothing is a number, not a measurement."
        },
        "warmup": null,
        "errors": [
          {
            "when": "fewer than two observations, or zero variance in signed volume",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "kyleLambda([{\"id\":\"K001\",\"interval_end\":0,\"signed_volume_k\":-8.8,\"mid_change_bps\":-3.756},{\"id\":\"K002\",\"interval_end\":1,\"signed_volume_k\":4.8,\"mid_change_bps\":2.196},{\"id\":\"K003\",\"interval_end\":2,\"signed_volume_k\":0,\"mid_change_bps\":0.08}], \"linear\", true)",
        "args": [
          {
            "value": [
              {
                "id": "K001",
                "interval_end": 0,
                "signed_volume_k": -8.8,
                "mid_change_bps": -3.756
              },
              {
                "id": "K002",
                "interval_end": 1,
                "signed_volume_k": 4.8,
                "mid_change_bps": 2.196
              },
              {
                "id": "K003",
                "interval_end": 2,
                "signed_volume_k": 0,
                "mid_change_bps": 0.08
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 60
            }
          },
          {
            "value": "linear",
            "elided": null
          },
          {
            "value": true,
            "elided": null
          }
        ],
        "output": {
          "model": "empirical-kyle-lambda",
          "state": "estimated",
          "volume_transform": "linear",
          "intercept": true,
          "observation_count": 60,
          "alpha_bps": 0.1008250803,
          "lambda_bps_per_regressor_unit": 0.4210091524,
          "r_squared": 0.9980824794,
          "residual_std_bps": 0.1004292969,
          "trace": [
            {
              "id": "K001",
              "index": 0,
              "signed_volume_k": -8.8,
              "regressor": -8.8,
              "mid_change_bps": -3.756,
              "predicted_change_bps": -3.6040554607,
              "residual_bps": -0.1519445393,
              "side": "negative-impact",
              "reason": "linear"
            },
            {
              "id": "K002",
              "index": 1,
              "signed_volume_k": 4.8,
              "regressor": 4.8,
              "mid_change_bps": 2.196,
              "predicted_change_bps": 2.1216690117,
              "residual_bps": 0.0743309883,
              "side": "positive-impact",
              "reason": "linear"
            },
            {
              "id": "K003",
              "index": 2,
              "signed_volume_k": 0,
              "regressor": 0,
              "mid_change_bps": 0.08,
              "predicted_change_bps": 0.1008250803,
              "residual_bps": -0.0208250803,
              "side": "positive-impact",
              "reason": "linear"
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: model, state, volume_transform, intercept, observation_count, alpha_bps, lambda_bps_per_regressor_unit, r_squared, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a03/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a03/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a03/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a03/static/scenario-matrix.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a03/static/worked-example.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "KYLE",
          "title": "Continuous Auctions and Insider Trading",
          "author": null,
          "url": "https://doi.org/10.2307/1913210"
        },
        {
          "key": "ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": null,
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/order-flow-and-impact/kyle-lambda/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/order-flow-and-impact/kyle-lambda/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F03-A04",
      "name": "Hasbrouck Price Impact",
      "headline": null,
      "slug": "hasbrouck-price-impact",
      "path": "market-microstructure/order-flow-and-impact/hasbrouck-price-impact",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F03",
        "family": "Order-Flow and Impact",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/order-flow-and-impact/hasbrouck-price-impact",
        "entry": "hasbrouckPriceImpact",
        "params": [
          "inputRows",
          "horizon"
        ],
        "exports": [
          "orderFlowImbalance",
          "queueImbalance",
          "kyleLambda",
          "hasbrouckPriceImpact",
          "pin",
          "vpin",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "hasbrouckPriceImpact(inputRows, horizon)"
      },
      "api": {
        "summary": "Decomposes a trade's price effect into the permanent part — information — and the transient part that reverts. The split is what distinguishes an informed trade from a liquidity demand.",
        "params": [
          {
            "name": "inputRows",
            "type": "Row[]",
            "required": true,
            "description": "Trades with signed direction and the midpoint path around each.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "horizon",
            "type": "number",
            "required": true,
            "description": "Observations after the trade over which permanence is judged.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ permanent_impact, transient_impact, total, horizon, … }",
          "description": "Both components with the horizon they were measured over."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the midpoint path is shorter than the horizon",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n × horizon)",
          "space": "O(n)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "hasbrouckPriceImpact([{\"id\":\"H001\",\"interval_end\":0,\"signed_flow\":-1.8,\"mid_change_bps\":-0.404},{\"id\":\"H002\",\"interval_end\":1,\"signed_flow\":0.17,\"mid_change_bps\":-0.43029818},{\"id\":\"H003\",\"interval_end\":2,\"signed_flow\":-0.3405,\"mid_change_bps\":-0.03967215}], 10)",
        "args": [
          {
            "value": [
              {
                "id": "H001",
                "interval_end": 0,
                "signed_flow": -1.8,
                "mid_change_bps": -0.404
              },
              {
                "id": "H002",
                "interval_end": 1,
                "signed_flow": 0.17,
                "mid_change_bps": -0.43029818
              },
              {
                "id": "H003",
                "interval_end": 2,
                "signed_flow": -0.3405,
                "mid_change_bps": -0.03967215
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 60
            }
          },
          {
            "value": 10,
            "elided": null
          }
        ],
        "output": {
          "model": "hasbrouck-var1-flow-first",
          "state": "estimated",
          "observation_count": 60,
          "horizon": 10,
          "flow_equation": {
            "intercept": -0.0138732152,
            "flow_lag": 0.0401141764,
            "return_lag": -0.7889548599
          },
          "return_equation": {
            "intercept": -0.0042458851,
            "flow_lag": 0.232390819,
            "return_lag": -0.0460365216
          },
          "flow_innovation_variance": 0.9887794778,
          "return_flow_innovation_covariance": 0.1786454708,
          "contemporaneous_return_response_bps": 0.1806727129,
          "cumulative_price_impact_bps": 0.3417920234,
          "trace": [
            {
              "id": "H000",
              "index": 0,
              "flow_response": 1,
              "return_response_bps": 0.1806727129,
              "cumulative_impact_bps": 0.1806727129,
              "side": "positive-impact",
              "reason": "recursive-var1-response"
            },
            {
              "id": "H001",
              "index": 1,
              "flow_response": -0.1024284385,
              "return_response_bps": 0.2240732757,
              "cumulative_impact_bps": 0.4047459887,
              "side": "positive-impact",
              "reason": "recursive-var1-response"
            },
            {
              "id": "H002",
              "index": 2,
              "flow_response": -0.1808925323,
              "return_response_bps": -0.0341189829,
              "cumulative_impact_bps": 0.3706270058,
              "side": "positive-impact",
              "reason": "recursive-var1-response"
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: model, state, observation_count, horizon, flow_equation, return_equation, flow_innovation_variance, return_flow_innovation_covariance, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a04/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a04/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a04/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a04/static/scenario-matrix.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a04/static/worked-example.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "HASBROUCK",
          "title": "Measuring the Information Content of Stock Trades",
          "author": null,
          "url": "https://doi.org/10.1111/j.1540-6261.1991.tb03749.x"
        },
        {
          "key": "ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": null,
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/order-flow-and-impact/hasbrouck-price-impact/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/order-flow-and-impact/hasbrouck-price-impact/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F03-A05",
      "name": "PIN",
      "headline": null,
      "slug": "pin",
      "path": "market-microstructure/order-flow-and-impact/pin",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F03",
        "family": "Order-Flow and Impact",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/order-flow-and-impact/pin",
        "entry": "pin",
        "params": [
          "inputRows",
          "starts",
          "balancedNoise",
          "iterations"
        ],
        "exports": [
          "orderFlowImbalance",
          "queueImbalance",
          "kyleLambda",
          "hasbrouckPriceImpact",
          "pin",
          "vpin",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "pin(inputRows, starts, balancedNoise, iterations)"
      },
      "api": {
        "summary": "Probability of informed trading, estimated by maximum likelihood on daily buy and sell counts. Notoriously hard to optimise — the likelihood has flat regions and local optima, which is why the starting points are a parameter.",
        "params": [
          {
            "name": "inputRows",
            "type": "Row[]",
            "required": true,
            "description": "Daily buy and sell trade counts.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "starts",
            "type": "number[][]",
            "required": true,
            "description": "Starting parameter vectors. Multiple starts are the standard defence against local optima; a single start frequently converges somewhere wrong.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "balancedNoise",
            "type": "number",
            "required": true,
            "description": "Initial guess for the balanced uninformed arrival rate.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "iterations",
            "type": "number",
            "required": true,
            "description": "Maximum optimiser iterations.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ pin, alpha, mu, epsilon_buy, epsilon_sell, converged, … }",
          "description": "The PIN estimate with every structural parameter and a convergence flag — an unconverged PIN is not an estimate."
        },
        "warmup": null,
        "errors": [
          {
            "when": "no starting vector is supplied",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(days × iterations × starts)",
          "space": "O(days)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "pin([{\"id\":\"D001\",\"day\":1,\"buys\":12,\"sells\":29},{\"id\":\"D002\",\"day\":2,\"buys\":14,\"sells\":12},{\"id\":\"D003\",\"day\":3,\"buys\":16,\"sells\":13}], 3, false, 120)",
        "args": [
          {
            "value": [
              {
                "id": "D001",
                "day": 1,
                "buys": 12,
                "sells": 29
              },
              {
                "id": "D002",
                "day": 2,
                "buys": 14,
                "sells": 12
              },
              {
                "id": "D003",
                "day": 3,
                "buys": 16,
                "sells": 13
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 60
            }
          },
          {
            "value": 3,
            "elided": null
          },
          {
            "value": false,
            "elided": null
          },
          {
            "value": 120,
            "elided": null
          }
        ],
        "output": {
          "model": "ekop-pin",
          "state": "estimated",
          "observation_count": 60,
          "starts": 3,
          "balanced_noise": false,
          "alpha": 0.3335769653,
          "delta": 0.3998646736,
          "mu": 19.2332579136,
          "epsilon_buy": 14.0464750051,
          "epsilon_sell": 13.0377527714,
          "log_likelihood": -335.6690937078,
          "pin": 0.1915155787,
          "trace": [
            {
              "id": "D001",
              "index": 0,
              "buys": 12,
              "sells": 29,
              "imbalance": -17,
              "side": "sell-heavy",
              "reason": "daily-count-input"
            },
            {
              "id": "D002",
              "index": 1,
              "buys": 14,
              "sells": 12,
              "imbalance": 2,
              "side": "buy-heavy",
              "reason": "daily-count-input"
            },
            {
              "id": "D003",
              "index": 2,
              "buys": 16,
              "sells": 13,
              "imbalance": 3,
              "side": "buy-heavy",
              "reason": "daily-count-input"
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: model, state, observation_count, starts, balanced_noise, alpha, delta, mu, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a05/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a05/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a05/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a05/static/scenario-matrix.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a05/static/worked-example.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "PIN",
          "title": "Liquidity, Information, and Infrequently Traded Stocks",
          "author": null,
          "url": "https://doi.org/10.1111/j.1540-6261.1996.tb04074.x"
        },
        {
          "key": "ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": null,
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/order-flow-and-impact/pin/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/order-flow-and-impact/pin/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F03-A06",
      "name": "VPIN",
      "headline": null,
      "slug": "vpin",
      "path": "market-microstructure/order-flow-and-impact/vpin",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F03",
        "family": "Order-Flow and Impact",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/order-flow-and-impact/vpin",
        "entry": "vpin",
        "params": [
          "inputRows",
          "bucketVolume",
          "windowBuckets",
          "includePartial"
        ],
        "exports": [
          "orderFlowImbalance",
          "queueImbalance",
          "kyleLambda",
          "hasbrouckPriceImpact",
          "pin",
          "vpin",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "vpin(inputRows, bucketVolume, windowBuckets, includePartial)"
      },
      "api": {
        "summary": "Volume-synchronised probability of informed trading: order imbalance measured in volume buckets rather than clock time. Proposed as a flash-crash early warning, and contested — its predictive claims are actively disputed in the literature.",
        "params": [
          {
            "name": "inputRows",
            "type": "Row[]",
            "required": true,
            "description": "Trades or volume bars with signed or classifiable volume.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "bucketVolume",
            "type": "number",
            "required": true,
            "description": "Volume that closes a bucket. The choice materially changes the series.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "windowBuckets",
            "type": "number",
            "required": true,
            "description": "Buckets averaged into each VPIN reading.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "includePartial",
            "type": "boolean",
            "required": true,
            "description": "Whether a final incomplete bucket is included.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ vpin, buckets, window_buckets, … }",
          "description": "The VPIN series with the buckets it was computed from."
        },
        "warmup": null,
        "errors": [
          {
            "when": "bucketVolume is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(buckets)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "vpin([{\"id\":\"V001\",\"event_time_ns\":0,\"buy_volume\":50,\"sell_volume\":50},{\"id\":\"V002\",\"event_time_ns\":1000000,\"buy_volume\":54.59220119,\"sell_volume\":45.40779881},{\"id\":\"V003\",\"event_time_ns\":2000000,\"buy_volume\":58.48528137,\"sell_volume\":41.51471863}], 100, 10, false)",
        "args": [
          {
            "value": [
              {
                "id": "V001",
                "event_time_ns": 0,
                "buy_volume": 50,
                "sell_volume": 50
              },
              {
                "id": "V002",
                "event_time_ns": 1000000,
                "buy_volume": 54.59220119,
                "sell_volume": 45.40779881
              },
              {
                "id": "V003",
                "event_time_ns": 2000000,
                "buy_volume": 58.48528137,
                "sell_volume": 41.51471863
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 60
            }
          },
          {
            "value": 100,
            "elided": null
          },
          {
            "value": 10,
            "elided": null
          },
          {
            "value": false,
            "elided": null
          }
        ],
        "output": {
          "model": "volume-synchronized-probability-of-informed-trading",
          "state": "estimated",
          "bucket_volume": 100,
          "window_buckets": 10,
          "include_partial": false,
          "input_event_count": 60,
          "bucket_count": 60,
          "dropped_partial_volume": 0,
          "valid_vpin_count": 51,
          "last_vpin": 0.1597998193,
          "mean_vpin": 0.3604789898,
          "max_vpin": 0.86,
          "trace": [
            {
              "id": "V001",
              "index": 0,
              "buy_volume": 50,
              "sell_volume": 50,
              "total_volume": 100,
              "absolute_imbalance": 0,
              "imbalance_fraction": 0,
              "source_event_index": 0,
              "vpin": null,
              "window_count": 1,
              "side": "warm-up",
              "reason": "insufficient-buckets"
            },
            {
              "id": "V002",
              "index": 1,
              "buy_volume": 54.59220119,
              "sell_volume": 45.40779881,
              "total_volume": 100,
              "absolute_imbalance": 9.18440238,
              "imbalance_fraction": 0.0918440238,
              "source_event_index": 1,
              "vpin": null,
              "window_count": 2,
              "side": "warm-up",
              "reason": "insufficient-buckets"
            },
            {
              "id": "V003",
              "index": 2,
              "buy_volume": 58.48528137,
              "sell_volume": 41.51471863,
              "total_volume": 100,
              "absolute_imbalance": 16.97056274,
              "imbalance_fraction": 0.1697056274,
              "source_event_index": 2,
              "vpin": null,
              "window_count": 3,
              "side": "warm-up",
              "reason": "insufficient-buckets"
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: model, state, bucket_volume, window_buckets, include_partial, input_event_count, bucket_count, dropped_partial_volume, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a06/static/calculation-map.svg"
          },
          {
            "file": "decision-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a06/static/decision-boundary.svg"
          },
          {
            "file": "failure-boundary.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a06/static/failure-boundary.svg"
          },
          {
            "file": "scenario-matrix.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a06/static/scenario-matrix.svg"
          },
          {
            "file": "worked-example.svg",
            "url": "https://thefintechbuilder.com/content/d11-f03-a06/static/worked-example.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "VPIN",
          "title": "Flow Toxicity and Liquidity in a High-Frequency World",
          "author": null,
          "url": "https://doi.org/10.1093/rfs/hhs053"
        },
        {
          "key": "VPIN_CRITIQUE",
          "title": "VPIN and the Flash Crash",
          "author": null,
          "url": "https://doi.org/10.1016/j.finmar.2013.05.005"
        },
        {
          "key": "ITCH",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": null,
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/order-flow-and-impact/vpin/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/order-flow-and-impact/vpin/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F04-A01",
      "name": "Order-Book Slope",
      "headline": null,
      "slug": "order-book-slope",
      "path": "market-microstructure/order-book-dynamics/order-book-slope",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F04",
        "family": "Order-Book Dynamics",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/order-book-dynamics/order-book-slope",
        "entry": "orderBookSlope",
        "params": [
          "bidPrices",
          "bidSizes",
          "askPrices",
          "askSizes"
        ],
        "exports": [
          "orderBookSlope",
          "depthWeightedMidprice",
          "microprice",
          "orderBookResiliency",
          "hawkesOrderArrival",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "orderBookSlope(bidPrices, bidSizes, askPrices, askSizes)"
      },
      "api": {
        "summary": "How steeply depth accumulates as you move away from the touch. A steep book absorbs size with little price movement; a flat one does not — it is a liquidity measure that the spread alone cannot express.",
        "params": [
          {
            "name": "bidPrices",
            "type": "number[]",
            "required": true,
            "description": "Bid prices, best first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "bidSizes",
            "type": "number[]",
            "required": true,
            "description": "Sizes aligned with bidPrices.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "askPrices",
            "type": "number[]",
            "required": true,
            "description": "Ask prices, best first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "askSizes",
            "type": "number[]",
            "required": true,
            "description": "Sizes aligned with askPrices.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ bid_slope, ask_slope, slope, asymmetry, … }",
          "description": "Slope per side and combined, with the asymmetry between them."
        },
        "warmup": null,
        "errors": [
          {
            "when": "prices and sizes differ in length, or a side is empty",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(levels)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "orderBookSlope([99.5,99,98.5], [400,600,1000], [100.5,101,101.5], [300,700,1000])",
        "args": [
          {
            "value": [
              99.5,
              99,
              98.5
            ],
            "elided": null
          },
          {
            "value": [
              400,
              600,
              1000
            ],
            "elided": null
          },
          {
            "value": [
              100.5,
              101,
              101.5
            ],
            "elided": null
          },
          {
            "value": [
              300,
              700,
              1000
            ],
            "elided": null
          }
        ],
        "output": {
          "model": "naes-skjeltorp-snapshot-slope",
          "level_count": 3,
          "bid_level_count": 3,
          "ask_level_count": 3,
          "midpoint": 100,
          "bid_cumulative_depth": [
            400,
            1000,
            2000
          ],
          "ask_cumulative_depth": [
            300,
            1000,
            2000
          ],
          "bid_local_slopes": [
            1198.2929094215954,
            30.433603371811753,
            19.86797971382265
          ],
          "ask_local_slopes": [
            1140.7564949312646,
            42.42772839686445,
            20.269353041374735
          ],
          "bid_slope": 416.1981641690766,
          "ask_slope": 401.1511921231679,
          "order_book_slope": 408.67467814612223,
          "slope_tolerance": 4.161981641690766e-10,
          "state": "steeper-bid"
        },
        "outputElided": null,
        "outputShape": "object with 14 fields: model, level_count, bid_level_count, ask_level_count, midpoint, bid_cumulative_depth, ask_cumulative_depth, bid_local_slopes, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f04-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Source 1",
          "title": "Næs and Skjeltorp (2006)",
          "author": "Randi Næs and Johannes A. Skjeltorp",
          "url": "https://doi.org/10.1016/j.finmar.2006.04.001"
        },
        {
          "key": "Source 2",
          "title": "NYSE Integrated Feed",
          "author": "NYSE",
          "url": "https://www.nyse.com/data-products/catalog/integrated-feed"
        },
        {
          "key": "Publication and data boundary",
          "title": "Publication and data boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/order-book-dynamics/order-book-slope/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/order-book-dynamics/order-book-slope/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F04-A02",
      "name": "Depth-Weighted Midprice",
      "headline": null,
      "slug": "depth-weighted-midprice",
      "path": "market-microstructure/order-book-dynamics/depth-weighted-midprice",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F04",
        "family": "Order-Book Dynamics",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/order-book-dynamics/depth-weighted-midprice",
        "entry": "depthWeightedMidprice",
        "params": [
          "bidPrices",
          "bidSizes",
          "askPrices",
          "askSizes"
        ],
        "exports": [
          "orderBookSlope",
          "depthWeightedMidprice",
          "microprice",
          "orderBookResiliency",
          "hawkesOrderArrival",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "depthWeightedMidprice(bidPrices, bidSizes, askPrices, askSizes)"
      },
      "api": {
        "summary": "A midpoint weighted by depth across several levels rather than the naive average of best bid and ask. Less prone to jumping when a single small order sits at the touch.",
        "params": [
          {
            "name": "bidPrices",
            "type": "number[]",
            "required": true,
            "description": "Bid prices, best first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "bidSizes",
            "type": "number[]",
            "required": true,
            "description": "Sizes aligned with bidPrices.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "askPrices",
            "type": "number[]",
            "required": true,
            "description": "Ask prices, best first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "askSizes",
            "type": "number[]",
            "required": true,
            "description": "Sizes aligned with askPrices.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ midprice, simple_midpoint, weighted_bid, weighted_ask, … }",
          "description": "The depth-weighted midpoint alongside the naive one, so the difference is visible."
        },
        "warmup": null,
        "errors": [
          {
            "when": "total depth on either side is zero",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(levels)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "depthWeightedMidprice([99.99,99.98,99.97], [500,1000,1500], [100.01,100.02,100.03], [300,700,2000])",
        "args": [
          {
            "value": [
              99.99,
              99.98,
              99.97
            ],
            "elided": null
          },
          {
            "value": [
              500,
              1000,
              1500
            ],
            "elided": null
          },
          {
            "value": [
              100.01,
              100.02,
              100.03
            ],
            "elided": null
          },
          {
            "value": [
              300,
              700,
              2000
            ],
            "elided": null
          }
        ],
        "output": {
          "model": "same-side-depth-weighted-midpoint",
          "level_count": 3,
          "bid_level_count": 3,
          "ask_level_count": 3,
          "top_midpoint": 100,
          "depth_weighted_bid": 99.97666666666667,
          "depth_weighted_ask": 100.02566666666667,
          "depth_weighted_midprice": 100.00116666666668,
          "shift": 0.0011666666666769743,
          "shift_bps": 0.11666666666769743,
          "bid_total_depth": 3000,
          "ask_total_depth": 3000,
          "state": "above-top-mid"
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: model, level_count, bid_level_count, ask_level_count, top_midpoint, depth_weighted_bid, depth_weighted_ask, depth_weighted_midprice, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f04-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Source 1",
          "title": "Stoikov microprice paper and explicit package convention",
          "author": "Sasha Stoikov; exact same-side weighting is a repository implementation choice",
          "url": "https://doi.org/10.2139/ssrn.2970694"
        },
        {
          "key": "Source 2",
          "title": "NYSE Integrated Feed",
          "author": "NYSE",
          "url": "https://www.nyse.com/data-products/catalog/integrated-feed"
        },
        {
          "key": "Publication and data boundary",
          "title": "Publication and data boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/order-book-dynamics/depth-weighted-midprice/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/order-book-dynamics/depth-weighted-midprice/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F04-A03",
      "name": "Microprice",
      "headline": null,
      "slug": "microprice",
      "path": "market-microstructure/order-book-dynamics/microprice",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F04",
        "family": "Order-Book Dynamics",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/order-book-dynamics/microprice",
        "entry": "microprice",
        "params": [
          "bid",
          "bidSize",
          "ask",
          "askSize"
        ],
        "exports": [
          "orderBookSlope",
          "depthWeightedMidprice",
          "microprice",
          "orderBookResiliency",
          "hawkesOrderArrival",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "microprice(bid, bidSize, ask, askSize)"
      },
      "api": {
        "summary": "The midpoint weighted by the *opposite* side's size, so a heavy bid pulls the price up. Counter-intuitive until you see the derivation — the imbalance predicts where the midpoint is going, not where it is.",
        "params": [
          {
            "name": "bid",
            "type": "number",
            "required": true,
            "description": "Best bid price.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "bidSize",
            "type": "number",
            "required": true,
            "description": "Size at the best bid.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "ask",
            "type": "number",
            "required": true,
            "description": "Best ask price.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "askSize",
            "type": "number",
            "required": true,
            "description": "Size at the best ask.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ microprice, midpoint, imbalance, … }",
          "description": "The microprice with the imbalance that tilted it."
        },
        "warmup": null,
        "errors": [
          {
            "when": "both sizes are zero, or ask is below bid",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "microprice(99.99, 800, 100.01, 200)",
        "args": [
          {
            "value": 99.99,
            "elided": null
          },
          {
            "value": 800,
            "elided": null
          },
          {
            "value": 100.01,
            "elided": null
          },
          {
            "value": 200,
            "elided": null
          }
        ],
        "output": {
          "model": "top-of-book-imbalance-weighted-quote",
          "bid": 99.99,
          "ask": 100.01,
          "bid_size": 800,
          "ask_size": 200,
          "midpoint": 100,
          "spread": 0.020000000000010232,
          "queue_imbalance": 0.6,
          "microprice": 100.006,
          "shift": 0.006000000000000227,
          "shift_bps": 0.6000000000000227,
          "identity_error": 0,
          "state": "bid-pressure"
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: model, bid, ask, bid_size, ask_size, midpoint, spread, queue_imbalance, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f04-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Source 1",
          "title": "Stoikov, The Micro-Price",
          "author": "Sasha Stoikov",
          "url": "https://doi.org/10.2139/ssrn.2970694"
        },
        {
          "key": "Source 2",
          "title": "NYSE Integrated Feed",
          "author": "NYSE",
          "url": "https://www.nyse.com/data-products/catalog/integrated-feed"
        },
        {
          "key": "Publication and data boundary",
          "title": "Publication and data boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/order-book-dynamics/microprice/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/order-book-dynamics/microprice/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F04-A04",
      "name": "Order-Book Resiliency",
      "headline": null,
      "slug": "order-book-resiliency",
      "path": "market-microstructure/order-book-dynamics/order-book-resiliency",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F04",
        "family": "Order-Book Dynamics",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/order-book-dynamics/order-book-resiliency",
        "entry": "orderBookResiliency",
        "params": [
          "timesSeconds",
          "displacementBps",
          "forecastSeconds"
        ],
        "exports": [
          "orderBookSlope",
          "depthWeightedMidprice",
          "microprice",
          "orderBookResiliency",
          "hawkesOrderArrival",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "orderBookResiliency(timesSeconds, displacementBps, forecastSeconds)"
      },
      "api": {
        "summary": "How quickly the book refills after being depleted, fitted as a decay over observed displacement. Resiliency is the third dimension of liquidity beside spread and depth, and the one that decides whether a large order can be worked at all.",
        "params": [
          {
            "name": "timesSeconds",
            "type": "number[]",
            "required": true,
            "description": "Observation times after the depleting event, in seconds.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "displacementBps",
            "type": "number[]",
            "required": true,
            "description": "Displacement from the pre-event level at each time, in basis points.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "forecastSeconds",
            "type": "number",
            "required": true,
            "description": "Horizon at which to project the remaining displacement.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ decay_rate, half_life_seconds, forecast_displacement, fit_quality, … }",
          "description": "The decay rate and half-life, with fit quality — a resiliency figure from a poor fit is not usable."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the two series differ in length or contain fewer than two points",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "orderBookResiliency([0,1,2,3,4,5], [8,5.637504,3.972682,2.7995,1.972776,1.390191], 5)",
        "args": [
          {
            "value": [
              0,
              1,
              2,
              3,
              4,
              5
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 7
            }
          },
          {
            "value": [
              8,
              5.637504,
              3.972682,
              2.7995,
              1.972776,
              1.390191
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 7
            }
          },
          {
            "value": 5,
            "elided": null
          }
        ],
        "output": {
          "model": "exponential-displacement-recovery",
          "observation_count": 7,
          "initial_displacement_bps": 8,
          "recovery_rate_per_second": 0.3500000711368042,
          "half_life_seconds": 1.980420113369107,
          "forecast_seconds": 5,
          "forecast_displacement_bps": 1.3901910531347295,
          "recovered_fraction": 0.8262261183581588,
          "fitted_displacement_bps": [
            8,
            5.637504316715653,
            3.972681865123452,
            2.799501395446431,
            1.9727751501850936,
            1.3901910531347295
          ],
          "rmse_bps": 6.314204089006822e-7,
          "state": "estimated"
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: model, observation_count, initial_displacement_bps, recovery_rate_per_second, half_life_seconds, forecast_seconds, forecast_displacement_bps, recovered_fraction, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f04-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Source 1",
          "title": "Obizhaeva and Wang (2013)",
          "author": "Anna A. Obizhaeva and Jiang Wang",
          "url": "https://web.mit.edu/wangj/OldFiles/www/pap/ObizhaevaWang13.pdf"
        },
        {
          "key": "Source 2",
          "title": "NYSE Integrated Feed",
          "author": "NYSE",
          "url": "https://www.nyse.com/data-products/catalog/integrated-feed"
        },
        {
          "key": "Publication and data boundary",
          "title": "Publication and data boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/order-book-dynamics/order-book-resiliency/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/order-book-dynamics/order-book-resiliency/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F04-A05",
      "name": "Hawkes Order-Arrival Model",
      "headline": null,
      "slug": "hawkes-order-arrival-model",
      "path": "market-microstructure/order-book-dynamics/hawkes-order-arrival-model",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F04",
        "family": "Order-Book Dynamics",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/order-book-dynamics/hawkes-order-arrival-model",
        "entry": "hawkesOrderArrival",
        "params": [
          "eventTimesSeconds",
          "baselineIntensity",
          "excitationJump",
          "decayRate",
          "evaluationTimeSeconds",
          "horizonSeconds"
        ],
        "exports": [
          "orderBookSlope",
          "depthWeightedMidprice",
          "microprice",
          "orderBookResiliency",
          "hawkesOrderArrival",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "hawkesOrderArrival(eventTimesSeconds, baselineIntensity, excitationJump, decayRate, evaluationTimeSeconds, horizonSeconds)"
      },
      "api": {
        "summary": "A self-exciting point process: each arrival raises the probability of the next. It captures order clustering that a Poisson model cannot, which is why order flow looks bursty rather than smooth.",
        "params": [
          {
            "name": "eventTimesSeconds",
            "type": "number[]",
            "required": true,
            "description": "Arrival times in seconds, ascending.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "baselineIntensity",
            "type": "number",
            "required": true,
            "description": "Background arrival rate absent any excitation.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "excitationJump",
            "type": "number",
            "required": true,
            "description": "Intensity added by each arrival. Above the decay rate the process is explosive and has no stationary distribution.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "decayRate",
            "type": "number",
            "required": true,
            "description": "Rate at which excitation fades.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "evaluationTimeSeconds",
            "type": "number",
            "required": true,
            "description": "Time at which the intensity is evaluated.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "horizonSeconds",
            "type": "number",
            "required": true,
            "description": "Forecast horizon for expected arrivals.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ intensity, expected_arrivals, branching_ratio, stationary, … }",
          "description": "Intensity and expected arrivals, plus the branching ratio — at or above 1 the process is non-stationary and the forecast is meaningless."
        },
        "warmup": null,
        "errors": [
          {
            "when": "event times are not ascending, or decayRate is zero",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "hawkesOrderArrival([0.2,0.9,1.4,2.7], 0.5, 0.8, 1.6, 3, 3.5)",
        "args": [
          {
            "value": [
              0.2,
              0.9,
              1.4,
              2.7
            ],
            "elided": null
          },
          {
            "value": 0.5,
            "elided": null
          },
          {
            "value": 0.8,
            "elided": null
          },
          {
            "value": 1.6,
            "elided": null
          },
          {
            "value": 3,
            "elided": null
          },
          {
            "value": 3.5,
            "elided": null
          }
        ],
        "output": {
          "model": "univariate-exponential-hawkes",
          "event_count": 4,
          "baseline_intensity": 0.5,
          "excitation_jump": 0.8,
          "decay_rate": 1.6,
          "branching_ratio": 0.5,
          "stationary": true,
          "expected_cluster_multiplier": 2,
          "evaluation_time_seconds": 3,
          "intensity_at_evaluation": 1.0937254434790773,
          "event_intensities": [
            0.5,
            0.7610238356984316,
            0.9767487409980575,
            0.6595044911371601
          ],
          "horizon_seconds": 3.5,
          "compensator": 3.5832637259446924,
          "log_likelihood": -4.9892938375210205
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 15
        },
        "outputShape": "object with 15 fields: model, event_count, baseline_intensity, excitation_jump, decay_rate, branching_ratio, stationary, expected_cluster_multiplier, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f04-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "Source 1",
          "title": "Hawkes (1971)",
          "author": "Alan G. Hawkes",
          "url": "https://doi.org/10.1093/biomet/58.1.83"
        },
        {
          "key": "Source 2",
          "title": "NYSE Integrated Feed",
          "author": "NYSE",
          "url": "https://www.nyse.com/data-products/catalog/integrated-feed"
        },
        {
          "key": "Source 3",
          "title": "Hawkes model for price and trades high-frequency dynamics",
          "author": "Emmanuel Bacry and Jean-François Muzy",
          "url": "https://arxiv.org/abs/1301.1135"
        },
        {
          "key": "Publication and data boundary",
          "title": "Publication and data boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/order-book-dynamics/hawkes-order-arrival-model/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/order-book-dynamics/hawkes-order-arrival-model/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F05-A01",
      "name": "Cumulative Bid/Ask Depth",
      "headline": null,
      "slug": "cumulative-bid-ask-depth",
      "path": "market-microstructure/market-depth-analytics/cumulative-bid-ask-depth",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F05",
        "family": "Market-Depth Analytics",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/market-depth-analytics/cumulative-bid-ask-depth",
        "entry": "cumulativeDepth",
        "params": [
          "bidsRaw",
          "asksRaw",
          "tickRaw"
        ],
        "exports": [
          "cumulativeDepth",
          "topNDepthImbalance",
          "depthAtDistanceProfile",
          "expectedFillPrice",
          "sweepCostAndSlippage",
          "liquidityWallConcentration",
          "depthDepletionReplenishment",
          "marketDepthHeatmap",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "cumulativeDepth(bidsRaw, asksRaw, tickRaw)"
      },
      "api": {
        "summary": "Running total of quantity available as you walk out from the touch on each side — the basis of every question about how much can be traded before price moves.",
        "params": [
          {
            "name": "bidsRaw",
            "type": "Level[]",
            "required": true,
            "description": "Bid levels, best first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "asksRaw",
            "type": "Level[]",
            "required": true,
            "description": "Ask levels, best first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "tickRaw",
            "type": "number",
            "required": true,
            "description": "Tick size, used to express distance in ticks rather than currency.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ bids, asks, total_bid_depth, total_ask_depth, … }",
          "description": "Cumulative depth per level on each side."
        },
        "warmup": null,
        "errors": [
          {
            "when": "tick size is not positive, or a level has negative size",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(levels)",
          "space": "O(levels)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "cumulativeDepth([{\"price\":99.99,\"quantity\":500},{\"price\":99.98,\"quantity\":800},{\"price\":99.97,\"quantity\":1200}], [{\"price\":100.01,\"quantity\":300},{\"price\":100.02,\"quantity\":600},{\"price\":100.03,\"quantity\":1000}], 0.01)",
        "args": [
          {
            "value": [
              {
                "price": 99.99,
                "quantity": 500
              },
              {
                "price": 99.98,
                "quantity": 800
              },
              {
                "price": 99.97,
                "quantity": 1200
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": [
              {
                "price": 100.01,
                "quantity": 300
              },
              {
                "price": 100.02,
                "quantity": 600
              },
              {
                "price": 100.03,
                "quantity": 1000
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": 0.01,
            "elided": null
          }
        ],
        "output": {
          "model": "visible-cumulative-depth",
          "best_bid": 99.99,
          "best_ask": 100.01,
          "tick_size": 0.01,
          "spread_ticks": 2,
          "bid_levels": [
            {
              "price": 99.99,
              "quantity": 500,
              "distance_ticks": 0,
              "cumulative_quantity": 500
            },
            {
              "price": 99.98,
              "quantity": 800,
              "distance_ticks": 1,
              "cumulative_quantity": 1300
            },
            {
              "price": 99.97,
              "quantity": 1200,
              "distance_ticks": 2,
              "cumulative_quantity": 2500
            }
          ],
          "ask_levels": [
            {
              "price": 100.01,
              "quantity": 300,
              "distance_ticks": 0,
              "cumulative_quantity": 300
            },
            {
              "price": 100.02,
              "quantity": 600,
              "distance_ticks": 1,
              "cumulative_quantity": 900
            },
            {
              "price": 100.03,
              "quantity": 1000,
              "distance_ticks": 2,
              "cumulative_quantity": 1900
            }
          ],
          "total_bid_depth": 3600,
          "total_ask_depth": 3300,
          "state": "bid-deeper"
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: model, best_bid, best_ask, tick_size, spread_ticks, bid_levels, ask_levels, total_bid_depth, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "NYSE Integrated Feed",
          "author": "New York Stock Exchange",
          "url": "https://www.nyse.com/data-products/catalog/integrated-feed"
        },
        {
          "key": "S2",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/market-depth-analytics/cumulative-bid-ask-depth/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/market-depth-analytics/cumulative-bid-ask-depth/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F05-A02",
      "name": "Top-N Depth Imbalance",
      "headline": null,
      "slug": "top-n-depth-imbalance",
      "path": "market-microstructure/market-depth-analytics/top-n-depth-imbalance",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F05",
        "family": "Market-Depth Analytics",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/market-depth-analytics/top-n-depth-imbalance",
        "entry": "topNDepthImbalance",
        "params": [
          "bidsRaw",
          "asksRaw",
          "nRaw",
          "thresholdRaw"
        ],
        "exports": [
          "cumulativeDepth",
          "topNDepthImbalance",
          "depthAtDistanceProfile",
          "expectedFillPrice",
          "sweepCostAndSlippage",
          "liquidityWallConcentration",
          "depthDepletionReplenishment",
          "marketDepthHeatmap",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "topNDepthImbalance(bidsRaw, asksRaw, nRaw, thresholdRaw)"
      },
      "api": {
        "summary": "Depth imbalance restricted to the top N levels — the same idea as queue imbalance, bounded to the part of the book that is realistically accessible.",
        "params": [
          {
            "name": "bidsRaw",
            "type": "Level[]",
            "required": true,
            "description": "Bid levels, best first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "asksRaw",
            "type": "Level[]",
            "required": true,
            "description": "Ask levels, best first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "nRaw",
            "type": "number",
            "required": true,
            "description": "Levels to include.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "thresholdRaw",
            "type": "number",
            "required": true,
            "description": "Magnitude above which the imbalance is flagged as significant.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ imbalance, bid_depth, ask_depth, significant, … }",
          "description": "The imbalance with the depths behind it and whether it cleared the threshold."
        },
        "warmup": null,
        "errors": [
          {
            "when": "nRaw exceeds the levels supplied",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(n)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "topNDepthImbalance([{\"price\":99.99,\"quantity\":500},{\"price\":99.98,\"quantity\":800},{\"price\":99.97,\"quantity\":1200}], [{\"price\":100.01,\"quantity\":300},{\"price\":100.02,\"quantity\":600},{\"price\":100.03,\"quantity\":1000}], 3, 0.1)",
        "args": [
          {
            "value": [
              {
                "price": 99.99,
                "quantity": 500
              },
              {
                "price": 99.98,
                "quantity": 800
              },
              {
                "price": 99.97,
                "quantity": 1200
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": [
              {
                "price": 100.01,
                "quantity": 300
              },
              {
                "price": 100.02,
                "quantity": 600
              },
              {
                "price": 100.03,
                "quantity": 1000
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": 3,
            "elided": null
          },
          {
            "value": 0.1,
            "elided": null
          }
        ],
        "output": {
          "model": "top-n-visible-depth-imbalance",
          "n": 3,
          "bid_depth": 2500,
          "ask_depth": 1900,
          "total_depth": 4400,
          "imbalance": 0.13636363636363635,
          "threshold": 0.1,
          "state": "bid-heavy",
          "complete_window": true
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: model, n, bid_depth, ask_depth, total_depth, imbalance, threshold, state, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "NYSE Integrated Feed",
          "author": "New York Stock Exchange",
          "url": "https://www.nyse.com/data-products/catalog/integrated-feed"
        },
        {
          "key": "S2",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "S3",
          "title": "The Price Impact of Order Book Events",
          "author": "Rama Cont, Arseniy Kukanov, and Sasha Stoikov",
          "url": "https://arxiv.org/abs/1011.6402"
        },
        {
          "key": "S4",
          "title": "Multi-Level Order-Flow Imbalance in a Limit Order Book",
          "author": "Ke Xu, Martin D. Gould, and Sam D. Howison",
          "url": "https://arxiv.org/abs/1907.06230"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/market-depth-analytics/top-n-depth-imbalance/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/market-depth-analytics/top-n-depth-imbalance/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F05-A03",
      "name": "Depth-at-Distance Profile",
      "headline": null,
      "slug": "depth-at-distance-profile",
      "path": "market-microstructure/market-depth-analytics/depth-at-distance-profile",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F05",
        "family": "Market-Depth Analytics",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/market-depth-analytics/depth-at-distance-profile",
        "entry": "depthAtDistanceProfile",
        "params": [
          "bidsRaw",
          "asksRaw",
          "tickRaw",
          "maxRaw"
        ],
        "exports": [
          "cumulativeDepth",
          "topNDepthImbalance",
          "depthAtDistanceProfile",
          "expectedFillPrice",
          "sweepCostAndSlippage",
          "liquidityWallConcentration",
          "depthDepletionReplenishment",
          "marketDepthHeatmap",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "depthAtDistanceProfile(bidsRaw, asksRaw, tickRaw, maxRaw)"
      },
      "api": {
        "summary": "Depth bucketed by distance from the touch, in ticks. Shows where liquidity actually sits rather than reducing the book to a single number.",
        "params": [
          {
            "name": "bidsRaw",
            "type": "Level[]",
            "required": true,
            "description": "Bid levels.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "asksRaw",
            "type": "Level[]",
            "required": true,
            "description": "Ask levels.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "tickRaw",
            "type": "number",
            "required": true,
            "description": "Tick size.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "maxRaw",
            "type": "number",
            "required": true,
            "description": "Maximum distance in ticks to profile.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ profile, max_distance, tick, … }",
          "description": "Depth per distance bucket on both sides."
        },
        "warmup": null,
        "errors": [
          {
            "when": "tick size is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(levels)",
          "space": "O(buckets)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "depthAtDistanceProfile([{\"price\":99.99,\"quantity\":500},{\"price\":99.98,\"quantity\":800},{\"price\":99.97,\"quantity\":1200}], [{\"price\":100.01,\"quantity\":300},{\"price\":100.02,\"quantity\":600},{\"price\":100.03,\"quantity\":1000}], 0.01, 4)",
        "args": [
          {
            "value": [
              {
                "price": 99.99,
                "quantity": 500
              },
              {
                "price": 99.98,
                "quantity": 800
              },
              {
                "price": 99.97,
                "quantity": 1200
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": [
              {
                "price": 100.01,
                "quantity": 300
              },
              {
                "price": 100.02,
                "quantity": 600
              },
              {
                "price": 100.03,
                "quantity": 1000
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": 0.01,
            "elided": null
          },
          {
            "value": 4,
            "elided": null
          }
        ],
        "output": {
          "model": "same-side-best-tick-distance-profile",
          "tick_size": 0.01,
          "max_distance_ticks": 4,
          "bid_profile": [
            {
              "distance_ticks": 0,
              "quantity": 500,
              "cumulative_quantity": 500,
              "depth_share": 0.1388888888888889
            },
            {
              "distance_ticks": 1,
              "quantity": 800,
              "cumulative_quantity": 1300,
              "depth_share": 0.2222222222222222
            },
            {
              "distance_ticks": 2,
              "quantity": 1200,
              "cumulative_quantity": 2500,
              "depth_share": 0.3333333333333333
            }
          ],
          "ask_profile": [
            {
              "distance_ticks": 0,
              "quantity": 300,
              "cumulative_quantity": 300,
              "depth_share": 0.09090909090909091
            },
            {
              "distance_ticks": 1,
              "quantity": 600,
              "cumulative_quantity": 900,
              "depth_share": 0.18181818181818182
            },
            {
              "distance_ticks": 2,
              "quantity": 1000,
              "cumulative_quantity": 1900,
              "depth_share": 0.30303030303030304
            }
          ],
          "included_bid_depth": 3600,
          "included_ask_depth": 3300,
          "state": "bid-profile-heavier"
        },
        "outputElided": null,
        "outputShape": "object with 8 fields: model, tick_size, max_distance_ticks, bid_profile, ask_profile, included_bid_depth, included_ask_depth, state"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "NYSE Integrated Feed",
          "author": "New York Stock Exchange",
          "url": "https://www.nyse.com/data-products/catalog/integrated-feed"
        },
        {
          "key": "S2",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/market-depth-analytics/depth-at-distance-profile/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/market-depth-analytics/depth-at-distance-profile/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F05-A04",
      "name": "Expected Market-Order Fill Price",
      "headline": null,
      "slug": "expected-market-order-fill-price",
      "path": "market-microstructure/market-depth-analytics/expected-market-order-fill-price",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F05",
        "family": "Market-Depth Analytics",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/market-depth-analytics/expected-market-order-fill-price",
        "entry": "expectedFillPrice",
        "params": [
          "bids",
          "asks",
          "side",
          "quantity",
          "limitPrice"
        ],
        "exports": [
          "cumulativeDepth",
          "topNDepthImbalance",
          "depthAtDistanceProfile",
          "expectedFillPrice",
          "sweepCostAndSlippage",
          "liquidityWallConcentration",
          "depthDepletionReplenishment",
          "marketDepthHeatmap",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "expectedFillPrice(bids, asks, side, quantity, limitPrice)"
      },
      "api": {
        "summary": "Walks a market order through the book and returns the volume-weighted price it would pay. The honest answer to 'what will this cost' — and it can be a partial fill, which a naive estimate silently ignores.",
        "params": [
          {
            "name": "bids",
            "type": "Level[]",
            "required": true,
            "description": "Bid levels, best first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "asks",
            "type": "Level[]",
            "required": true,
            "description": "Ask levels, best first.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "side",
            "type": "\"buy\" | \"sell\"",
            "required": true,
            "description": "Order direction, which selects the side consumed.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "quantity",
            "type": "number",
            "required": true,
            "description": "Order quantity.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "limitPrice",
            "type": "number",
            "required": false,
            "description": "Optional limit beyond which the order stops consuming levels.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ average_price, filled_quantity, unfilled_quantity, levels_consumed, … }",
          "description": "The average price with the filled and **unfilled** quantities stated separately — a book too thin to fill the order is the case that matters."
        },
        "warmup": null,
        "errors": [
          {
            "when": "quantity is not positive, or side is unrecognised",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(levels)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "expectedFillPrice([{\"price\":99.99,\"quantity\":500},{\"price\":99.98,\"quantity\":800},{\"price\":99.97,\"quantity\":1200}], [{\"price\":100.01,\"quantity\":300},{\"price\":100.02,\"quantity\":600},{\"price\":100.03,\"quantity\":1000}], \"buy\", 1500, null)",
        "args": [
          {
            "value": [
              {
                "price": 99.99,
                "quantity": 500
              },
              {
                "price": 99.98,
                "quantity": 800
              },
              {
                "price": 99.97,
                "quantity": 1200
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": [
              {
                "price": 100.01,
                "quantity": 300
              },
              {
                "price": 100.02,
                "quantity": 600
              },
              {
                "price": 100.03,
                "quantity": 1000
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": "buy",
            "elided": null
          },
          {
            "value": 1500,
            "elided": null
          },
          {
            "value": null,
            "elided": null
          }
        ],
        "output": {
          "model": "deterministic-visible-book-fill-estimate",
          "side": "buy",
          "requested_quantity": 1500,
          "filled_quantity": 1500,
          "unfilled_quantity": 0,
          "full_fill": true,
          "fills": [
            {
              "level_index": 0,
              "price": 100.01,
              "quantity": 300,
              "notional": 30003
            },
            {
              "level_index": 1,
              "price": 100.02,
              "quantity": 600,
              "notional": 60012
            },
            {
              "level_index": 2,
              "price": 100.03,
              "quantity": 600,
              "notional": 60018
            }
          ],
          "fill_notional": 150033,
          "partial_vwap": 100.022,
          "worst_fill_price": 100.03,
          "best_bid": 99.99,
          "best_ask": 100.01,
          "midpoint": 100,
          "expected_fill_price": 100.022
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 15
        },
        "outputShape": "object with 15 fields: model, side, requested_quantity, filled_quantity, unfilled_quantity, full_fill, fills, fill_notional, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "NYSE Integrated Feed",
          "author": "New York Stock Exchange",
          "url": "https://www.nyse.com/data-products/catalog/integrated-feed"
        },
        {
          "key": "S2",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/market-depth-analytics/expected-market-order-fill-price/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/market-depth-analytics/expected-market-order-fill-price/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F05-A05",
      "name": "Multi-Level Sweep Cost and Slippage",
      "headline": null,
      "slug": "multi-level-sweep-cost-and-slippage",
      "path": "market-microstructure/market-depth-analytics/multi-level-sweep-cost-and-slippage",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F05",
        "family": "Market-Depth Analytics",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/market-depth-analytics/multi-level-sweep-cost-and-slippage",
        "entry": "sweepCostAndSlippage",
        "params": [
          "bids",
          "asks",
          "side",
          "quantity",
          "benchmarkRaw",
          "benchmarkPriceRaw",
          "limitPrice"
        ],
        "exports": [
          "cumulativeDepth",
          "topNDepthImbalance",
          "depthAtDistanceProfile",
          "expectedFillPrice",
          "sweepCostAndSlippage",
          "liquidityWallConcentration",
          "depthDepletionReplenishment",
          "marketDepthHeatmap",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "sweepCostAndSlippage(bids, asks, side, quantity, benchmarkRaw, benchmarkPriceRaw, limitPrice)"
      },
      "api": {
        "summary": "The cost of sweeping multiple levels, measured against a chosen benchmark. Slippage is only meaningful relative to a benchmark, so which one is a parameter rather than an assumption.",
        "params": [
          {
            "name": "bids",
            "type": "Level[]",
            "required": true,
            "description": "Bid levels.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "asks",
            "type": "Level[]",
            "required": true,
            "description": "Ask levels.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "side",
            "type": "\"buy\" | \"sell\"",
            "required": true,
            "description": "Order direction.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "quantity",
            "type": "number",
            "required": true,
            "description": "Order quantity.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "benchmarkRaw",
            "type": "string",
            "required": true,
            "description": "Which benchmark to measure against — touch, midpoint or a supplied price.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "benchmarkPriceRaw",
            "type": "number",
            "required": false,
            "description": "The benchmark price when one is supplied explicitly.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "limitPrice",
            "type": "number",
            "required": false,
            "description": "Optional limit price.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ sweep_cost, slippage_bps, average_price, benchmark_price, … }",
          "description": "Cost and slippage in basis points with the benchmark actually used."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the benchmark is unrecognised, or requires a price that was not supplied",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(levels)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "sweepCostAndSlippage([{\"price\":99.99,\"quantity\":500},{\"price\":99.98,\"quantity\":800},{\"price\":99.97,\"quantity\":1200}], [{\"price\":100.01,\"quantity\":300},{\"price\":100.02,\"quantity\":600},{\"price\":100.03,\"quantity\":1000}], \"buy\", 2600, \"midpoint\", null, null)",
        "args": [
          {
            "value": [
              {
                "price": 99.99,
                "quantity": 500
              },
              {
                "price": 99.98,
                "quantity": 800
              },
              {
                "price": 99.97,
                "quantity": 1200
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": [
              {
                "price": 100.01,
                "quantity": 300
              },
              {
                "price": 100.02,
                "quantity": 600
              },
              {
                "price": 100.03,
                "quantity": 1000
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": "buy",
            "elided": null
          },
          {
            "value": 2600,
            "elided": null
          },
          {
            "value": "midpoint",
            "elided": null
          },
          {
            "value": null,
            "elided": null
          },
          {
            "value": null,
            "elided": null
          }
        ],
        "output": {
          "model": "visible-book-sweep-cost",
          "side": "buy",
          "requested_quantity": 2600,
          "filled_quantity": 2600,
          "unfilled_quantity": 0,
          "full_fill": true,
          "fills": [
            {
              "level_index": 0,
              "price": 100.01,
              "quantity": 300,
              "notional": 30003
            },
            {
              "level_index": 1,
              "price": 100.02,
              "quantity": 600,
              "notional": 60012
            },
            {
              "level_index": 2,
              "price": 100.03,
              "quantity": 1000,
              "notional": 100030
            }
          ],
          "fill_notional": 260073,
          "partial_vwap": 100.02807692307692,
          "worst_fill_price": 100.04,
          "best_bid": 99.99,
          "best_ask": 100.01,
          "midpoint": 100,
          "benchmark": "midpoint"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 20
        },
        "outputShape": "object with 20 fields: model, side, requested_quantity, filled_quantity, unfilled_quantity, full_fill, fills, fill_notional, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "NYSE Integrated Feed",
          "author": "New York Stock Exchange",
          "url": "https://www.nyse.com/data-products/catalog/integrated-feed"
        },
        {
          "key": "S2",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/market-depth-analytics/multi-level-sweep-cost-and-slippage/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/market-depth-analytics/multi-level-sweep-cost-and-slippage/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F05-A06",
      "name": "Liquidity-Wall and Concentration Detection",
      "headline": null,
      "slug": "liquidity-wall-and-concentration-detection",
      "path": "market-microstructure/market-depth-analytics/liquidity-wall-and-concentration-detection",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F05",
        "family": "Market-Depth Analytics",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/market-depth-analytics/liquidity-wall-and-concentration-detection",
        "entry": "liquidityWallConcentration",
        "params": [
          "levelsRaw",
          "multipleRaw",
          "minShareRaw",
          "thresholdRaw"
        ],
        "exports": [
          "cumulativeDepth",
          "topNDepthImbalance",
          "depthAtDistanceProfile",
          "expectedFillPrice",
          "sweepCostAndSlippage",
          "liquidityWallConcentration",
          "depthDepletionReplenishment",
          "marketDepthHeatmap",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "liquidityWallConcentration(levelsRaw, multipleRaw, minShareRaw, thresholdRaw)"
      },
      "api": {
        "summary": "Finds levels holding disproportionate size — the 'walls' that act as short-term barriers. Worth treating with suspicion: a wall that disappears the moment price approaches it was never liquidity.",
        "params": [
          {
            "name": "levelsRaw",
            "type": "Level[]",
            "required": true,
            "description": "Book levels to examine.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "multipleRaw",
            "type": "number",
            "required": true,
            "description": "How many times the average level size counts as a wall.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "minShareRaw",
            "type": "number",
            "required": true,
            "description": "Minimum share of total depth a level must hold.",
            "constraints": {
              "min": 0,
              "max": 1
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "thresholdRaw",
            "type": "number",
            "required": true,
            "description": "Concentration threshold above which the book is flagged as concentrated.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ walls, concentration, flagged, … }",
          "description": "Detected walls with the concentration measure for the book as a whole."
        },
        "warmup": null,
        "errors": [
          {
            "when": "minShareRaw falls outside 0…1",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(levels)",
          "space": "O(walls)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "liquidityWallConcentration([{\"price\":100.01,\"quantity\":100},{\"price\":100.02,\"quantity\":110},{\"price\":100.03,\"quantity\":450}], 2.5, 0.3, 0.3)",
        "args": [
          {
            "value": [
              {
                "price": 100.01,
                "quantity": 100
              },
              {
                "price": 100.02,
                "quantity": 110
              },
              {
                "price": 100.03,
                "quantity": 450
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": 2.5,
            "elided": null
          },
          {
            "value": 0.3,
            "elided": null
          },
          {
            "value": 0.3,
            "elided": null
          }
        ],
        "output": {
          "model": "level-share-concentration-and-wall-screen",
          "level_count": 5,
          "total_depth": 900,
          "median_level_quantity": 120,
          "hhi_fraction": 0.3128395061728395,
          "effective_level_count": 3.196527229676401,
          "largest_level_index": 2,
          "largest_level_share": 0.5,
          "walls": [
            {
              "level_index": 2,
              "price": 100.03,
              "quantity": 450,
              "depth_share": 0.5,
              "median_multiple": 3.75
            }
          ],
          "wall_multiple": 2.5,
          "minimum_share": 0.3,
          "concentration_threshold": 0.3,
          "state": "wall-detected"
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: model, level_count, total_depth, median_level_quantity, hhi_fraction, effective_level_count, largest_level_index, largest_level_share, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a06/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "NYSE Integrated Feed",
          "author": "New York Stock Exchange",
          "url": "https://www.nyse.com/data-products/catalog/integrated-feed"
        },
        {
          "key": "S2",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "S3",
          "title": "Herfindahl-Hirschman Index",
          "author": "U.S. Department of Justice, Antitrust Division",
          "url": "https://www.justice.gov/atr/herfindahl-hirschman-index"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/market-depth-analytics/liquidity-wall-and-concentration-detection/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/market-depth-analytics/liquidity-wall-and-concentration-detection/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F05-A07",
      "name": "Depth Depletion and Replenishment",
      "headline": null,
      "slug": "depth-depletion-and-replenishment",
      "path": "market-microstructure/market-depth-analytics/depth-depletion-and-replenishment",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F05",
        "family": "Market-Depth Analytics",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/market-depth-analytics/depth-depletion-and-replenishment",
        "entry": "depthDepletionReplenishment",
        "params": [
          "seriesRaw"
        ],
        "exports": [
          "cumulativeDepth",
          "topNDepthImbalance",
          "depthAtDistanceProfile",
          "expectedFillPrice",
          "sweepCostAndSlippage",
          "liquidityWallConcentration",
          "depthDepletionReplenishment",
          "marketDepthHeatmap",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "depthDepletionReplenishment(seriesRaw)"
      },
      "api": {
        "summary": "Tracks depth being consumed and refilled over a sequence of snapshots. The pairing matters: depletion without replenishment is a book emptying out, which is the condition preceding a dislocation.",
        "params": [
          {
            "name": "seriesRaw",
            "type": "Snapshot[]",
            "required": true,
            "description": "Sequential book snapshots with per-side depth.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ events, depletion_total, replenishment_total, net, … }",
          "description": "Depletion and replenishment events with their net effect."
        },
        "warmup": null,
        "errors": [
          {
            "when": "fewer than two snapshots are supplied",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(snapshots × levels)",
          "space": "O(events)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "depthDepletionReplenishment([{\"timestamp_seconds\":0,\"quantity\":500},{\"timestamp_seconds\":1,\"quantity\":380},{\"timestamp_seconds\":2,\"quantity\":440}])",
        "args": [
          {
            "value": [
              {
                "timestamp_seconds": 0,
                "quantity": 500
              },
              {
                "timestamp_seconds": 1,
                "quantity": 380
              },
              {
                "timestamp_seconds": 2,
                "quantity": 440
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 6
            }
          }
        ],
        "output": {
          "model": "snapshot-visible-depth-change-decomposition",
          "snapshot_count": 6,
          "start_quantity": 500,
          "end_quantity": 420,
          "gross_depletion": 300,
          "gross_replenishment": 220,
          "net_depth_change": -80,
          "replenishment_to_depletion": 0.7333333333333333,
          "changes": [
            {
              "timestamp_seconds": 1,
              "previous_quantity": 500,
              "quantity": 380,
              "delta_quantity": -120,
              "classification": "depletion"
            },
            {
              "timestamp_seconds": 2,
              "previous_quantity": 380,
              "quantity": 440,
              "delta_quantity": 60,
              "classification": "replenishment"
            },
            {
              "timestamp_seconds": 3,
              "previous_quantity": 440,
              "quantity": 300,
              "delta_quantity": -140,
              "classification": "depletion"
            }
          ],
          "state": "net-depleting"
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: model, snapshot_count, start_quantity, end_quantity, gross_depletion, gross_replenishment, net_depth_change, replenishment_to_depletion, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a07/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "NYSE Integrated Feed",
          "author": "New York Stock Exchange",
          "url": "https://www.nyse.com/data-products/catalog/integrated-feed"
        },
        {
          "key": "S2",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "S3",
          "title": "The Price Impact of Order Book Events",
          "author": "Rama Cont, Arseniy Kukanov, and Sasha Stoikov",
          "url": "https://arxiv.org/abs/1011.6402"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/market-depth-analytics/depth-depletion-and-replenishment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/market-depth-analytics/depth-depletion-and-replenishment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D11-F05-A08",
      "name": "Market-Depth Heatmap Aggregation",
      "headline": null,
      "slug": "market-depth-heatmap-aggregation",
      "path": "market-microstructure/market-depth-analytics/market-depth-heatmap-aggregation",
      "taxonomy": {
        "domainId": "D11",
        "domain": "Market Microstructure",
        "familyId": "D11-F05",
        "family": "Market-Depth Analytics",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/market-microstructure/market-depth-analytics/market-depth-heatmap-aggregation",
        "entry": "marketDepthHeatmap",
        "params": [
          "snapshotsRaw",
          "tickRaw",
          "binRaw",
          "maxRaw"
        ],
        "exports": [
          "cumulativeDepth",
          "topNDepthImbalance",
          "depthAtDistanceProfile",
          "expectedFillPrice",
          "sweepCostAndSlippage",
          "liquidityWallConcentration",
          "depthDepletionReplenishment",
          "marketDepthHeatmap",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "marketDepthHeatmap(snapshotsRaw, tickRaw, binRaw, maxRaw)"
      },
      "api": {
        "summary": "Aggregates a sequence of book snapshots into a time-by-price grid — the data behind a depth heatmap, where persistent liquidity and fleeting quotes look completely different.",
        "params": [
          {
            "name": "snapshotsRaw",
            "type": "Snapshot[]",
            "required": true,
            "description": "Sequential book snapshots.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "tickRaw",
            "type": "number",
            "required": true,
            "description": "Tick size.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "binRaw",
            "type": "number",
            "required": true,
            "description": "Price bin width in ticks.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "maxRaw",
            "type": "number",
            "required": true,
            "description": "Maximum distance from the touch to include.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ grid, bins, snapshots, … }",
          "description": "The aggregated grid with its bin definitions."
        },
        "warmup": null,
        "errors": [
          {
            "when": "tick or bin width is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(snapshots × levels)",
          "space": "O(bins × snapshots)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "marketDepthHeatmap([{\"timestamp_seconds\":0,\"bids\":[{\"price\":99.99,\"quantity\":500},{\"price\":99.98,\"quantity\":700},{\"price\":99.97,\"quantity\":420}],\"asks\":[{\"price\":100.01,\"quantity\":360},{\"price\":100.02,\"quantity\":620},{\"price\":100.03,\"quantity\":460}]},{\"timestamp_seconds\":10,\"bids\":[{\"price\":99.99,\"quantity\":520},{\"price\":99.98,\"quantity\":715},{\"price\":99.97,\"quantity\":430}],\"asks\":[{\"price\":100.01,\"quantity\":375},{\"price\":100.02,\"quantity\":630},{\"price\":100.03,\"quantity\":468}]},{\"timestamp_seconds\":20,\"bids\":[{\"price\":99.99,\"quantity\":540},{\"price\":99.98,\"quantity\":730},{\"price\":99.97,\"quantity\":440}],\"asks\":[{\"price\":100.01,\"quantity\":390},{\"price\":100.02,\"quantity\":640},{\"price\":100.03,\"quantity\":476}]}], 0.01, 30, 2)",
        "args": [
          {
            "value": [
              {
                "timestamp_seconds": 0,
                "bids": [
                  {
                    "price": 99.99,
                    "quantity": 500
                  },
                  {
                    "price": 99.98,
                    "quantity": 700
                  },
                  {
                    "price": 99.97,
                    "quantity": 420
                  }
                ],
                "asks": [
                  {
                    "price": 100.01,
                    "quantity": 360
                  },
                  {
                    "price": 100.02,
                    "quantity": 620
                  },
                  {
                    "price": 100.03,
                    "quantity": 460
                  }
                ]
              },
              {
                "timestamp_seconds": 10,
                "bids": [
                  {
                    "price": 99.99,
                    "quantity": 520
                  },
                  {
                    "price": 99.98,
                    "quantity": 715
                  },
                  {
                    "price": 99.97,
                    "quantity": 430
                  }
                ],
                "asks": [
                  {
                    "price": 100.01,
                    "quantity": 375
                  },
                  {
                    "price": 100.02,
                    "quantity": 630
                  },
                  {
                    "price": 100.03,
                    "quantity": 468
                  }
                ]
              },
              {
                "timestamp_seconds": 20,
                "bids": [
                  {
                    "price": 99.99,
                    "quantity": 540
                  },
                  {
                    "price": 99.98,
                    "quantity": 730
                  },
                  {
                    "price": 99.97,
                    "quantity": 440
                  }
                ],
                "asks": [
                  {
                    "price": 100.01,
                    "quantity": 390
                  },
                  {
                    "price": 100.02,
                    "quantity": 640
                  },
                  {
                    "price": 100.03,
                    "quantity": 476
                  }
                ]
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 12
            }
          },
          {
            "value": 0.01,
            "elided": null
          },
          {
            "value": 30,
            "elided": null
          },
          {
            "value": 2,
            "elided": null
          }
        ],
        "output": {
          "model": "regular-snapshot-inside-relative-depth-heatmap",
          "snapshot_interval_seconds": 10,
          "time_bin_seconds": 30,
          "max_distance_ticks": 2,
          "time_bin_count": 4,
          "book_coordinates": [
            -3,
            -2,
            -1,
            1,
            2,
            3
          ],
          "cells": [
            {
              "time_bin_index": 0,
              "time_bin_start_seconds": 0,
              "book_coordinate": -3,
              "mean_quantity": 430,
              "max_quantity": 440,
              "observation_count": 3
            },
            {
              "time_bin_index": 0,
              "time_bin_start_seconds": 0,
              "book_coordinate": -2,
              "mean_quantity": 715,
              "max_quantity": 730,
              "observation_count": 3
            },
            {
              "time_bin_index": 0,
              "time_bin_start_seconds": 0,
              "book_coordinate": -1,
              "mean_quantity": 520,
              "max_quantity": 540,
              "observation_count": 3
            }
          ],
          "peak_cell": {
            "time_bin_index": 3,
            "time_bin_start_seconds": 90,
            "book_coordinate": -2,
            "mean_quantity": 850,
            "max_quantity": 865,
            "observation_count": 3
          },
          "state": "bid-peak"
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: model, snapshot_interval_seconds, time_bin_seconds, max_distance_ticks, time_bin_count, book_coordinates, cells, peak_cell, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d11-f05-a08/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "NYSE Integrated Feed",
          "author": "New York Stock Exchange",
          "url": "https://www.nyse.com/data-products/catalog/integrated-feed"
        },
        {
          "key": "S2",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/market-microstructure/market-depth-analytics/market-depth-heatmap-aggregation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/market-microstructure/market-depth-analytics/market-depth-heatmap-aggregation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F01-A01",
      "name": "Price-Time Priority",
      "headline": null,
      "slug": "price-time-priority",
      "path": "matching-engines-and-venue-logic/continuous-matching/price-time-priority",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F01",
        "family": "Continuous Matching",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/continuous-matching/price-time-priority",
        "entry": "priceTimePriority",
        "params": [
          "incomingRaw",
          "restingRaw"
        ],
        "exports": [
          "priceTimePriority",
          "proRataMatching",
          "sizeTimePriority",
          "hybridProRataTime",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "priceTimePriority(incomingRaw, restingRaw)"
      },
      "api": {
        "summary": "Matches an incoming order against resting orders by best price, then earliest arrival. The default rule on most equity venues, and the one that makes queue position valuable. Prices and quantities are integer **atoms** — the venue's minimum increment — not floating-point currency. Matching arithmetic that rounds is matching arithmetic that disagrees with the exchange.",
        "params": [
          {
            "name": "incomingRaw",
            "type": "Order",
            "required": true,
            "description": "The aggressing order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "restingRaw",
            "type": "Order[]",
            "required": true,
            "description": "Resting orders with prices, quantities and arrival sequence.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ fills, residual, book_after, … }",
          "description": "Fills in priority order with any residual quantity and the resulting book."
        },
        "warmup": null,
        "errors": [
          {
            "when": "an order has non-integer atoms or a non-positive quantity",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(resting log resting)",
          "space": "O(fills)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "priceTimePriority({\"order_id\":\"B-IN\",\"side\":\"buy\",\"order_type\":\"limit\",\"quantity\":650,\"limit_price\":100.1}, [{\"order_id\":\"S-1\",\"side\":\"sell\",\"price\":100,\"remaining_quantity\":200,\"arrival_sequence\":10},{\"order_id\":\"S-2\",\"side\":\"sell\",\"price\":100,\"remaining_quantity\":300,\"arrival_sequence\":20},{\"order_id\":\"S-3\",\"side\":\"sell\",\"price\":100.05,\"remaining_quantity\":400,\"arrival_sequence\":30}])",
        "args": [
          {
            "value": {
              "order_id": "B-IN",
              "side": "buy",
              "order_type": "limit",
              "quantity": 650,
              "limit_price": 100.1
            },
            "elided": null
          },
          {
            "value": [
              {
                "order_id": "S-1",
                "side": "sell",
                "price": 100,
                "remaining_quantity": 200,
                "arrival_sequence": 10
              },
              {
                "order_id": "S-2",
                "side": "sell",
                "price": 100,
                "remaining_quantity": 300,
                "arrival_sequence": 20
              },
              {
                "order_id": "S-3",
                "side": "sell",
                "price": 100.05,
                "remaining_quantity": 400,
                "arrival_sequence": 30
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 4
            }
          }
        ],
        "output": {
          "model": "single-venue-price-time-priority",
          "incoming_order_id": "B-IN",
          "requested_quantity": 650,
          "filled_quantity": 650,
          "residual_quantity": 0,
          "average_fill_price": 100.01153846153846,
          "fill_count": 3,
          "fills": [
            {
              "resting_order_id": "S-1",
              "price": 100,
              "quantity": 200,
              "arrival_sequence": 10
            },
            {
              "resting_order_id": "S-2",
              "price": 100,
              "quantity": 300,
              "arrival_sequence": 20
            },
            {
              "resting_order_id": "S-3",
              "price": 100.05,
              "quantity": 150,
              "arrival_sequence": 30
            }
          ],
          "final_resting_orders": [
            {
              "order_id": "S-3",
              "side": "sell",
              "price": 100.05,
              "remaining_quantity": 250,
              "arrival_sequence": 30
            },
            {
              "order_id": "S-4",
              "side": "sell",
              "price": 100.1,
              "remaining_quantity": 500,
              "arrival_sequence": 40
            }
          ],
          "state": "filled"
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: model, incoming_order_id, requested_quantity, filled_quantity, residual_quantity, average_fill_price, fill_count, fills, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f01-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Matching principles",
          "author": "Eurex Frankfurt AG",
          "url": "https://www.eurex.com/ex-en/trade/order-book-trading/matching-principles"
        },
        {
          "key": "S2",
          "title": "Matching Algorithm Overview",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/matching-algorithm-overview"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/continuous-matching/price-time-priority/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/continuous-matching/price-time-priority/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F01-A02",
      "name": "Pro-Rata Matching",
      "headline": null,
      "slug": "pro-rata-matching",
      "path": "matching-engines-and-venue-logic/continuous-matching/pro-rata-matching",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F01",
        "family": "Continuous Matching",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/continuous-matching/pro-rata-matching",
        "entry": "proRataMatching",
        "params": [
          "incomingRaw",
          "priceRaw",
          "lotRaw",
          "restingRaw"
        ],
        "exports": [
          "priceTimePriority",
          "proRataMatching",
          "sizeTimePriority",
          "hybridProRataTime",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "proRataMatching(incomingRaw, priceRaw, lotRaw, restingRaw)"
      },
      "api": {
        "summary": "Allocates a fill across all resting orders at a price in proportion to size, ignoring arrival time. Common in some futures markets, and it removes the incentive to queue that price-time creates — participants instead inflate size.",
        "params": [
          {
            "name": "incomingRaw",
            "type": "Order",
            "required": true,
            "description": "The aggressing order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "priceRaw",
            "type": "number",
            "required": true,
            "description": "Price level at which allocation occurs.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "lotRaw",
            "type": "number",
            "required": true,
            "description": "Lot size; allocations round to it, and the rounding remainder must be redistributed rather than lost.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "restingRaw",
            "type": "Order[]",
            "required": true,
            "description": "Resting orders at that price.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ allocations, residual, remainder_handling, … }",
          "description": "Per-order allocation with how the rounding remainder was distributed."
        },
        "warmup": null,
        "errors": [
          {
            "when": "lot size is not a positive integer",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(resting)",
          "space": "O(resting)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "proRataMatching(600, 100, 10, [{\"order_id\":\"R-1\",\"side\":\"sell\",\"price\":100,\"remaining_quantity\":500,\"arrival_sequence\":10},{\"order_id\":\"R-2\",\"side\":\"sell\",\"price\":100,\"remaining_quantity\":300,\"arrival_sequence\":20},{\"order_id\":\"R-3\",\"side\":\"sell\",\"price\":100,\"remaining_quantity\":200,\"arrival_sequence\":30}])",
        "args": [
          {
            "value": 600,
            "elided": null
          },
          {
            "value": 100,
            "elided": null
          },
          {
            "value": 10,
            "elided": null
          },
          {
            "value": [
              {
                "order_id": "R-1",
                "side": "sell",
                "price": 100,
                "remaining_quantity": 500,
                "arrival_sequence": 10
              },
              {
                "order_id": "R-2",
                "side": "sell",
                "price": 100,
                "remaining_quantity": 300,
                "arrival_sequence": 20
              },
              {
                "order_id": "R-3",
                "side": "sell",
                "price": 100,
                "remaining_quantity": 200,
                "arrival_sequence": 30
              }
            ],
            "elided": null
          }
        ],
        "output": {
          "model": "single-price-lot-aware-pro-rata",
          "price": 100,
          "lot_size": 10,
          "incoming_quantity": 600,
          "executable_quantity": 600,
          "allocated_quantity": 600,
          "unfilled_quantity": 0,
          "allocations": [
            {
              "order_id": "R-1",
              "resting_quantity": 500,
              "allocated_quantity": 300,
              "remaining_quantity": 200,
              "arrival_sequence": 10
            },
            {
              "order_id": "R-2",
              "resting_quantity": 300,
              "allocated_quantity": 180,
              "remaining_quantity": 120,
              "arrival_sequence": 20
            },
            {
              "order_id": "R-3",
              "resting_quantity": 200,
              "allocated_quantity": 120,
              "remaining_quantity": 80,
              "arrival_sequence": 30
            }
          ],
          "state": "fully-allocated"
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: model, price, lot_size, incoming_quantity, executable_quantity, allocated_quantity, unfilled_quantity, allocations, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f01-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Matching principles",
          "author": "Eurex Frankfurt AG",
          "url": "https://www.eurex.com/ex-en/trade/order-book-trading/matching-principles"
        },
        {
          "key": "S2",
          "title": "Matching Algorithm Overview",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/matching-algorithm-overview"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/continuous-matching/pro-rata-matching/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/continuous-matching/pro-rata-matching/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F01-A03",
      "name": "Size-Time Priority",
      "headline": null,
      "slug": "size-time-priority",
      "path": "matching-engines-and-venue-logic/continuous-matching/size-time-priority",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F01",
        "family": "Continuous Matching",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/continuous-matching/size-time-priority",
        "entry": "sizeTimePriority",
        "params": [
          "incomingRaw",
          "priceRaw",
          "lotRaw",
          "restingRaw"
        ],
        "exports": [
          "priceTimePriority",
          "proRataMatching",
          "sizeTimePriority",
          "hybridProRataTime",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "sizeTimePriority(incomingRaw, priceRaw, lotRaw, restingRaw)"
      },
      "api": {
        "summary": "Orders by size first and arrival second — rewarding large resting orders. Used where a venue wants to attract size rather than speed.",
        "params": [
          {
            "name": "incomingRaw",
            "type": "Order",
            "required": true,
            "description": "The aggressing order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "priceRaw",
            "type": "number",
            "required": true,
            "description": "Price level.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "lotRaw",
            "type": "number",
            "required": true,
            "description": "Lot size.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "restingRaw",
            "type": "Order[]",
            "required": true,
            "description": "Resting orders at that price.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ fills, residual, ordering, … }",
          "description": "Fills with the priority ordering that produced them."
        },
        "warmup": null,
        "errors": [
          {
            "when": "lot size is not a positive integer",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(resting log resting)",
          "space": "O(fills)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "sizeTimePriority(650, 50, 10, [{\"order_id\":\"ST-1\",\"side\":\"buy\",\"price\":50,\"remaining_quantity\":300,\"arrival_sequence\":10},{\"order_id\":\"ST-2\",\"side\":\"buy\",\"price\":50,\"remaining_quantity\":500,\"arrival_sequence\":30},{\"order_id\":\"ST-3\",\"side\":\"buy\",\"price\":50,\"remaining_quantity\":500,\"arrival_sequence\":20}])",
        "args": [
          {
            "value": 650,
            "elided": null
          },
          {
            "value": 50,
            "elided": null
          },
          {
            "value": 10,
            "elided": null
          },
          {
            "value": [
              {
                "order_id": "ST-1",
                "side": "buy",
                "price": 50,
                "remaining_quantity": 300,
                "arrival_sequence": 10
              },
              {
                "order_id": "ST-2",
                "side": "buy",
                "price": 50,
                "remaining_quantity": 500,
                "arrival_sequence": 30
              },
              {
                "order_id": "ST-3",
                "side": "buy",
                "price": 50,
                "remaining_quantity": 500,
                "arrival_sequence": 20
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 4
            }
          }
        ],
        "output": {
          "model": "single-price-size-then-time-priority",
          "price": 50,
          "lot_size": 10,
          "incoming_quantity": 650,
          "allocated_quantity": 650,
          "unfilled_quantity": 0,
          "ranked_order_ids": [
            "ST-3",
            "ST-2",
            "ST-1",
            "ST-4"
          ],
          "allocations": [
            {
              "rank": 1,
              "order_id": "ST-3",
              "resting_quantity": 500,
              "allocated_quantity": 500,
              "remaining_quantity": 0,
              "arrival_sequence": 20
            },
            {
              "rank": 2,
              "order_id": "ST-2",
              "resting_quantity": 500,
              "allocated_quantity": 150,
              "remaining_quantity": 350,
              "arrival_sequence": 30
            }
          ],
          "state": "fully-allocated"
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: model, price, lot_size, incoming_quantity, allocated_quantity, unfilled_quantity, ranked_order_ids, allocations, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f01-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Turquoise Plato Block Discovery Trading Service Description",
          "author": "London Stock Exchange Group, Turquoise",
          "url": "https://docs.londonstockexchange.com/sites/default/files/documents/turquoise-block-discovery-trading-service-description-v2.29.1.pdf"
        },
        {
          "key": "S2",
          "title": "Matching principles",
          "author": "Eurex Frankfurt AG",
          "url": "https://www.eurex.com/ex-en/trade/order-book-trading/matching-principles"
        },
        {
          "key": "S3",
          "title": "Matching Algorithm Overview",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/matching-algorithm-overview"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/continuous-matching/size-time-priority/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/continuous-matching/size-time-priority/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F01-A04",
      "name": "Hybrid Pro-Rata/Time Matching",
      "headline": null,
      "slug": "hybrid-pro-rata-time-matching",
      "path": "matching-engines-and-venue-logic/continuous-matching/hybrid-pro-rata-time-matching",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F01",
        "family": "Continuous Matching",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/continuous-matching/hybrid-pro-rata-time-matching",
        "entry": "calculate",
        "params": [
          "topicId",
          "inputs"
        ],
        "exports": [
          "priceTimePriority",
          "proRataMatching",
          "sizeTimePriority",
          "hybridProRataTime",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "calculate(topicId, inputs)"
      },
      "api": {
        "summary": "Splits an incoming order between a time-priority portion and a pro-rata portion — the compromise most futures venues actually run, because pure pro-rata invites size inflation and pure price-time invites a latency race.",
        "params": [
          {
            "name": "topicId",
            "type": "string",
            "required": true,
            "description": "Topic identifier selecting the matching variant.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "inputs",
            "type": "MatchingInput",
            "required": true,
            "description": "The aggressing order, the resting book, and the split between the time-priority and pro-rata portions.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ fills, allocations, residual, split, … }",
          "description": "Fills from both portions with the split applied."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the split fractions do not sum to 1",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(resting log resting)",
          "space": "O(fills)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculate(\"D12-F01-A04\", {\"incoming_quantity\":600,\"price\":100,\"lot_size\":1,\"fifo_fraction\":0.4,\"resting_orders\":[{\"order_id\":\"H-1\",\"side\":\"sell\",\"price\":100,\"remaining_quantity\":500,\"arrival_sequence\":10},{\"order_id\":\"H-2\",\"side\":\"sell\",\"price\":100,\"remaining_quantity\":300,\"arrival_sequence\":20},{\"order_id\":\"H-3\",\"side\":\"sell\",\"price\":100,\"remaining_quantity\":200,\"arrival_sequence\":30}]})",
        "args": [
          {
            "value": "D12-F01-A04",
            "elided": null
          },
          {
            "value": {
              "incoming_quantity": 600,
              "price": 100,
              "lot_size": 1,
              "fifo_fraction": 0.4,
              "resting_orders": [
                {
                  "order_id": "H-1",
                  "side": "sell",
                  "price": 100,
                  "remaining_quantity": 500,
                  "arrival_sequence": 10
                },
                {
                  "order_id": "H-2",
                  "side": "sell",
                  "price": 100,
                  "remaining_quantity": 300,
                  "arrival_sequence": 20
                },
                {
                  "order_id": "H-3",
                  "side": "sell",
                  "price": 100,
                  "remaining_quantity": 200,
                  "arrival_sequence": 30
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "model": "single-price-fifo-pro-rata-split",
          "price": 100,
          "lot_size": 1,
          "fifo_fraction": 0.4,
          "incoming_quantity": 600,
          "executable_quantity": 600,
          "fifo_target_quantity": 240,
          "pro_rata_target_quantity": 360,
          "allocated_quantity": 600,
          "unfilled_quantity": 0,
          "allocations": [
            {
              "order_id": "H-1",
              "resting_quantity": 500,
              "fifo_quantity": 240,
              "pro_rata_quantity": 123,
              "allocated_quantity": 363,
              "remaining_quantity": 137,
              "arrival_sequence": 10
            },
            {
              "order_id": "H-2",
              "resting_quantity": 300,
              "fifo_quantity": 0,
              "pro_rata_quantity": 142,
              "allocated_quantity": 142,
              "remaining_quantity": 158,
              "arrival_sequence": 20
            },
            {
              "order_id": "H-3",
              "resting_quantity": 200,
              "fifo_quantity": 0,
              "pro_rata_quantity": 95,
              "allocated_quantity": 95,
              "remaining_quantity": 105,
              "arrival_sequence": 30
            }
          ],
          "state": "fully-allocated"
        },
        "outputElided": null,
        "outputShape": "object with 12 fields: model, price, lot_size, fifo_fraction, incoming_quantity, executable_quantity, fifo_target_quantity, pro_rata_target_quantity, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f01-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "How CME Group Agricultural Markets Operate",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/articles-and-reports/overview-what-makes-ags-markets-work"
        },
        {
          "key": "S2",
          "title": "Matching Algorithm Overview",
          "author": "CME Group",
          "url": "https://www.cmegroup.com/education/matching-algorithm-overview"
        },
        {
          "key": "S3",
          "title": "Matching principles",
          "author": "Eurex Frankfurt AG",
          "url": "https://www.eurex.com/ex-en/trade/order-book-trading/matching-principles"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/continuous-matching/hybrid-pro-rata-time-matching/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/continuous-matching/hybrid-pro-rata-time-matching/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F02-A01",
      "name": "Maximum-Executable-Volume Auction",
      "headline": null,
      "slug": "maximum-executable-volume-auction",
      "path": "matching-engines-and-venue-logic/auctions/maximum-executable-volume-auction",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F02",
        "family": "Auctions",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/auctions/maximum-executable-volume-auction",
        "entry": "maximumExecutableVolumeAuction",
        "params": [
          "ordersRaw",
          "referenceRaw",
          "tickRaw"
        ],
        "exports": [
          "maximumExecutableVolumeAuction",
          "minimumImbalanceTieBreak",
          "openingCrossPrice",
          "closingCrossPrice",
          "volatilityAuctionReopening",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "maximumExecutableVolumeAuction(ordersRaw, referenceRaw, tickRaw)"
      },
      "api": {
        "summary": "Finds the price that crosses the most volume — the first and most important auction criterion. Ties are common, which is why the tie-break rules exist as their own topics. Prices and quantities are integer **atoms** — the venue's minimum increment — not floating-point currency. Matching arithmetic that rounds is matching arithmetic that disagrees with the exchange.",
        "params": [
          {
            "name": "ordersRaw",
            "type": "Order[]",
            "required": true,
            "description": "Auction orders with prices, quantities and sides.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "referenceRaw",
            "type": "number",
            "required": true,
            "description": "Reference price used when criteria tie.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "tickRaw",
            "type": "number",
            "required": true,
            "description": "Tick size in atoms.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ price, executable_volume, candidates, tie, … }",
          "description": "The clearing price and volume, with every tied candidate — a hidden tie is a hidden decision."
        },
        "warmup": null,
        "errors": [
          {
            "when": "no order crosses",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(orders log orders)",
          "space": "O(prices)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "maximumExecutableVolumeAuction([{\"order_id\":\"B-101\",\"side\":\"buy\",\"order_type\":\"limit\",\"price\":101,\"quantity\":300,\"arrival_sequence\":10},{\"order_id\":\"B-100\",\"side\":\"buy\",\"order_type\":\"limit\",\"price\":100,\"quantity\":500,\"arrival_sequence\":20},{\"order_id\":\"S-099\",\"side\":\"sell\",\"order_type\":\"limit\",\"price\":99,\"quantity\":200,\"arrival_sequence\":30}], 100, 1)",
        "args": [
          {
            "value": [
              {
                "order_id": "B-101",
                "side": "buy",
                "order_type": "limit",
                "price": 101,
                "quantity": 300,
                "arrival_sequence": 10
              },
              {
                "order_id": "B-100",
                "side": "buy",
                "order_type": "limit",
                "price": 100,
                "quantity": 500,
                "arrival_sequence": 20
              },
              {
                "order_id": "S-099",
                "side": "sell",
                "order_type": "limit",
                "price": 99,
                "quantity": 200,
                "arrival_sequence": 30
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": 100,
            "elided": null
          },
          {
            "value": 1,
            "elided": null
          }
        ],
        "output": {
          "model": "maximum-executable-volume-candidate-set",
          "reference_price": 100,
          "tick_size": 1,
          "order_count": 5,
          "maximum_executable_quantity": 600,
          "maximum_volume_prices": [
            100
          ],
          "unique_price": 100,
          "candidate_evaluations": [
            {
              "price": 99,
              "buy_quantity": 800,
              "sell_quantity": 200,
              "executable_quantity": 200,
              "imbalance_quantity": 600,
              "absolute_imbalance": 600,
              "imbalance_side": "buy"
            },
            {
              "price": 100,
              "buy_quantity": 800,
              "sell_quantity": 600,
              "executable_quantity": 600,
              "imbalance_quantity": 200,
              "absolute_imbalance": 200,
              "imbalance_side": "buy"
            },
            {
              "price": 101,
              "buy_quantity": 300,
              "sell_quantity": 1100,
              "executable_quantity": 300,
              "imbalance_quantity": -800,
              "absolute_imbalance": 800,
              "imbalance_side": "sell"
            }
          ],
          "state": "unique-maximum"
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: model, reference_price, tick_size, order_count, maximum_executable_quantity, maximum_volume_prices, unique_price, candidate_evaluations, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f02-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "T7 Release 14.0 Functional Reference, Version 3",
          "author": "Deutsche Börse Group",
          "url": "https://www.xetra.com/resource/blob/4591804/afb8a01ba7c00951ad48f8196d9f3732/data/T7_Release_14.0_-_Functional_Reference_Version_3.pdf"
        },
        {
          "key": "S2",
          "title": "Market Model for the Trading Venue Xetra, T7 Release 14.0",
          "author": "Deutsche Börse Cash Market",
          "url": "https://www.xetra.com/xetra-en/technology/t7/system-documentation/release14-0/production"
        },
        {
          "key": "S3",
          "title": "Introduction of T7 Release 14.1",
          "author": "Deutsche Börse Cash Market",
          "url": "https://www.cashmarket.deutsche-boerse.com/cash-en/Stay-Informed/circulars-newsletters/deutsche-boerse-circulars/Introduction-of-T7-Release-14.1-4803320"
        },
        {
          "key": "S4",
          "title": "Nasdaq Equity 4 Trading Rules",
          "author": "The Nasdaq Stock Market LLC",
          "url": "https://listingcenter.nasdaq.com/rulebook/nasdaq/rules/Nasdaq%20Equity%204"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/auctions/maximum-executable-volume-auction/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/auctions/maximum-executable-volume-auction/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F02-A02",
      "name": "Minimum-Imbalance Tie-Break",
      "headline": null,
      "slug": "minimum-imbalance-tie-break",
      "path": "matching-engines-and-venue-logic/auctions/minimum-imbalance-tie-break",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F02",
        "family": "Auctions",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/auctions/minimum-imbalance-tie-break",
        "entry": "minimumImbalanceTieBreak",
        "params": [
          "ordersRaw",
          "referenceRaw",
          "tickRaw"
        ],
        "exports": [
          "maximumExecutableVolumeAuction",
          "minimumImbalanceTieBreak",
          "openingCrossPrice",
          "closingCrossPrice",
          "volatilityAuctionReopening",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "minimumImbalanceTieBreak(ordersRaw, referenceRaw, tickRaw)"
      },
      "api": {
        "summary": "Applies the second auction criterion: among prices crossing equal volume, choose the one leaving the least unfilled imbalance.",
        "params": [
          {
            "name": "ordersRaw",
            "type": "Order[]",
            "required": true,
            "description": "Auction orders.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "referenceRaw",
            "type": "number",
            "required": true,
            "description": "Reference price for further ties.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "tickRaw",
            "type": "number",
            "required": true,
            "description": "Tick size in atoms.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ price, imbalance, side, candidates, … }",
          "description": "The selected price with the residual imbalance and which side it falls on."
        },
        "warmup": null,
        "errors": [
          {
            "when": "no candidate prices are supplied",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(orders log orders)",
          "space": "O(prices)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "minimumImbalanceTieBreak([{\"order_id\":\"B-101\",\"side\":\"buy\",\"order_type\":\"limit\",\"price\":101,\"quantity\":500,\"arrival_sequence\":10},{\"order_id\":\"B-100\",\"side\":\"buy\",\"order_type\":\"limit\",\"price\":100,\"quantity\":100,\"arrival_sequence\":20},{\"order_id\":\"S-099\",\"side\":\"sell\",\"order_type\":\"limit\",\"price\":99,\"quantity\":100,\"arrival_sequence\":30}], 100, 1)",
        "args": [
          {
            "value": [
              {
                "order_id": "B-101",
                "side": "buy",
                "order_type": "limit",
                "price": 101,
                "quantity": 500,
                "arrival_sequence": 10
              },
              {
                "order_id": "B-100",
                "side": "buy",
                "order_type": "limit",
                "price": 100,
                "quantity": 100,
                "arrival_sequence": 20
              },
              {
                "order_id": "S-099",
                "side": "sell",
                "order_type": "limit",
                "price": 99,
                "quantity": 100,
                "arrival_sequence": 30
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          },
          {
            "value": 100,
            "elided": null
          },
          {
            "value": 1,
            "elided": null
          }
        ],
        "output": {
          "model": "maximum-volume-then-minimum-imbalance",
          "reference_price": 100,
          "tick_size": 1,
          "order_count": 5,
          "maximum_executable_quantity": 500,
          "minimum_absolute_imbalance": 100,
          "volume_winner_prices": [
            100,
            101
          ],
          "minimum_imbalance_prices": [
            100
          ],
          "selected_price": 100,
          "candidate_evaluations": [
            {
              "price": 99,
              "buy_quantity": 600,
              "sell_quantity": 100,
              "executable_quantity": 100,
              "imbalance_quantity": 500,
              "absolute_imbalance": 500,
              "imbalance_side": "buy"
            },
            {
              "price": 100,
              "buy_quantity": 600,
              "sell_quantity": 500,
              "executable_quantity": 500,
              "imbalance_quantity": 100,
              "absolute_imbalance": 100,
              "imbalance_side": "buy"
            },
            {
              "price": 101,
              "buy_quantity": 500,
              "sell_quantity": 700,
              "executable_quantity": 500,
              "imbalance_quantity": -200,
              "absolute_imbalance": 200,
              "imbalance_side": "sell"
            }
          ],
          "state": "tie-resolved"
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: model, reference_price, tick_size, order_count, maximum_executable_quantity, minimum_absolute_imbalance, volume_winner_prices, minimum_imbalance_prices, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f02-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "T7 Release 14.0 Functional Reference, Version 3",
          "author": "Deutsche Börse Group",
          "url": "https://www.xetra.com/resource/blob/4591804/afb8a01ba7c00951ad48f8196d9f3732/data/T7_Release_14.0_-_Functional_Reference_Version_3.pdf"
        },
        {
          "key": "S2",
          "title": "Market Model for the Trading Venue Xetra, T7 Release 14.0",
          "author": "Deutsche Börse Cash Market",
          "url": "https://www.xetra.com/xetra-en/technology/t7/system-documentation/release14-0/production"
        },
        {
          "key": "S3",
          "title": "Introduction of T7 Release 14.1",
          "author": "Deutsche Börse Cash Market",
          "url": "https://www.cashmarket.deutsche-boerse.com/cash-en/Stay-Informed/circulars-newsletters/deutsche-boerse-circulars/Introduction-of-T7-Release-14.1-4803320"
        },
        {
          "key": "S4",
          "title": "Nasdaq Equity 4 Trading Rules",
          "author": "The Nasdaq Stock Market LLC",
          "url": "https://listingcenter.nasdaq.com/rulebook/nasdaq/rules/Nasdaq%20Equity%204"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/auctions/minimum-imbalance-tie-break/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/auctions/minimum-imbalance-tie-break/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F02-A03",
      "name": "Opening-Cross Price",
      "headline": null,
      "slug": "opening-cross-price",
      "path": "matching-engines-and-venue-logic/auctions/opening-cross-price",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F02",
        "family": "Auctions",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/auctions/opening-cross-price",
        "entry": "openingCrossPrice",
        "params": [
          "orders",
          "previousClose",
          "tick",
          "low",
          "high"
        ],
        "exports": [
          "maximumExecutableVolumeAuction",
          "minimumImbalanceTieBreak",
          "openingCrossPrice",
          "closingCrossPrice",
          "volatilityAuctionReopening",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "openingCrossPrice(orders, previousClose, tick, low, high)"
      },
      "api": {
        "summary": "Runs the full opening auction: maximum volume, minimum imbalance, then reference-price proximity, bounded by the permitted price range.",
        "params": [
          {
            "name": "orders",
            "type": "Order[]",
            "required": true,
            "description": "Orders entered into the opening auction.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "previousClose",
            "type": "number",
            "required": true,
            "description": "Previous close, the reference for the final tie-break.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "tick",
            "type": "number",
            "required": true,
            "description": "Tick size in atoms.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number",
            "required": true,
            "description": "Lower bound of the permitted opening range.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "high",
            "type": "number",
            "required": true,
            "description": "Upper bound of the permitted range.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ price, volume, imbalance, criterion_applied, … }",
          "description": "The opening price and **which criterion decided it** — the audit trail an exchange has to be able to produce."
        },
        "warmup": null,
        "errors": [
          {
            "when": "low exceeds high, or no order crosses",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(orders log orders)",
          "space": "O(prices)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "openingCrossPrice([{\"order_id\":\"MOO-B\",\"side\":\"buy\",\"order_type\":\"MOO\",\"price\":null,\"quantity\":200,\"arrival_sequence\":10},{\"order_id\":\"LOO-B101\",\"side\":\"buy\",\"order_type\":\"LOO\",\"price\":101,\"quantity\":400,\"arrival_sequence\":20},{\"order_id\":\"LOO-B100\",\"side\":\"buy\",\"order_type\":\"LOO\",\"price\":100,\"quantity\":300,\"arrival_sequence\":30}], 100, 1, 95, 105)",
        "args": [
          {
            "value": [
              {
                "order_id": "MOO-B",
                "side": "buy",
                "order_type": "MOO",
                "price": null,
                "quantity": 200,
                "arrival_sequence": 10
              },
              {
                "order_id": "LOO-B101",
                "side": "buy",
                "order_type": "LOO",
                "price": 101,
                "quantity": 400,
                "arrival_sequence": 20
              },
              {
                "order_id": "LOO-B100",
                "side": "buy",
                "order_type": "LOO",
                "price": 100,
                "quantity": 300,
                "arrival_sequence": 30
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 7
            }
          },
          {
            "value": 100,
            "elided": null
          },
          {
            "value": 1,
            "elided": null
          },
          {
            "value": 95,
            "elided": null
          },
          {
            "value": 105,
            "elided": null
          }
        ],
        "output": {
          "model": "declared-opening-cross",
          "session": "opening",
          "reference_price": 100,
          "collar_low": 95,
          "collar_high": 105,
          "eligible_order_count": 7,
          "selected_price": 100,
          "executed_quantity": 650,
          "buy_quantity": 900,
          "sell_quantity": 650,
          "imbalance_quantity": 250,
          "imbalance_side": "buy",
          "selection_trace": [
            "maximize executable quantity at 650",
            "minimize absolute imbalance at 250",
            "the objective hierarchy leaves one price"
          ],
          "candidate_evaluations": [
            {
              "price": 99,
              "buy_quantity": 900,
              "sell_quantity": 350,
              "executable_quantity": 350,
              "imbalance_quantity": 550,
              "absolute_imbalance": 550,
              "imbalance_side": "buy"
            },
            {
              "price": 100,
              "buy_quantity": 900,
              "sell_quantity": 650,
              "executable_quantity": 650,
              "imbalance_quantity": 250,
              "absolute_imbalance": 250,
              "imbalance_side": "buy"
            },
            {
              "price": 101,
              "buy_quantity": 600,
              "sell_quantity": 1150,
              "executable_quantity": 600,
              "imbalance_quantity": -550,
              "absolute_imbalance": 550,
              "imbalance_side": "sell"
            }
          ]
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 15
        },
        "outputShape": "object with 15 fields: model, session, reference_price, collar_low, collar_high, eligible_order_count, selected_price, executed_quantity, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f02-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Nasdaq Equity 4 Trading Rules",
          "author": "The Nasdaq Stock Market LLC",
          "url": "https://listingcenter.nasdaq.com/rulebook/nasdaq/rules/Nasdaq%20Equity%204"
        },
        {
          "key": "S2",
          "title": "The Nasdaq Opening and Closing Crosses",
          "author": "Nasdaq Trader",
          "url": "https://www.nasdaqtrader.com/Trader.aspx?id=OpenClose"
        },
        {
          "key": "S3",
          "title": "The Nasdaq Stock Market System Settings",
          "author": "Nasdaq Trader",
          "url": "https://www.nasdaqtrader.com/Trader.aspx?id=SYSTEMSETTINGS"
        },
        {
          "key": "S4",
          "title": "T7 Release 14.0 Functional Reference, Version 3",
          "author": "Deutsche Börse Group",
          "url": "https://www.xetra.com/resource/blob/4591804/afb8a01ba7c00951ad48f8196d9f3732/data/T7_Release_14.0_-_Functional_Reference_Version_3.pdf"
        },
        {
          "key": "S5",
          "title": "Introduction of T7 Release 14.1",
          "author": "Deutsche Börse Cash Market",
          "url": "https://www.cashmarket.deutsche-boerse.com/cash-en/Stay-Informed/circulars-newsletters/deutsche-boerse-circulars/Introduction-of-T7-Release-14.1-4803320"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/auctions/opening-cross-price/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/auctions/opening-cross-price/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F02-A04",
      "name": "Closing-Cross Price",
      "headline": null,
      "slug": "closing-cross-price",
      "path": "matching-engines-and-venue-logic/auctions/closing-cross-price",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F02",
        "family": "Auctions",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/auctions/closing-cross-price",
        "entry": "closingCrossPrice",
        "params": [
          "orders",
          "reference",
          "tick",
          "low",
          "high"
        ],
        "exports": [
          "maximumExecutableVolumeAuction",
          "minimumImbalanceTieBreak",
          "openingCrossPrice",
          "closingCrossPrice",
          "volatilityAuctionReopening",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "closingCrossPrice(orders, reference, tick, low, high)"
      },
      "api": {
        "summary": "The closing auction, which sets the price index funds actually trade at. Same criteria as the open, different reference and typically a tighter permitted band.",
        "params": [
          {
            "name": "orders",
            "type": "Order[]",
            "required": true,
            "description": "Orders entered into the closing auction.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "reference",
            "type": "number",
            "required": true,
            "description": "Reference price for tie-breaking.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "tick",
            "type": "number",
            "required": true,
            "description": "Tick size in atoms.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "low",
            "type": "number",
            "required": true,
            "description": "Lower bound of the permitted range.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "high",
            "type": "number",
            "required": true,
            "description": "Upper bound.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ price, volume, imbalance, criterion_applied, … }",
          "description": "The closing price with the deciding criterion."
        },
        "warmup": null,
        "errors": [
          {
            "when": "low exceeds high, or no order crosses",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(orders log orders)",
          "space": "O(prices)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "closingCrossPrice([{\"order_id\":\"MOC-B\",\"side\":\"buy\",\"order_type\":\"MOC\",\"price\":null,\"quantity\":300,\"arrival_sequence\":10},{\"order_id\":\"LOC-B101\",\"side\":\"buy\",\"order_type\":\"LOC\",\"price\":101,\"quantity\":350,\"arrival_sequence\":20},{\"order_id\":\"DAY-B100\",\"side\":\"buy\",\"order_type\":\"DAY\",\"price\":100,\"quantity\":250,\"arrival_sequence\":30}], 100, 1, 95, 105)",
        "args": [
          {
            "value": [
              {
                "order_id": "MOC-B",
                "side": "buy",
                "order_type": "MOC",
                "price": null,
                "quantity": 300,
                "arrival_sequence": 10
              },
              {
                "order_id": "LOC-B101",
                "side": "buy",
                "order_type": "LOC",
                "price": 101,
                "quantity": 350,
                "arrival_sequence": 20
              },
              {
                "order_id": "DAY-B100",
                "side": "buy",
                "order_type": "DAY",
                "price": 100,
                "quantity": 250,
                "arrival_sequence": 30
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 7
            }
          },
          {
            "value": 100,
            "elided": null
          },
          {
            "value": 1,
            "elided": null
          },
          {
            "value": 95,
            "elided": null
          },
          {
            "value": 105,
            "elided": null
          }
        ],
        "output": {
          "model": "declared-closing-cross",
          "session": "closing",
          "reference_price": 100,
          "collar_low": 95,
          "collar_high": 105,
          "eligible_order_count": 7,
          "selected_price": 100,
          "executed_quantity": 700,
          "buy_quantity": 900,
          "sell_quantity": 700,
          "imbalance_quantity": 200,
          "imbalance_side": "buy",
          "selection_trace": [
            "maximize executable quantity at 700",
            "minimize absolute imbalance at 200",
            "the objective hierarchy leaves one price"
          ],
          "candidate_evaluations": [
            {
              "price": 99,
              "buy_quantity": 900,
              "sell_quantity": 400,
              "executable_quantity": 400,
              "imbalance_quantity": 500,
              "absolute_imbalance": 500,
              "imbalance_side": "buy"
            },
            {
              "price": 100,
              "buy_quantity": 900,
              "sell_quantity": 700,
              "executable_quantity": 700,
              "imbalance_quantity": 200,
              "absolute_imbalance": 200,
              "imbalance_side": "buy"
            },
            {
              "price": 101,
              "buy_quantity": 650,
              "sell_quantity": 1150,
              "executable_quantity": 650,
              "imbalance_quantity": -500,
              "absolute_imbalance": 500,
              "imbalance_side": "sell"
            }
          ]
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 15
        },
        "outputShape": "object with 15 fields: model, session, reference_price, collar_low, collar_high, eligible_order_count, selected_price, executed_quantity, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f02-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Nasdaq Equity 4 Trading Rules",
          "author": "The Nasdaq Stock Market LLC",
          "url": "https://listingcenter.nasdaq.com/rulebook/nasdaq/rules/Nasdaq%20Equity%204"
        },
        {
          "key": "S2",
          "title": "The Nasdaq Opening and Closing Crosses",
          "author": "Nasdaq Trader",
          "url": "https://www.nasdaqtrader.com/Trader.aspx?id=OpenClose"
        },
        {
          "key": "S3",
          "title": "The Nasdaq Stock Market System Settings",
          "author": "Nasdaq Trader",
          "url": "https://www.nasdaqtrader.com/Trader.aspx?id=SYSTEMSETTINGS"
        },
        {
          "key": "S4",
          "title": "T7 Release 14.0 Functional Reference, Version 3",
          "author": "Deutsche Börse Group",
          "url": "https://www.xetra.com/resource/blob/4591804/afb8a01ba7c00951ad48f8196d9f3732/data/T7_Release_14.0_-_Functional_Reference_Version_3.pdf"
        },
        {
          "key": "S5",
          "title": "Introduction of T7 Release 14.1",
          "author": "Deutsche Börse Cash Market",
          "url": "https://www.cashmarket.deutsche-boerse.com/cash-en/Stay-Informed/circulars-newsletters/deutsche-boerse-circulars/Introduction-of-T7-Release-14.1-4803320"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/auctions/closing-cross-price/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/auctions/closing-cross-price/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F02-A05",
      "name": "Volatility-Auction Reopening",
      "headline": null,
      "slug": "volatility-auction-reopening",
      "path": "matching-engines-and-venue-logic/auctions/volatility-auction-reopening",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F02",
        "family": "Auctions",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/auctions/volatility-auction-reopening",
        "entry": "volatilityAuctionReopening",
        "params": [
          "inputs"
        ],
        "exports": [
          "maximumExecutableVolumeAuction",
          "minimumImbalanceTieBreak",
          "openingCrossPrice",
          "closingCrossPrice",
          "volatilityAuctionReopening",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "volatilityAuctionReopening(inputs)"
      },
      "api": {
        "summary": "Determines the reopening price after a volatility halt, including whether the auction may conclude at all or must be extended. An auction that reopens outside the band simply extends rather than printing.",
        "params": [
          {
            "name": "inputs",
            "type": "ReopeningInput",
            "required": true,
            "description": "Auction orders with the halt reference, the permitted band, and the extension policy.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, price, extended, band, … }",
          "description": "The reopening price, or an extension decision with the reason."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the extension policy is unrecognised",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(orders log orders)",
          "space": "O(prices)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "volatilityAuctionReopening({\"reference_price\":100,\"dynamic_reference\":100,\"dynamic_band_pct\":0.02,\"static_reference\":98,\"static_band_pct\":0.05,\"potential_continuous_price\":103,\"indicative_auction_price\":101.5,\"extended_band_multiplier\":2,\"executable_quantity\":500})",
        "args": [
          {
            "value": {
              "reference_price": 100,
              "dynamic_reference": 100,
              "dynamic_band_pct": 0.02,
              "static_reference": 98,
              "static_band_pct": 0.05,
              "potential_continuous_price": 103,
              "indicative_auction_price": 101.5,
              "extended_band_multiplier": 2,
              "executable_quantity": 500
            },
            "elided": null
          }
        ],
        "output": {
          "model": "dual-corridor-volatility-auction-reopening",
          "reference_price": 100,
          "potential_continuous_price": 103,
          "dynamic_corridor": [
            98,
            102
          ],
          "static_corridor": [
            93.1,
            102.9
          ],
          "dynamic_breach": true,
          "static_breach": true,
          "triggered": true,
          "indicative_auction_price": 101.5,
          "executable_quantity": 500,
          "expanded_dynamic_corridor": [
            96,
            104
          ],
          "expanded_static_corridor": [
            88.2,
            107.80000000000001
          ],
          "inside_reopening_corridor": true,
          "reopened": true
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 17
        },
        "outputShape": "object with 17 fields: model, reference_price, potential_continuous_price, dynamic_corridor, static_corridor, dynamic_breach, static_breach, triggered, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f02-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "T7 Release 14.0 Functional Reference, Version 3",
          "author": "Deutsche Börse Group",
          "url": "https://www.xetra.com/resource/blob/4591804/afb8a01ba7c00951ad48f8196d9f3732/data/T7_Release_14.0_-_Functional_Reference_Version_3.pdf"
        },
        {
          "key": "S2",
          "title": "Market Model for the Trading Venue Xetra, T7 Release 14.0",
          "author": "Deutsche Börse Cash Market",
          "url": "https://www.xetra.com/xetra-en/technology/t7/system-documentation/release14-0/production"
        },
        {
          "key": "S3",
          "title": "Introduction of T7 Release 14.1",
          "author": "Deutsche Börse Cash Market",
          "url": "https://www.cashmarket.deutsche-boerse.com/cash-en/Stay-Informed/circulars-newsletters/deutsche-boerse-circulars/Introduction-of-T7-Release-14.1-4803320"
        },
        {
          "key": "S4",
          "title": "T7 Trading Parameters: Implied Reference Price and ACE Parameter Classes",
          "author": "Deutsche Börse Cash Market",
          "url": "https://www.cashmarket.deutsche-boerse.com/cash-en/Stay-Informed/circulars-newsletters/deutsche-boerse-circulars/T7-Trading-Parameters-Determination-of-the-Implied-Reference-Price-and-Adjustment-of-Parameter-Classes-in-the-Volatility-Interruption-Model-with-Automated-Corridor-Expansion-ACE--5302636"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/auctions/volatility-auction-reopening/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/auctions/volatility-auction-reopening/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F03-A01",
      "name": "Tick-Size Validation",
      "headline": null,
      "slug": "tick-size-validation",
      "path": "matching-engines-and-venue-logic/order-controls/tick-size-validation",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F03",
        "family": "Order Controls",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/order-controls/tick-size-validation",
        "entry": "tickSizeValidation",
        "params": [
          "price_atoms",
          "tick_size_atoms",
          "price_scale",
          "effective_policy_id"
        ],
        "exports": [
          "tickSizeValidation",
          "priceBandValidation",
          "selfTradePrevention",
          "cancelOnDisconnect",
          "fatFingerLimit",
          "circuitBreakerTrigger",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "tickSizeValidation(price_atoms, tick_size_atoms, price_scale, effective_policy_id)"
      },
      "api": {
        "summary": "Rejects a price that is not a whole multiple of the instrument's tick. Prices and quantities are integer **atoms** — the venue's minimum increment — not floating-point currency. Matching arithmetic that rounds is matching arithmetic that disagrees with the exchange. Validating in floating point is how sub-tick prices reach a book that cannot represent them.",
        "params": [
          {
            "name": "price_atoms",
            "type": "number",
            "required": true,
            "description": "Order price in integer atoms.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "tick_size_atoms",
            "type": "number",
            "required": true,
            "description": "Tick size in atoms.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "price_scale",
            "type": "number",
            "required": true,
            "description": "Decimal scale relating atoms to display currency.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "effective_policy_id",
            "type": "string",
            "required": true,
            "description": "Which tick policy applies; tick size varies by price band on many venues.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ valid, reason, price_atoms, tick_size_atoms, policy_id }",
          "description": "The verdict with the policy applied, so a rejection can be explained to the participant."
        },
        "warmup": null,
        "errors": [
          {
            "when": "tick size is not a positive integer",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "tickSizeValidation(1000500, 100, 10000, \"SYN-US-EQ-2026-A\")",
        "args": [
          {
            "value": 1000500,
            "elided": null
          },
          {
            "value": 100,
            "elided": null
          },
          {
            "value": 10000,
            "elided": null
          },
          {
            "value": "SYN-US-EQ-2026-A",
            "elided": null
          }
        ],
        "output": {
          "effective_policy_id": "SYN-US-EQ-2026-A",
          "price_atoms": 1000500,
          "tick_size_atoms": 100,
          "price_scale": 10000,
          "valid": true,
          "remainder_atoms": 0,
          "lower_valid_price_atoms": 1000500,
          "upper_valid_price_atoms": 1000500,
          "distance_to_lower_atoms": 0,
          "distance_to_upper_atoms": 0,
          "reason": "on-grid",
          "state": "accepted"
        },
        "outputElided": null,
        "outputShape": "object with 12 fields: effective_policy_id, price_atoms, tick_size_atoms, price_scale, valid, remainder_atoms, lower_valid_price_atoms, upper_valid_price_atoms, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f03-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Statement Regarding Minimum Pricing Increments and Access Fee Caps",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/newsroom/speeches-statements/atkins-statement-minimum-pricing-increments-access-fee-caps-061126"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/order-controls/tick-size-validation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/order-controls/tick-size-validation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F03-A02",
      "name": "Price-Band Validation",
      "headline": null,
      "slug": "price-band-validation",
      "path": "matching-engines-and-venue-logic/order-controls/price-band-validation",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F03",
        "family": "Order Controls",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/order-controls/price-band-validation",
        "entry": "priceBandValidation",
        "params": [
          "side",
          "limit_price_atoms",
          "lower_band_atoms",
          "upper_band_atoms",
          "band_as_of_ns",
          "inclusive"
        ],
        "exports": [
          "tickSizeValidation",
          "priceBandValidation",
          "selfTradePrevention",
          "cancelOnDisconnect",
          "fatFingerLimit",
          "circuitBreakerTrigger",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "priceBandValidation(side, limit_price_atoms, lower_band_atoms, upper_band_atoms, band_as_of_ns, inclusive)"
      },
      "api": {
        "summary": "Checks a limit price against the venue's dynamic price band. Bands move with the reference price, so a valid order becomes invalid moments later — which is why the band's as-of time is part of the check.",
        "params": [
          {
            "name": "side",
            "type": "\"buy\" | \"sell\"",
            "required": true,
            "description": "Order side, which decides which bound binds.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "limit_price_atoms",
            "type": "number",
            "required": true,
            "description": "Limit price in atoms.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "lower_band_atoms",
            "type": "number",
            "required": true,
            "description": "Lower band in atoms.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "upper_band_atoms",
            "type": "number",
            "required": true,
            "description": "Upper band in atoms.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "band_as_of_ns",
            "type": "number",
            "required": true,
            "description": "Nanosecond timestamp the band was published, so a stale band is detectable.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "inclusive",
            "type": "boolean",
            "required": true,
            "description": "Whether prices exactly on the band are accepted.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ valid, reason, band_as_of_ns, … }",
          "description": "The verdict with the band version applied."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the lower band exceeds the upper band",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "priceBandValidation(\"buy\", 1020000, 950000, 1050000, 1200000000, true)",
        "args": [
          {
            "value": "buy",
            "elided": null
          },
          {
            "value": 1020000,
            "elided": null
          },
          {
            "value": 950000,
            "elided": null
          },
          {
            "value": 1050000,
            "elided": null
          },
          {
            "value": 1200000000,
            "elided": null
          },
          {
            "value": true,
            "elided": null
          }
        ],
        "output": {
          "side": "buy",
          "limit_price_atoms": 1020000,
          "lower_band_atoms": 950000,
          "upper_band_atoms": 1050000,
          "band_as_of_ns": 1200000000,
          "inclusive": true,
          "valid": true,
          "distance_from_lower_atoms": 70000,
          "distance_to_upper_atoms": 30000,
          "violation_atoms": 0,
          "reason": "inside-band",
          "state": "accepted"
        },
        "outputElided": null,
        "outputShape": "object with 12 fields: side, limit_price_atoms, lower_band_atoms, upper_band_atoms, band_as_of_ns, inclusive, valid, distance_from_lower_atoms, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f03-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Plan to Address Extraordinary Market Volatility",
          "author": "Limit Up-Limit Down Plan participants",
          "url": "https://www.luldplan.com/plans"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/order-controls/price-band-validation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/order-controls/price-band-validation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F03-A03",
      "name": "Self-Trade Prevention",
      "headline": null,
      "slug": "self-trade-prevention",
      "path": "matching-engines-and-venue-logic/order-controls/self-trade-prevention",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F03",
        "family": "Order Controls",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/order-controls/self-trade-prevention",
        "entry": "selfTradePrevention",
        "params": [
          "incoming_order",
          "resting_orders",
          "mode"
        ],
        "exports": [
          "tickSizeValidation",
          "priceBandValidation",
          "selfTradePrevention",
          "cancelOnDisconnect",
          "fatFingerLimit",
          "circuitBreakerTrigger",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "selfTradePrevention(incoming_order, resting_orders, mode)"
      },
      "api": {
        "summary": "Stops a participant trading with itself — required by most venues, and the *mode* determines who loses their order. Cancel-newest, cancel-oldest and cancel-both give materially different outcomes for queue position.",
        "params": [
          {
            "name": "incoming_order",
            "type": "Order",
            "required": true,
            "description": "The aggressing order with its participant identifier.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "resting_orders",
            "type": "Order[]",
            "required": true,
            "description": "Resting orders that would otherwise match.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "mode",
            "type": "string",
            "required": true,
            "description": "Prevention mode — cancel newest, cancel oldest, cancel both, or decrement.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ action, cancelled, remaining, mode, … }",
          "description": "Which orders were cancelled and which survive, under the mode applied."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the mode is unrecognised",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(resting)",
          "space": "O(cancelled)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "selfTradePrevention({\"order_id\":\"IN-1\",\"side\":\"buy\",\"price_atoms\":1000200,\"quantity\":600,\"participant_id\":\"P-1\",\"stp_group\":\"G-1\"}, [{\"order_id\":\"R-EXT-1\",\"side\":\"sell\",\"price_atoms\":1000000,\"quantity\":150,\"participant_id\":\"P-EXT\",\"stp_group\":\"G-X\",\"sequence\":1},{\"order_id\":\"R-SELF\",\"side\":\"sell\",\"price_atoms\":1000100,\"quantity\":220,\"participant_id\":\"P-1\",\"stp_group\":\"G-1\",\"sequence\":2},{\"order_id\":\"R-EXT-2\",\"side\":\"sell\",\"price_atoms\":1000200,\"quantity\":300,\"participant_id\":\"P-EXT\",\"stp_group\":\"G-X\",\"sequence\":3}], \"cancel_newest\")",
        "args": [
          {
            "value": {
              "order_id": "IN-1",
              "side": "buy",
              "price_atoms": 1000200,
              "quantity": 600,
              "participant_id": "P-1",
              "stp_group": "G-1"
            },
            "elided": null
          },
          {
            "value": [
              {
                "order_id": "R-EXT-1",
                "side": "sell",
                "price_atoms": 1000000,
                "quantity": 150,
                "participant_id": "P-EXT",
                "stp_group": "G-X",
                "sequence": 1
              },
              {
                "order_id": "R-SELF",
                "side": "sell",
                "price_atoms": 1000100,
                "quantity": 220,
                "participant_id": "P-1",
                "stp_group": "G-1",
                "sequence": 2
              },
              {
                "order_id": "R-EXT-2",
                "side": "sell",
                "price_atoms": 1000200,
                "quantity": 300,
                "participant_id": "P-EXT",
                "stp_group": "G-X",
                "sequence": 3
              }
            ],
            "elided": null
          },
          {
            "value": "cancel_newest",
            "elided": null
          }
        ],
        "output": {
          "mode": "cancel_newest",
          "incoming_order_id": "IN-1",
          "original_incoming_quantity": 600,
          "external_executed_quantity": 150,
          "prevented_self_quantity": 220,
          "canceled_incoming_quantity": 450,
          "canceled_resting_quantity": 0,
          "remaining_incoming_quantity": 0,
          "events": [
            {
              "action": "execute-external",
              "incoming_order_id": "IN-1",
              "resting_order_id": "R-EXT-1",
              "quantity": 150,
              "price_atoms": 1000000
            },
            {
              "action": "cancel-incoming",
              "incoming_order_id": "IN-1",
              "resting_order_id": "R-SELF",
              "prevented_quantity": 220
            }
          ],
          "resting_orders": [
            {
              "order_id": "R-SELF",
              "side": "sell",
              "price_atoms": 1000100,
              "quantity": 220,
              "participant_id": "P-1",
              "stp_group": "G-1",
              "sequence": 2
            },
            {
              "order_id": "R-EXT-2",
              "side": "sell",
              "price_atoms": 1000200,
              "quantity": 300,
              "participant_id": "P-EXT",
              "stp_group": "G-X",
              "sequence": 3
            }
          ],
          "state": "self-trade-prevented"
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: mode, incoming_order_id, original_incoming_quantity, external_executed_quantity, prevented_self_quantity, canceled_incoming_quantity, canceled_resting_quantity, remaining_incoming_quantity, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f03-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Nasdaq OUCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/content/technicalsupport/specifications/TradingProducts/OUCH5.0.pdf"
        },
        {
          "key": "S2",
          "title": "Cboe U.S. Equities Match Trade Prevention",
          "author": "Cboe Global Markets",
          "url": "https://cdn.cboe.com/resources/membership/Cboe_US_Equities_MTP.pdf"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/order-controls/self-trade-prevention/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/order-controls/self-trade-prevention/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F03-A04",
      "name": "Cancel-on-Disconnect",
      "headline": null,
      "slug": "cancel-on-disconnect",
      "path": "matching-engines-and-venue-logic/order-controls/cancel-on-disconnect",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F03",
        "family": "Order Controls",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/order-controls/cancel-on-disconnect",
        "entry": "cancelOnDisconnect",
        "params": [
          "disconnected_session_id",
          "disconnect_type",
          "trigger_disconnect_types",
          "policy",
          "orders"
        ],
        "exports": [
          "tickSizeValidation",
          "priceBandValidation",
          "selfTradePrevention",
          "cancelOnDisconnect",
          "fatFingerLimit",
          "circuitBreakerTrigger",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "cancelOnDisconnect(disconnected_session_id, disconnect_type, trigger_disconnect_types, policy, orders)"
      },
      "api": {
        "summary": "Decides which orders to pull when a session drops. Not every disconnect should cancel — a deliberate logout and a network failure are different events, and cancelling a hedge because of a brief blip is its own risk.",
        "params": [
          {
            "name": "disconnected_session_id",
            "type": "string",
            "required": true,
            "description": "The session that dropped.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "disconnect_type",
            "type": "string",
            "required": true,
            "description": "How it dropped — graceful, timeout or transport failure.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "trigger_disconnect_types",
            "type": "string[]",
            "required": true,
            "description": "Which disconnect types actually trigger cancellation.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "policy",
            "type": "string",
            "required": true,
            "description": "Cancellation scope: session, participant or firm.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "orders",
            "type": "Order[]",
            "required": true,
            "description": "Live orders to evaluate.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ cancelled, retained, triggered, policy, … }",
          "description": "Orders cancelled and retained, with whether the disconnect type triggered at all."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the policy is unrecognised",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(orders)",
          "space": "O(cancelled)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "cancelOnDisconnect(\"S-1\", \"hard\", [\"hard\",\"graceful\",\"server\"], \"cancel_continuous\", [{\"order_id\":\"O-1\",\"session_id\":\"S-1\",\"book\":\"continuous\",\"time_in_force\":\"DAY\",\"quantity\":100},{\"order_id\":\"O-2\",\"session_id\":\"S-1\",\"book\":\"continuous\",\"time_in_force\":\"GTC\",\"quantity\":200},{\"order_id\":\"O-3\",\"session_id\":\"S-1\",\"book\":\"auction\",\"time_in_force\":\"DAY\",\"quantity\":300}])",
        "args": [
          {
            "value": "S-1",
            "elided": null
          },
          {
            "value": "hard",
            "elided": null
          },
          {
            "value": [
              "hard",
              "graceful",
              "server"
            ],
            "elided": null
          },
          {
            "value": "cancel_continuous",
            "elided": null
          },
          {
            "value": [
              {
                "order_id": "O-1",
                "session_id": "S-1",
                "book": "continuous",
                "time_in_force": "DAY",
                "quantity": 100
              },
              {
                "order_id": "O-2",
                "session_id": "S-1",
                "book": "continuous",
                "time_in_force": "GTC",
                "quantity": 200
              },
              {
                "order_id": "O-3",
                "session_id": "S-1",
                "book": "auction",
                "time_in_force": "DAY",
                "quantity": 300
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 4
            }
          }
        ],
        "output": {
          "disconnected_session_id": "S-1",
          "disconnect_type": "hard",
          "triggered": true,
          "policy": "cancel_continuous",
          "canceled_order_ids": [
            "O-1",
            "O-2"
          ],
          "retained_orders": [
            {
              "order_id": "O-3",
              "reason": "auction-order-retained"
            },
            {
              "order_id": "O-4",
              "reason": "different-session"
            }
          ],
          "canceled_count": 2,
          "retained_count": 2,
          "state": "purge-applied"
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: disconnected_session_id, disconnect_type, triggered, policy, canceled_order_ids, retained_orders, canceled_count, retained_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f03-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Nasdaq Introduces Changes to Cancel on Disconnect Functionality",
          "author": "Nasdaq",
          "url": "https://www.nasdaqtrader.com/TraderNews.aspx?id=ETA2016-129"
        },
        {
          "key": "S2",
          "title": "Cboe Titanium U.S. Equities FIX Specification",
          "author": "Cboe Global Markets",
          "url": "https://www.cboe.com/document/tech-spec/document/technical-specifications/cboe-titanium-u.s.-equities-fix-specification"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/order-controls/cancel-on-disconnect/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/order-controls/cancel-on-disconnect/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F03-A05",
      "name": "Fat-Finger Limit",
      "headline": null,
      "slug": "fat-finger-limit",
      "path": "matching-engines-and-venue-logic/order-controls/fat-finger-limit",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F03",
        "family": "Order Controls",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/order-controls/fat-finger-limit",
        "entry": "fatFingerLimit",
        "params": [
          "side",
          "limit_price_atoms",
          "reference_price_atoms",
          "quantity",
          "max_quantity",
          "max_notional_atoms",
          "max_aggressive_deviation_bps"
        ],
        "exports": [
          "tickSizeValidation",
          "priceBandValidation",
          "selfTradePrevention",
          "cancelOnDisconnect",
          "fatFingerLimit",
          "circuitBreakerTrigger",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "fatFingerLimit(side, limit_price_atoms, reference_price_atoms, quantity, max_quantity, max_notional_atoms, max_aggressive_deviation_bps)"
      },
      "api": {
        "summary": "Blocks obviously erroneous orders on quantity, notional and aggressive price deviation. The last automated check between a mistyped order and a market-wide incident.",
        "params": [
          {
            "name": "side",
            "type": "\"buy\" | \"sell\"",
            "required": true,
            "description": "Order side.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "limit_price_atoms",
            "type": "number",
            "required": true,
            "description": "Limit price in atoms.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "reference_price_atoms",
            "type": "number",
            "required": true,
            "description": "Reference price the deviation is measured against.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "quantity",
            "type": "number",
            "required": true,
            "description": "Order quantity.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "max_quantity",
            "type": "number",
            "required": true,
            "description": "Maximum permitted quantity.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "max_notional_atoms",
            "type": "number",
            "required": true,
            "description": "Maximum permitted notional in atoms.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "max_aggressive_deviation_bps",
            "type": "number",
            "required": true,
            "description": "Maximum permitted aggressive deviation from the reference, in basis points.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ valid, breached_checks, quantity, notional, deviation_bps }",
          "description": "Which specific checks failed rather than a bare rejection — a participant cannot correct what they are not told."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a limit is negative",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "fatFingerLimit(\"buy\", 1015000, 1000000, 4000, 5000, 5000000000, 200)",
        "args": [
          {
            "value": "buy",
            "elided": null
          },
          {
            "value": 1015000,
            "elided": null
          },
          {
            "value": 1000000,
            "elided": null
          },
          {
            "value": 4000,
            "elided": null
          },
          {
            "value": 5000,
            "elided": null
          },
          {
            "value": 5000000000,
            "elided": null
          },
          {
            "value": 200,
            "elided": null
          }
        ],
        "output": {
          "side": "buy",
          "limit_price_atoms": 1015000,
          "reference_price_atoms": 1000000,
          "quantity": 4000,
          "order_notional_atoms": 4060000000,
          "aggressive_deviation_bps": 150,
          "checks": {
            "quantity": {
              "value": 4000,
              "limit": 5000,
              "passed": true
            },
            "notional": {
              "value": 4060000000,
              "limit": 5000000000,
              "passed": true
            },
            "aggressive_deviation_bps": {
              "value": 150,
              "limit": 200,
              "passed": true
            }
          },
          "violations": [],
          "valid": true,
          "reason": "within-configured-limits",
          "state": "accepted"
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: side, limit_price_atoms, reference_price_atoms, quantity, order_notional_atoms, aggressive_deviation_bps, checks, violations, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f03-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Cboe Titanium U.S. Equities/Options Web Portal Port Controls Specification",
          "author": "Cboe Global Markets",
          "url": "https://www.cboe.com/document/tech-spec/document/technical-specifications/cboe-titanium-u.s.-equitiesoptions-web-portal-port-controls-specification"
        },
        {
          "key": "S2",
          "title": "Cboe Titanium U.S. Equities FIX Specification",
          "author": "Cboe Global Markets",
          "url": "https://www.cboe.com/document/tech-spec/document/technical-specifications/cboe-titanium-u.s.-equities-fix-specification"
        },
        {
          "key": "S3",
          "title": "Commission Delegated Regulation (EU) 2017/584",
          "author": "European Commission",
          "url": "https://eur-lex.europa.eu/legal-content/EN/ALL/?uri=CELEX%3A32017R0584"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/order-controls/fat-finger-limit/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/order-controls/fat-finger-limit/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F03-A06",
      "name": "Circuit-Breaker Trigger",
      "headline": null,
      "slug": "circuit-breaker-trigger",
      "path": "matching-engines-and-venue-logic/order-controls/circuit-breaker-trigger",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F03",
        "family": "Order Controls",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/order-controls/circuit-breaker-trigger",
        "entry": "circuitBreakerTrigger",
        "params": [
          "reference_close_atoms",
          "current_index_atoms",
          "level_thresholds_bps",
          "previously_triggered_level"
        ],
        "exports": [
          "tickSizeValidation",
          "priceBandValidation",
          "selfTradePrevention",
          "cancelOnDisconnect",
          "fatFingerLimit",
          "circuitBreakerTrigger",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "circuitBreakerTrigger(reference_close_atoms, current_index_atoms, level_thresholds_bps, previously_triggered_level)"
      },
      "api": {
        "summary": "Evaluates market-wide circuit breaker levels against the index move. Levels are sequential — once a level has fired it cannot fire again the same session, which is why the previously-triggered level is an input.",
        "params": [
          {
            "name": "reference_close_atoms",
            "type": "number",
            "required": true,
            "description": "Prior close the move is measured from, in atoms.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "current_index_atoms",
            "type": "number",
            "required": true,
            "description": "Current index level in atoms.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "level_thresholds_bps",
            "type": "number[]",
            "required": true,
            "description": "Thresholds in basis points, ascending.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "previously_triggered_level",
            "type": "number",
            "required": true,
            "description": "Highest level already triggered this session; 0 if none.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ triggered, level, decline_bps, halt_required, … }",
          "description": "Whether a breaker fires, at which level, and the measured decline."
        },
        "warmup": null,
        "errors": [
          {
            "when": "thresholds are not ascending",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(levels)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "circuitBreakerTrigger(4000000, 3480000, [700,1300,2000], 1)",
        "args": [
          {
            "value": 4000000,
            "elided": null
          },
          {
            "value": 3480000,
            "elided": null
          },
          {
            "value": [
              700,
              1300,
              2000
            ],
            "elided": null
          },
          {
            "value": 1,
            "elided": null
          }
        ],
        "output": {
          "reference_close_atoms": 4000000,
          "current_index_atoms": 3480000,
          "decline_bps": 1300,
          "level_thresholds_bps": [
            700,
            1300,
            2000
          ],
          "previously_triggered_level": 1,
          "reached_level": 2,
          "newly_triggered_level": 2,
          "newly_triggered": true,
          "action": "level-2-halt",
          "next_threshold_bps": 2000,
          "distance_to_next_threshold_bps": 700,
          "state": "triggered"
        },
        "outputElided": null,
        "outputShape": "object with 12 fields: reference_close_atoms, current_index_atoms, decline_bps, level_thresholds_bps, previously_triggered_level, reached_level, newly_triggered_level, newly_triggered, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f03-a06/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "SEC Approves Proposals to Address Extraordinary Volatility in Individual Stocks and Broader Stock Market",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/newsroom/press-releases/2012-2012-107htm"
        },
        {
          "key": "S2",
          "title": "Market-Wide Circuit Breakers FAQ",
          "author": "New York Stock Exchange",
          "url": "https://www.nyse.com/publicdocs/nyse/NYSE_MWCB_FAQ.pdf"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/order-controls/circuit-breaker-trigger/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/order-controls/circuit-breaker-trigger/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F04-A01",
      "name": "Limit-Order Lifecycle State Machine",
      "headline": null,
      "slug": "limit-order-lifecycle-state-machine",
      "path": "matching-engines-and-venue-logic/order-lifecycle-and-queue-state/limit-order-lifecycle-state-machine",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F04",
        "family": "Order Lifecycle and Queue State",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/limit-order-lifecycle-state-machine",
        "entry": "limitOrderLifecycle",
        "params": [
          "orderIdRaw",
          "orderQuantityRaw",
          "eventsRaw"
        ],
        "exports": [
          "limitOrderLifecycle",
          "cancelReplacePriority",
          "partialFillResidual",
          "queuePositionAheadVolume",
          "icebergReplenishment",
          "marketableOrderSweep",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "limitOrderLifecycle(orderIdRaw, orderQuantityRaw, eventsRaw)"
      },
      "api": {
        "summary": "Replays an order's events into its state history — new, partially filled, replaced, cancelled, done. The value is rejecting *invalid* transitions: a fill after a cancel is a bug somewhere upstream, and it must not be absorbed silently.",
        "params": [
          {
            "name": "orderIdRaw",
            "type": "string",
            "required": true,
            "description": "The order being tracked.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "orderQuantityRaw",
            "type": "number",
            "required": true,
            "description": "Original order quantity.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "eventsRaw",
            "type": "Event[]",
            "required": true,
            "description": "Lifecycle events in sequence.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ states, final_state, invalid_transitions, filled, residual, … }",
          "description": "The state path with any invalid transitions named rather than absorbed."
        },
        "warmup": null,
        "errors": [
          {
            "when": "an event references a different order id",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(events)",
          "space": "O(events)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "limitOrderLifecycle(\"L-100\", 1000, [{\"type\":\"accept\"},{\"type\":\"fill\",\"quantity\":300,\"price\":100},{\"type\":\"fill\",\"quantity\":500,\"price\":100.01}])",
        "args": [
          {
            "value": "L-100",
            "elided": null
          },
          {
            "value": 1000,
            "elided": null
          },
          {
            "value": [
              {
                "type": "accept"
              },
              {
                "type": "fill",
                "quantity": 300,
                "price": 100
              },
              {
                "type": "fill",
                "quantity": 500,
                "price": 100.01
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 4
            }
          }
        ],
        "output": {
          "model": "accepted-order-lifecycle-state-machine",
          "order_id": "L-100",
          "order_quantity": 1000,
          "cumulative_quantity": 1000,
          "leaves_quantity": 0,
          "average_fill_price": 100.009,
          "execution_count": 3,
          "status": "filled",
          "terminal": true,
          "transitions": [
            {
              "event_index": 0,
              "event_type": "accept",
              "before_status": "pending-new",
              "after_status": "new",
              "cumulative_quantity": 0,
              "leaves_quantity": 1000
            },
            {
              "event_index": 1,
              "event_type": "fill",
              "before_status": "new",
              "after_status": "partially-filled",
              "cumulative_quantity": 300,
              "leaves_quantity": 700
            },
            {
              "event_index": 2,
              "event_type": "fill",
              "before_status": "partially-filled",
              "after_status": "partially-filled",
              "cumulative_quantity": 800,
              "leaves_quantity": 200
            }
          ],
          "state": "filled"
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: model, order_id, order_quantity, cumulative_quantity, leaves_quantity, average_fill_price, execution_count, status, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f04-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Order State Changes",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/online-specification/order-state-changes/"
        },
        {
          "key": "S2",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "S3",
          "title": "Nasdaq Equity 4 — Equity Rules",
          "author": "The Nasdaq Stock Market LLC",
          "url": "https://listingcenter.nasdaq.com/rulebook/nasdaq/rules/Nasdaq%20Equity%204"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/limit-order-lifecycle-state-machine/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/limit-order-lifecycle-state-machine/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F04-A02",
      "name": "Cancel/Replace Priority Rule",
      "headline": null,
      "slug": "cancel-replace-priority-rule",
      "path": "matching-engines-and-venue-logic/order-lifecycle-and-queue-state/cancel-replace-priority-rule",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F04",
        "family": "Order Lifecycle and Queue State",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/cancel-replace-priority-rule",
        "entry": "cancelReplacePriority",
        "params": [
          "originalRaw",
          "replacementRaw"
        ],
        "exports": [
          "limitOrderLifecycle",
          "cancelReplacePriority",
          "partialFillResidual",
          "queuePositionAheadVolume",
          "icebergReplenishment",
          "marketableOrderSweep",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "cancelReplacePriority(originalRaw, replacementRaw)"
      },
      "api": {
        "summary": "Decides whether an amendment keeps queue position. Reducing quantity usually keeps it; raising quantity or changing price loses it. This one rule determines whether an amend is nearly free or extremely expensive.",
        "params": [
          {
            "name": "originalRaw",
            "type": "Order",
            "required": true,
            "description": "The resting order before amendment.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "replacementRaw",
            "type": "Order",
            "required": true,
            "description": "The requested replacement.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ priority_retained, reason, new_sequence, … }",
          "description": "Whether priority survives and the reason — the reason is what a participant needs to design around."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the replacement changes side or instrument",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "cancelReplacePriority({\"order_id\":\"O-1\",\"order_type\":\"displayed-limit\",\"price\":100,\"remaining_quantity\":1000,\"priority_sequence\":42}, {\"order_id\":\"O-2\",\"price\":100,\"remaining_quantity\":600,\"replace_sequence\":80})",
        "args": [
          {
            "value": {
              "order_id": "O-1",
              "order_type": "displayed-limit",
              "price": 100,
              "remaining_quantity": 1000,
              "priority_sequence": 42
            },
            "elided": null
          },
          {
            "value": {
              "order_id": "O-2",
              "price": 100,
              "remaining_quantity": 600,
              "replace_sequence": 80
            },
            "elided": null
          }
        ],
        "output": {
          "model": "nasdaq-style-displayed-limit-priority-rule",
          "original_order_id": "O-1",
          "replacement_order_id": "O-2",
          "original_price": 100,
          "replacement_price": 100,
          "original_remaining_quantity": 1000,
          "replacement_remaining_quantity": 600,
          "same_price": true,
          "decrease_only": true,
          "priority_preserved": true,
          "original_priority_sequence": 42,
          "effective_priority_sequence": 42,
          "reason": "same-price quantity decrease preserves canonical displayed-order priority",
          "state": "priority-preserved"
        },
        "outputElided": null,
        "outputShape": "object with 14 fields: model, original_order_id, replacement_order_id, original_price, replacement_price, original_remaining_quantity, replacement_remaining_quantity, same_price, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f04-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Order State Changes",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/online-specification/order-state-changes/"
        },
        {
          "key": "S2",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "S3",
          "title": "Nasdaq Equity 4 — Equity Rules",
          "author": "The Nasdaq Stock Market LLC",
          "url": "https://listingcenter.nasdaq.com/rulebook/nasdaq/rules/Nasdaq%20Equity%204"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/cancel-replace-priority-rule/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/cancel-replace-priority-rule/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F04-A03",
      "name": "Partial-Fill and Residual-Quantity Processing",
      "headline": null,
      "slug": "partial-fill-and-residual-quantity-processing",
      "path": "matching-engines-and-venue-logic/order-lifecycle-and-queue-state/partial-fill-and-residual-quantity-processing",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F04",
        "family": "Order Lifecycle and Queue State",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/partial-fill-and-residual-quantity-processing",
        "entry": "partialFillResidual",
        "params": [
          "orderQuantityRaw",
          "fillsRaw"
        ],
        "exports": [
          "limitOrderLifecycle",
          "cancelReplacePriority",
          "partialFillResidual",
          "queuePositionAheadVolume",
          "icebergReplenishment",
          "marketableOrderSweep",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "partialFillResidual(orderQuantityRaw, fillsRaw)"
      },
      "api": {
        "summary": "Tracks cumulative fills against an order and computes the residual. Over-fill is impossible on a correct venue, so detecting it is detecting a defect rather than handling a case.",
        "params": [
          {
            "name": "orderQuantityRaw",
            "type": "number",
            "required": true,
            "description": "Original order quantity.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "fillsRaw",
            "type": "Fill[]",
            "required": true,
            "description": "Fills in sequence, each with a quantity.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ filled, residual, over_filled, fills, … }",
          "description": "Cumulative filled and residual quantity, with an explicit over-fill flag."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a fill quantity is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(fills)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "partialFillResidual(1200, [{\"execution_id\":\"E-1\",\"quantity\":300,\"price\":100},{\"execution_id\":\"E-2\",\"quantity\":450,\"price\":100.01},{\"execution_id\":\"E-3\",\"quantity\":250,\"price\":100.02}])",
        "args": [
          {
            "value": 1200,
            "elided": null
          },
          {
            "value": [
              {
                "execution_id": "E-1",
                "quantity": 300,
                "price": 100
              },
              {
                "execution_id": "E-2",
                "quantity": 450,
                "price": 100.01
              },
              {
                "execution_id": "E-3",
                "quantity": 250,
                "price": 100.02
              }
            ],
            "elided": null
          }
        ],
        "output": {
          "model": "partial-fill-residual-accounting",
          "order_quantity": 1200,
          "cumulative_quantity": 1000,
          "leaves_quantity": 200,
          "fill_notional": 100009.5,
          "average_fill_price": 100.0095,
          "execution_count": 3,
          "fill_states": [
            {
              "execution_id": "E-1",
              "last_quantity": 300,
              "last_price": 100,
              "cumulative_quantity": 300,
              "leaves_quantity": 900,
              "status": "partially-filled"
            },
            {
              "execution_id": "E-2",
              "last_quantity": 450,
              "last_price": 100.01,
              "cumulative_quantity": 750,
              "leaves_quantity": 450,
              "status": "partially-filled"
            },
            {
              "execution_id": "E-3",
              "last_quantity": 250,
              "last_price": 100.02,
              "cumulative_quantity": 1000,
              "leaves_quantity": 200,
              "status": "partially-filled"
            }
          ],
          "status": "partially-filled",
          "state": "partially-filled"
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: model, order_quantity, cumulative_quantity, leaves_quantity, fill_notional, average_fill_price, execution_count, fill_states, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f04-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Order State Changes",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/online-specification/order-state-changes/"
        },
        {
          "key": "S2",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "S3",
          "title": "Nasdaq Equity 4 — Equity Rules",
          "author": "The Nasdaq Stock Market LLC",
          "url": "https://listingcenter.nasdaq.com/rulebook/nasdaq/rules/Nasdaq%20Equity%204"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/partial-fill-and-residual-quantity-processing/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/partial-fill-and-residual-quantity-processing/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F04-A04",
      "name": "Queue Position and Ahead-Volume Calculation",
      "headline": null,
      "slug": "queue-position-and-ahead-volume-calculation",
      "path": "matching-engines-and-venue-logic/order-lifecycle-and-queue-state/queue-position-and-ahead-volume-calculation",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F04",
        "family": "Order Lifecycle and Queue State",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/queue-position-and-ahead-volume-calculation",
        "entry": "queuePositionAheadVolume",
        "params": [
          "ordersRaw",
          "targetIdRaw"
        ],
        "exports": [
          "limitOrderLifecycle",
          "cancelReplacePriority",
          "partialFillResidual",
          "queuePositionAheadVolume",
          "icebergReplenishment",
          "marketableOrderSweep",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "queuePositionAheadVolume(ordersRaw, targetIdRaw)"
      },
      "api": {
        "summary": "How much volume sits ahead of a given order at its price. This is the number that decides fill probability under price-time priority — position in the queue, not distance from the touch.",
        "params": [
          {
            "name": "ordersRaw",
            "type": "Order[]",
            "required": true,
            "description": "Resting orders at the price, in priority order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "targetIdRaw",
            "type": "string",
            "required": true,
            "description": "The order whose position is wanted.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ position, ahead_volume, behind_volume, total, … }",
          "description": "Position with volume ahead and behind."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the target order is not in the queue",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(orders)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "queuePositionAheadVolume([{\"order_id\":\"Q-1\",\"side\":\"buy\",\"price\":100,\"remaining_quantity\":300,\"arrival_sequence\":1,\"displayed\":true},{\"order_id\":\"H-1\",\"side\":\"buy\",\"price\":100,\"remaining_quantity\":1000,\"arrival_sequence\":2,\"displayed\":false},{\"order_id\":\"Q-2\",\"side\":\"buy\",\"price\":100,\"remaining_quantity\":450,\"arrival_sequence\":3,\"displayed\":true}], \"TARGET\")",
        "args": [
          {
            "value": [
              {
                "order_id": "Q-1",
                "side": "buy",
                "price": 100,
                "remaining_quantity": 300,
                "arrival_sequence": 1,
                "displayed": true
              },
              {
                "order_id": "H-1",
                "side": "buy",
                "price": 100,
                "remaining_quantity": 1000,
                "arrival_sequence": 2,
                "displayed": false
              },
              {
                "order_id": "Q-2",
                "side": "buy",
                "price": 100,
                "remaining_quantity": 450,
                "arrival_sequence": 3,
                "displayed": true
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 6
            }
          },
          {
            "value": "TARGET",
            "elided": null
          }
        ],
        "output": {
          "model": "displayed-price-time-fifo-ahead-volume",
          "target_order_id": "TARGET",
          "side": "buy",
          "price": 100,
          "ahead_order_count": 2,
          "ahead_volume": 750,
          "displayed_queue_rank": 3,
          "behind_order_count": 1,
          "behind_volume": 250,
          "hidden_same_price_quantity_excluded": 1000,
          "ahead_order_ids": [
            "Q-1",
            "Q-2"
          ],
          "state": "queued-behind-displayed-volume"
        },
        "outputElided": null,
        "outputShape": "object with 12 fields: model, target_order_id, side, price, ahead_order_count, ahead_volume, displayed_queue_rank, behind_order_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f04-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Order State Changes",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/online-specification/order-state-changes/"
        },
        {
          "key": "S2",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "S3",
          "title": "Nasdaq Equity 4 — Equity Rules",
          "author": "The Nasdaq Stock Market LLC",
          "url": "https://listingcenter.nasdaq.com/rulebook/nasdaq/rules/Nasdaq%20Equity%204"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/queue-position-and-ahead-volume-calculation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/queue-position-and-ahead-volume-calculation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F04-A05",
      "name": "Iceberg/Reserve-Order Replenishment",
      "headline": null,
      "slug": "iceberg-reserve-order-replenishment",
      "path": "matching-engines-and-venue-logic/order-lifecycle-and-queue-state/iceberg-reserve-order-replenishment",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F04",
        "family": "Order Lifecycle and Queue State",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/iceberg-reserve-order-replenishment",
        "entry": "icebergReplenishment",
        "params": [
          "totalRaw",
          "initialRaw",
          "displaySizeRaw",
          "fillsRaw",
          "priorityRaw"
        ],
        "exports": [
          "limitOrderLifecycle",
          "cancelReplacePriority",
          "partialFillResidual",
          "queuePositionAheadVolume",
          "icebergReplenishment",
          "marketableOrderSweep",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "icebergReplenishment(totalRaw, initialRaw, displaySizeRaw, fillsRaw, priorityRaw)"
      },
      "api": {
        "summary": "Manages a hidden reserve that refills the displayed quantity as it fills. The trap is priority: on most venues each replenishment goes to the **back** of the queue, which is the cost of hiding size.",
        "params": [
          {
            "name": "totalRaw",
            "type": "number",
            "required": true,
            "description": "Total order quantity including the hidden reserve.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "initialRaw",
            "type": "number",
            "required": true,
            "description": "Initially displayed quantity.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "displaySizeRaw",
            "type": "number",
            "required": true,
            "description": "Quantity displayed on each replenishment.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "fillsRaw",
            "type": "Fill[]",
            "required": true,
            "description": "Fills against the displayed portion.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "priorityRaw",
            "type": "string",
            "required": true,
            "description": "Whether replenishment retains or loses queue priority.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ tranches, displayed, reserve_remaining, priority_events, … }",
          "description": "Each replenishment tranche with its priority consequence."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the displayed size exceeds the total, or the priority rule is unrecognised",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(fills)",
          "space": "O(tranches)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "icebergReplenishment(1000, 200, 200, [100,200,250,300], 10)",
        "args": [
          {
            "value": 1000,
            "elided": null
          },
          {
            "value": 200,
            "elided": null
          },
          {
            "value": 200,
            "elided": null
          },
          {
            "value": [
              100,
              200,
              250,
              300
            ],
            "elided": null
          },
          {
            "value": 10,
            "elided": null
          }
        ],
        "output": {
          "model": "zero-displayed-tranche-replenishment",
          "total_quantity": 1000,
          "display_size": 200,
          "executed_quantity": 850,
          "displayed_remaining": 150,
          "reserve_remaining": 0,
          "total_remaining": 150,
          "replenishment_count": 4,
          "current_priority_sequence": 14,
          "unfilled_requested_quantity": 0,
          "events": [
            {
              "type": "fill",
              "fill_request_index": 0,
              "quantity": 100,
              "displayed_remaining": 100,
              "reserve_remaining": 800,
              "priority_sequence": 10
            },
            {
              "type": "fill",
              "fill_request_index": 1,
              "quantity": 100,
              "displayed_remaining": 0,
              "reserve_remaining": 800,
              "priority_sequence": 10
            },
            {
              "type": "replenish",
              "quantity": 200,
              "new_priority_sequence": 11,
              "displayed_remaining": 200,
              "reserve_remaining": 600
            }
          ],
          "state": "displayed-only"
        },
        "outputElided": null,
        "outputShape": "object with 12 fields: model, total_quantity, display_size, executed_quantity, displayed_remaining, reserve_remaining, total_remaining, replenishment_count, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f04-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Order State Changes",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/online-specification/order-state-changes/"
        },
        {
          "key": "S2",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "S3",
          "title": "Nasdaq Equity 4 — Equity Rules",
          "author": "The Nasdaq Stock Market LLC",
          "url": "https://listingcenter.nasdaq.com/rulebook/nasdaq/rules/Nasdaq%20Equity%204"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/iceberg-reserve-order-replenishment/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/iceberg-reserve-order-replenishment/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D12-F04-A06",
      "name": "Marketable-Order Multi-Level Sweep",
      "headline": null,
      "slug": "marketable-order-multi-level-sweep",
      "path": "matching-engines-and-venue-logic/order-lifecycle-and-queue-state/marketable-order-multi-level-sweep",
      "taxonomy": {
        "domainId": "D12",
        "domain": "Matching Engines and Venue Logic",
        "familyId": "D12-F04",
        "family": "Order Lifecycle and Queue State",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/marketable-order-multi-level-sweep",
        "entry": "marketableOrderSweep",
        "params": [
          "incomingRaw",
          "restingRaw"
        ],
        "exports": [
          "limitOrderLifecycle",
          "cancelReplacePriority",
          "partialFillResidual",
          "queuePositionAheadVolume",
          "icebergReplenishment",
          "marketableOrderSweep",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "marketableOrderSweep(incomingRaw, restingRaw)"
      },
      "api": {
        "summary": "Walks a marketable order across price levels until filled or exhausted — the matching-engine counterpart of the expected-fill-price calculation, producing actual fills rather than an estimate.",
        "params": [
          {
            "name": "incomingRaw",
            "type": "Order",
            "required": true,
            "description": "The marketable order.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "restingRaw",
            "type": "Order[]",
            "required": true,
            "description": "Resting orders across levels, in priority order.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ fills, levels_swept, average_price, residual, … }",
          "description": "Fills level by level with the residual left unfilled."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the incoming order has a non-positive quantity",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(resting)",
          "space": "O(fills)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "marketableOrderSweep({\"order_id\":\"IN-1\",\"side\":\"buy\",\"order_type\":\"limit\",\"quantity\":900,\"limit_price\":100.02,\"time_in_force\":\"GTC\",\"arrival_sequence\":100}, [{\"order_id\":\"B-1\",\"side\":\"buy\",\"price\":99.99,\"remaining_quantity\":500,\"priority_sequence\":1},{\"order_id\":\"S-1\",\"side\":\"sell\",\"price\":100.01,\"remaining_quantity\":300,\"priority_sequence\":2},{\"order_id\":\"S-2\",\"side\":\"sell\",\"price\":100.01,\"remaining_quantity\":400,\"priority_sequence\":3}])",
        "args": [
          {
            "value": {
              "order_id": "IN-1",
              "side": "buy",
              "order_type": "limit",
              "quantity": 900,
              "limit_price": 100.02,
              "time_in_force": "GTC",
              "arrival_sequence": 100
            },
            "elided": null
          },
          {
            "value": [
              {
                "order_id": "B-1",
                "side": "buy",
                "price": 99.99,
                "remaining_quantity": 500,
                "priority_sequence": 1
              },
              {
                "order_id": "S-1",
                "side": "sell",
                "price": 100.01,
                "remaining_quantity": 300,
                "priority_sequence": 2
              },
              {
                "order_id": "S-2",
                "side": "sell",
                "price": 100.01,
                "remaining_quantity": 400,
                "priority_sequence": 3
              }
            ],
            "elided": {
              "kind": "array",
              "shown": 3,
              "total": 5
            }
          }
        ],
        "output": {
          "model": "single-venue-price-time-marketable-sweep",
          "incoming_order_id": "IN-1",
          "incoming_side": "buy",
          "requested_quantity": 900,
          "filled_quantity": 900,
          "residual_quantity": 0,
          "fill_notional": 90011,
          "average_fill_price": 100.01222222222222,
          "fills": [
            {
              "resting_order_id": "S-1",
              "price": 100.01,
              "quantity": 300,
              "resting_remaining_quantity": 0
            },
            {
              "resting_order_id": "S-2",
              "price": 100.01,
              "quantity": 400,
              "resting_remaining_quantity": 0
            },
            {
              "resting_order_id": "S-3",
              "price": 100.02,
              "quantity": 200,
              "resting_remaining_quantity": 300
            }
          ],
          "residual_action": "none",
          "final_book": [
            {
              "order_id": "B-1",
              "side": "buy",
              "price": 99.99,
              "remaining_quantity": 500,
              "priority_sequence": 1
            },
            {
              "order_id": "S-3",
              "side": "sell",
              "price": 100.02,
              "remaining_quantity": 300,
              "priority_sequence": 4
            },
            {
              "order_id": "S-4",
              "side": "sell",
              "price": 100.03,
              "remaining_quantity": 600,
              "priority_sequence": 5
            }
          ],
          "status": "filled",
          "state": "filled"
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: model, incoming_order_id, incoming_side, requested_quantity, filled_quantity, residual_quantity, fill_notional, average_fill_price, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d12-f04-a06/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Order State Changes",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/online-specification/order-state-changes/"
        },
        {
          "key": "S2",
          "title": "Nasdaq TotalView-ITCH 5.0 Specification",
          "author": "Nasdaq",
          "url": "https://nasdaqtrader.com/content/technicalsupport/specifications/dataproducts/NQTVITCHSpecification.pdf"
        },
        {
          "key": "S3",
          "title": "Nasdaq Equity 4 — Equity Rules",
          "author": "The Nasdaq Stock Market LLC",
          "url": "https://listingcenter.nasdaq.com/rulebook/nasdaq/rules/Nasdaq%20Equity%204"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/marketable-order-multi-level-sweep/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/matching-engines-and-venue-logic/order-lifecycle-and-queue-state/marketable-order-multi-level-sweep/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D13-F01-A01",
      "name": "TWAP Execution",
      "headline": null,
      "slug": "twap-execution",
      "path": "execution-and-transaction-cost-analysis/schedule-based-execution/twap-execution",
      "taxonomy": {
        "domainId": "D13",
        "domain": "Execution and Transaction Cost Analysis",
        "familyId": "D13-F01",
        "family": "Schedule-Based Execution",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/execution-and-transaction-cost-analysis/schedule-based-execution/twap-execution",
        "entry": "twapExecution",
        "params": [
          "total_quantity",
          "start_time_ms",
          "end_time_ms",
          "bucket_count",
          "lot_size"
        ],
        "exports": [
          "twapExecution",
          "historicalVwapExecution",
          "adaptiveVwapExecution",
          "percentageOfVolumeExecution",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "twapExecution(total_quantity, start_time_ms, end_time_ms, bucket_count, lot_size)"
      },
      "api": {
        "summary": "Splits an order into equal slices across equal time buckets. The simplest schedule and the most predictable — predictable enough that it can be detected and traded against, which is the argument for the volume-based alternatives.",
        "params": [
          {
            "name": "total_quantity",
            "type": "number",
            "required": true,
            "description": "Total quantity to execute.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "start_time_ms",
            "type": "number",
            "required": true,
            "description": "Schedule start, epoch milliseconds.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "end_time_ms",
            "type": "number",
            "required": true,
            "description": "Schedule end, epoch milliseconds.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "bucket_count",
            "type": "number",
            "required": true,
            "description": "Number of time buckets.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "lot_size",
            "type": "number",
            "required": true,
            "description": "Lot size; slices round to it and the remainder must be placed somewhere explicit.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ schedule, bucket_quantity, remainder_placement, … }",
          "description": "The child-order schedule with how the lot-rounding remainder was distributed."
        },
        "warmup": null,
        "errors": [
          {
            "when": "end_time_ms is not after start_time_ms, or bucket_count is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(buckets)",
          "space": "O(buckets)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "twapExecution(12000, 0, 1440000, 24, 100)",
        "args": [
          {
            "value": 12000,
            "elided": null
          },
          {
            "value": 0,
            "elided": null
          },
          {
            "value": 1440000,
            "elided": null
          },
          {
            "value": 24,
            "elided": null
          },
          {
            "value": 100,
            "elided": null
          }
        ],
        "output": {
          "total_quantity": 12000,
          "lot_size": 100,
          "bucket_count": 24,
          "scheduled_quantity": 12000,
          "remaining_quantity": 0,
          "schedule": [
            {
              "bucket": 1,
              "start_time_ms": 0,
              "end_time_ms": 60000,
              "target_quantity": 500,
              "target_cumulative_quantity": 500
            },
            {
              "bucket": 2,
              "start_time_ms": 60000,
              "end_time_ms": 120000,
              "target_quantity": 500,
              "target_cumulative_quantity": 1000
            },
            {
              "bucket": 3,
              "start_time_ms": 120000,
              "end_time_ms": 180000,
              "target_quantity": 500,
              "target_cumulative_quantity": 1500
            }
          ],
          "state": "complete-schedule"
        },
        "outputElided": null,
        "outputShape": "object with 7 fields: total_quantity, lot_size, bucket_count, scheduled_quantity, remaining_quantity, schedule, state"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f01-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "FIX Algorithmic Trading Definition Language Online Specification",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/standards/fixatdl-online/"
        },
        {
          "key": "S2",
          "title": "Staff Report on Algorithmic Trading in U.S. Capital Markets",
          "author": "Staff of the U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/file/Algo_Trading_Report_2020.pdf"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/execution-and-transaction-cost-analysis/schedule-based-execution/twap-execution/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/execution-and-transaction-cost-analysis/schedule-based-execution/twap-execution/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D13-F01-A02",
      "name": "Historical VWAP Execution",
      "headline": null,
      "slug": "historical-vwap-execution",
      "path": "execution-and-transaction-cost-analysis/schedule-based-execution/historical-vwap-execution",
      "taxonomy": {
        "domainId": "D13",
        "domain": "Execution and Transaction Cost Analysis",
        "familyId": "D13-F01",
        "family": "Schedule-Based Execution",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/execution-and-transaction-cost-analysis/schedule-based-execution/historical-vwap-execution",
        "entry": "historicalVwapExecution",
        "params": [
          "total_quantity",
          "historical_bucket_volumes",
          "lot_size",
          "profile_id"
        ],
        "exports": [
          "twapExecution",
          "historicalVwapExecution",
          "adaptiveVwapExecution",
          "percentageOfVolumeExecution",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "historicalVwapExecution(total_quantity, historical_bucket_volumes, lot_size, profile_id)"
      },
      "api": {
        "summary": "Distributes an order according to a historical intraday volume profile — heavier at the open and close. Assumes today resembles the profile, which is exactly the assumption that fails on event days.",
        "params": [
          {
            "name": "total_quantity",
            "type": "number",
            "required": true,
            "description": "Total quantity.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "historical_bucket_volumes",
            "type": "number[]",
            "required": true,
            "description": "Historical volume per bucket, forming the profile.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "lot_size",
            "type": "number",
            "required": true,
            "description": "Lot size.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "profile_id",
            "type": "string",
            "required": true,
            "description": "Identifier of the profile used, recorded so an execution can be explained after the fact.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ schedule, profile_weights, profile_id, … }",
          "description": "The schedule with the profile weights that produced it."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the historical volumes sum to zero",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(buckets)",
          "space": "O(buckets)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "historicalVwapExecution(24000, [2400,2000,1700,1500,1300,1200], 100, \"SYN-24B-U-2026-07\")",
        "args": [
          {
            "value": 24000,
            "elided": null
          },
          {
            "value": [
              2400,
              2000,
              1700,
              1500,
              1300,
              1200
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 24
            }
          },
          {
            "value": 100,
            "elided": null
          },
          {
            "value": "SYN-24B-U-2026-07",
            "elided": null
          }
        ],
        "output": {
          "profile_id": "SYN-24B-U-2026-07",
          "total_quantity": 24000,
          "lot_size": 100,
          "bucket_count": 24,
          "historical_volume_total": 38250,
          "scheduled_quantity": 24000,
          "remaining_quantity": 0,
          "schedule": [
            {
              "bucket": 1,
              "historical_volume": 2400,
              "historical_weight": 0.062745098039,
              "target_quantity": 1500,
              "target_cumulative_quantity": 1500
            },
            {
              "bucket": 2,
              "historical_volume": 2000,
              "historical_weight": 0.052287581699,
              "target_quantity": 1300,
              "target_cumulative_quantity": 2800
            },
            {
              "bucket": 3,
              "historical_volume": 1700,
              "historical_weight": 0.044444444444,
              "target_quantity": 1100,
              "target_cumulative_quantity": 3900
            }
          ],
          "state": "complete-schedule"
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: profile_id, total_quantity, lot_size, bucket_count, historical_volume_total, scheduled_quantity, remaining_quantity, schedule, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f01-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "The Total Cost of Transactions on the NYSE",
          "author": "Stephen A. Berkowitz, Dennis E. Logue, and Eugene A. Noser Jr.",
          "url": "https://doi.org/10.1111/j.1540-6261.1988.tb02591.x"
        },
        {
          "key": "S2",
          "title": "Optimal Slice of a VWAP Trade",
          "author": "Hizuru Konishi",
          "url": "https://doi.org/10.1016/S1386-4181(01)00023-4"
        },
        {
          "key": "S3",
          "title": "FIX Algorithmic Trading Definition Language Online Specification",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/standards/fixatdl-online/"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/execution-and-transaction-cost-analysis/schedule-based-execution/historical-vwap-execution/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/execution-and-transaction-cost-analysis/schedule-based-execution/historical-vwap-execution/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D13-F01-A03",
      "name": "Adaptive VWAP Execution",
      "headline": null,
      "slug": "adaptive-vwap-execution",
      "path": "execution-and-transaction-cost-analysis/schedule-based-execution/adaptive-vwap-execution",
      "taxonomy": {
        "domainId": "D13",
        "domain": "Execution and Transaction Cost Analysis",
        "familyId": "D13-F01",
        "family": "Schedule-Based Execution",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/execution-and-transaction-cost-analysis/schedule-based-execution/adaptive-vwap-execution",
        "entry": "adaptiveVwapExecution",
        "params": [
          "total_quantity",
          "realized_market_volumes",
          "remaining_forecast_volumes",
          "executed_quantity",
          "lot_size",
          "forecast_version"
        ],
        "exports": [
          "twapExecution",
          "historicalVwapExecution",
          "adaptiveVwapExecution",
          "percentageOfVolumeExecution",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "adaptiveVwapExecution(total_quantity, realized_market_volumes, remaining_forecast_volumes, executed_quantity, lot_size, forecast_version)"
      },
      "api": {
        "summary": "Re-plans the remaining schedule from realised volume so far plus a forecast of what is left. Catches up when the market is busier than expected, and slows when it is not.",
        "params": [
          {
            "name": "total_quantity",
            "type": "number",
            "required": true,
            "description": "Total quantity.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "realized_market_volumes",
            "type": "number[]",
            "required": true,
            "description": "Volume actually observed in elapsed buckets.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "remaining_forecast_volumes",
            "type": "number[]",
            "required": true,
            "description": "Forecast volume for the remaining buckets.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "executed_quantity",
            "type": "number",
            "required": true,
            "description": "Quantity already executed.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "lot_size",
            "type": "number",
            "required": true,
            "description": "Lot size.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "forecast_version",
            "type": "string",
            "required": true,
            "description": "Which forecast produced the remaining profile, recorded for attribution.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ schedule, catch_up_quantity, participation, forecast_version, … }",
          "description": "The revised schedule with the catch-up implied by the shortfall so far."
        },
        "warmup": null,
        "errors": [
          {
            "when": "executed_quantity exceeds total_quantity",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(buckets)",
          "space": "O(buckets)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "adaptiveVwapExecution(24000, [2600,2100,1800,1600,1450,1300], [950,900,900,950,1000,1050], 5200, 100, \"SYN-LIVE-2026-07-30T14:00Z\")",
        "args": [
          {
            "value": 24000,
            "elided": null
          },
          {
            "value": [
              2600,
              2100,
              1800,
              1600,
              1450,
              1300
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 8
            }
          },
          {
            "value": [
              950,
              900,
              900,
              950,
              1000,
              1050
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 16
            }
          },
          {
            "value": 5200,
            "elided": null
          },
          {
            "value": 100,
            "elided": null
          },
          {
            "value": "SYN-LIVE-2026-07-30T14:00Z",
            "elided": null
          }
        ],
        "output": {
          "forecast_version": "SYN-LIVE-2026-07-30T14:00Z",
          "total_quantity": 24000,
          "executed_quantity": 5200,
          "remaining_quantity_before_schedule": 18800,
          "realized_market_volume": 13250,
          "remaining_forecast_market_volume": 26050,
          "projected_market_volume": 39300,
          "target_completed_quantity": 8000,
          "pacing_error_quantity": -2800,
          "pacing_state": "behind",
          "immediate_catch_up_quantity": 2800,
          "scheduled_future_quantity": 18800,
          "schedule": [
            {
              "future_bucket": 1,
              "forecast_market_volume": 950,
              "target_quantity": 3400,
              "target_cumulative_quantity": 8600,
              "includes_catch_up_quantity": 2800
            },
            {
              "future_bucket": 2,
              "forecast_market_volume": 900,
              "target_quantity": 600,
              "target_cumulative_quantity": 9200,
              "includes_catch_up_quantity": 0
            },
            {
              "future_bucket": 3,
              "forecast_market_volume": 900,
              "target_quantity": 600,
              "target_cumulative_quantity": 9800,
              "includes_catch_up_quantity": 0
            }
          ],
          "state": "adaptive-schedule"
        },
        "outputElided": null,
        "outputShape": "object with 14 fields: forecast_version, total_quantity, executed_quantity, remaining_quantity_before_schedule, realized_market_volume, remaining_forecast_market_volume, projected_market_volume, target_completed_quantity, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f01-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Dynamic Execution of VWAP Orders with Short-Term Predictions",
          "author": "Ngoc-Minh Dang and Yin Chen",
          "url": "https://papers.ssrn.com/sol3/papers.cfm?abstract_id=2366177"
        },
        {
          "key": "S2",
          "title": "Optimal Slice of a VWAP Trade",
          "author": "Hizuru Konishi",
          "url": "https://doi.org/10.1016/S1386-4181(01)00023-4"
        },
        {
          "key": "S3",
          "title": "FIX Algorithmic Trading Definition Language Online Specification",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/standards/fixatdl-online/"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/execution-and-transaction-cost-analysis/schedule-based-execution/adaptive-vwap-execution/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/execution-and-transaction-cost-analysis/schedule-based-execution/adaptive-vwap-execution/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D13-F01-A04",
      "name": "Percentage-of-Volume Execution",
      "headline": null,
      "slug": "percentage-of-volume-execution",
      "path": "execution-and-transaction-cost-analysis/schedule-based-execution/percentage-of-volume-execution",
      "taxonomy": {
        "domainId": "D13",
        "domain": "Execution and Transaction Cost Analysis",
        "familyId": "D13-F01",
        "family": "Schedule-Based Execution",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/execution-and-transaction-cost-analysis/schedule-based-execution/percentage-of-volume-execution",
        "entry": "percentageOfVolumeExecution",
        "params": [
          "total_quantity",
          "participation_rate_bps",
          "market_volume_buckets",
          "lot_size",
          "max_child_quantity"
        ],
        "exports": [
          "twapExecution",
          "historicalVwapExecution",
          "adaptiveVwapExecution",
          "percentageOfVolumeExecution",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "percentageOfVolumeExecution(total_quantity, participation_rate_bps, market_volume_buckets, lot_size, max_child_quantity)"
      },
      "api": {
        "summary": "Trades a fixed share of whatever volume occurs. The schedule is unknown in advance by design, which limits impact — and means the order may not complete at all if volume never arrives.",
        "params": [
          {
            "name": "total_quantity",
            "type": "number",
            "required": true,
            "description": "Total quantity.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "participation_rate_bps",
            "type": "number",
            "required": true,
            "description": "Target participation in basis points of market volume.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "market_volume_buckets",
            "type": "number[]",
            "required": true,
            "description": "Observed or forecast market volume per bucket.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "lot_size",
            "type": "number",
            "required": true,
            "description": "Lot size.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "max_child_quantity",
            "type": "number",
            "required": true,
            "description": "Cap on any single child order, which stops a volume spike producing an outsized print.",
            "constraints": {
              "min": 1,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ schedule, projected_completion, unfilled_quantity, … }",
          "description": "The schedule with projected completion and any quantity the volume path cannot absorb."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the participation rate is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(buckets)",
          "space": "O(buckets)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "percentageOfVolumeExecution(10000, 1000, [5200,4600,4100,3800,3500,3300], 100, 700)",
        "args": [
          {
            "value": 10000,
            "elided": null
          },
          {
            "value": 1000,
            "elided": null
          },
          {
            "value": [
              5200,
              4600,
              4100,
              3800,
              3500,
              3300
            ],
            "elided": {
              "kind": "array",
              "shown": 6,
              "total": 24
            }
          },
          {
            "value": 100,
            "elided": null
          },
          {
            "value": 700,
            "elided": null
          }
        ],
        "output": {
          "total_quantity": 10000,
          "participation_rate_bps": 1000,
          "lot_size": 100,
          "max_child_quantity": 700,
          "observed_market_volume": 120900,
          "released_quantity": 10000,
          "remaining_quantity": 0,
          "achieved_participation_bps": 827.129859,
          "schedule": [
            {
              "bucket": 1,
              "market_volume": 5200,
              "cumulative_market_volume": 5200,
              "target_cumulative_quantity": 500,
              "child_quantity": 500,
              "released_cumulative_quantity": 500,
              "remaining_quantity": 9500,
              "achieved_participation_bps": 961.538462
            },
            {
              "bucket": 2,
              "market_volume": 4600,
              "cumulative_market_volume": 9800,
              "target_cumulative_quantity": 900,
              "child_quantity": 400,
              "released_cumulative_quantity": 900,
              "remaining_quantity": 9100,
              "achieved_participation_bps": 918.367347
            },
            {
              "bucket": 3,
              "market_volume": 4100,
              "cumulative_market_volume": 13900,
              "target_cumulative_quantity": 1300,
              "child_quantity": 400,
              "released_cumulative_quantity": 1300,
              "remaining_quantity": 8700,
              "achieved_participation_bps": 935.251799
            }
          ],
          "state": "parent-complete"
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: total_quantity, participation_rate_bps, lot_size, max_child_quantity, observed_market_volume, released_quantity, remaining_quantity, achieved_participation_bps, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f01-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Execution and Block Trade Pricing with Optimal Constant Rate of Participation",
          "author": "Olivier Guéant",
          "url": "https://arxiv.org/abs/1210.7608"
        },
        {
          "key": "S2",
          "title": "FIX Algorithmic Trading Definition Language Online Specification",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/standards/fixatdl-online/"
        },
        {
          "key": "S3",
          "title": "Staff Report on Algorithmic Trading in U.S. Capital Markets",
          "author": "Staff of the U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/file/Algo_Trading_Report_2020.pdf"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/execution-and-transaction-cost-analysis/schedule-based-execution/percentage-of-volume-execution/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/execution-and-transaction-cost-analysis/schedule-based-execution/percentage-of-volume-execution/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D13-F02-A01",
      "name": "Almgren-Chriss Optimal Execution",
      "headline": null,
      "slug": "almgren-chriss-optimal-execution",
      "path": "execution-and-transaction-cost-analysis/cost-risk-optimization/almgren-chriss-optimal-execution",
      "taxonomy": {
        "domainId": "D13",
        "domain": "Execution and Transaction Cost Analysis",
        "familyId": "D13-F02",
        "family": "Cost/Risk Optimization",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/execution-and-transaction-cost-analysis/cost-risk-optimization/almgren-chriss-optimal-execution",
        "entry": "almgrenChrissOptimalExecution",
        "params": [
          "input"
        ],
        "exports": [
          "almgrenChrissOptimalExecution",
          "implementationShortfallExecution",
          "arrivalPriceExecution",
          "liquiditySeekingExecution",
          "opportunisticDarkPoolExecution",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "almgrenChrissOptimalExecution(input)"
      },
      "api": {
        "summary": "The canonical optimal execution trajectory: trades off market impact against the risk of holding the position longer. Risk aversion is the single parameter that shapes the answer — at zero it degenerates to TWAP.",
        "params": [
          {
            "name": "input",
            "type": "AlmgrenChrissInput",
            "required": true,
            "description": "Total quantity, horizon, volatility, temporary and permanent impact coefficients, and the risk-aversion parameter. The impact coefficients are estimates, and the trajectory is only as good as they are.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ trajectory, expected_cost, cost_variance, efficient_frontier_point, … }",
          "description": "The trading trajectory with expected cost **and** its variance — reporting cost alone hides the trade being made."
        },
        "warmup": null,
        "errors": [
          {
            "when": "risk aversion is negative, or an impact coefficient is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(steps)",
          "space": "O(steps)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "almgrenChrissOptimalExecution({\"total_quantity\":12000,\"interval_count\":12,\"lot_size\":100,\"temporary_impact_weight\":100,\"inventory_risk_weight\":1})",
        "args": [
          {
            "value": {
              "total_quantity": 12000,
              "interval_count": 12,
              "lot_size": 100,
              "temporary_impact_weight": 100,
              "inventory_risk_weight": 1
            },
            "elided": null
          }
        ],
        "output": {
          "total_quantity": 12000,
          "interval_count": 12,
          "lot_size": 100,
          "temporary_impact_weight": 100,
          "inventory_risk_weight": 1,
          "kappa": 0.099958380139,
          "scheduled_quantity": 12000,
          "remaining_quantity": 0,
          "temporary_impact_score": 1248000000,
          "inventory_risk_score": 410470000,
          "objective_score": 1658470000,
          "schedule": [
            {
              "interval": 1,
              "target_quantity": 1400,
              "target_remaining_quantity": 10600,
              "temporary_impact_score": 196000000,
              "inventory_risk_score": 112360000
            },
            {
              "interval": 2,
              "target_quantity": 1300,
              "target_remaining_quantity": 9300,
              "temporary_impact_score": 169000000,
              "inventory_risk_score": 86490000
            },
            {
              "interval": 3,
              "target_quantity": 1200,
              "target_remaining_quantity": 8100,
              "temporary_impact_score": 144000000,
              "inventory_risk_score": 65610000
            }
          ],
          "state": "risk-adjusted"
        },
        "outputElided": null,
        "outputShape": "object with 13 fields: total_quantity, interval_count, lot_size, temporary_impact_weight, inventory_risk_weight, kappa, scheduled_quantity, remaining_quantity, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f02-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Optimal Execution of Portfolio Transactions",
          "author": "Robert Almgren and Neil Chriss",
          "url": "https://doi.org/10.21314/JOR.2001.041"
        },
        {
          "key": "S2",
          "title": "Staff Report on Algorithmic Trading in U.S. Capital Markets",
          "author": "Staff of the U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/about/reports-publications/algo_trading_report_2020"
        },
        {
          "key": "S3",
          "title": "FIX Algorithmic Trading Definition Language Online Specification",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/standards/fixatdl-online/"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/execution-and-transaction-cost-analysis/cost-risk-optimization/almgren-chriss-optimal-execution/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/execution-and-transaction-cost-analysis/cost-risk-optimization/almgren-chriss-optimal-execution/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D13-F02-A02",
      "name": "Implementation-Shortfall Execution",
      "headline": null,
      "slug": "implementation-shortfall-execution",
      "path": "execution-and-transaction-cost-analysis/cost-risk-optimization/implementation-shortfall-execution",
      "taxonomy": {
        "domainId": "D13",
        "domain": "Execution and Transaction Cost Analysis",
        "familyId": "D13-F02",
        "family": "Cost/Risk Optimization",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/execution-and-transaction-cost-analysis/cost-risk-optimization/implementation-shortfall-execution",
        "entry": "implementationShortfallExecution",
        "params": [
          "input"
        ],
        "exports": [
          "almgrenChrissOptimalExecution",
          "implementationShortfallExecution",
          "arrivalPriceExecution",
          "liquiditySeekingExecution",
          "opportunisticDarkPoolExecution",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "implementationShortfallExecution(input)"
      },
      "api": {
        "summary": "Minimises total shortfall against the arrival price, including the opportunity cost of quantity that never executes. Unexecuted quantity is a real cost, and a strategy measured only on filled shares hides it.",
        "params": [
          {
            "name": "input",
            "type": "ShortfallInput",
            "required": true,
            "description": "Arrival price, quantity, impact and volatility parameters, and the urgency that trades impact against timing risk.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ schedule, expected_shortfall_bps, market_impact, timing_risk, opportunity_cost, … }",
          "description": "Shortfall decomposed into impact, timing risk and opportunity cost — the decomposition is what makes it actionable."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the arrival price is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(steps)",
          "space": "O(steps)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "implementationShortfallExecution({\"remaining_quantity\":10000,\"side\":\"buy\",\"decision_price_atoms\":1000000,\"current_price_atoms\":1001000,\"spread_bps\":4,\"impact_coefficient_bps\":35,\"average_daily_volume\":1000000,\"volatility_bps\":18,\"risk_aversion\":0.8,\"urgency_bps\":12,\"intervals_remaining\":8,\"max_child_quantity\":3000,\"candidate_step_quantity\":500,\"lot_size\":100})",
        "args": [
          {
            "value": {
              "remaining_quantity": 10000,
              "side": "buy",
              "decision_price_atoms": 1000000,
              "current_price_atoms": 1001000,
              "spread_bps": 4,
              "impact_coefficient_bps": 35,
              "average_daily_volume": 1000000,
              "volatility_bps": 18,
              "risk_aversion": 0.8,
              "urgency_bps": 12,
              "intervals_remaining": 8,
              "max_child_quantity": 3000,
              "candidate_step_quantity": 500,
              "lot_size": 100
            },
            "elided": null
          }
        ],
        "output": {
          "side": "buy",
          "decision_price_atoms": 1000000,
          "current_price_atoms": 1001000,
          "signed_move_bps": 10,
          "adverse_move_bps": 10,
          "remaining_quantity": 10000,
          "selected_child_quantity": 3000,
          "post_child_quantity": 7000,
          "selected_total_score": 122453.181772,
          "selected_immediate_cost_score": 6315,
          "selected_opportunity_cost_score": 80500,
          "selected_inventory_risk_score": 35638.181772,
          "candidates": [
            {
              "child_quantity": 0,
              "residual_quantity": 10000,
              "immediate_cost_score": 0,
              "opportunity_cost_score": 115000,
              "inventory_risk_score": 50911.688245,
              "total_score": 165911.688245
            },
            {
              "child_quantity": 500,
              "residual_quantity": 9500,
              "immediate_cost_score": 1008.75,
              "opportunity_cost_score": 109250,
              "inventory_risk_score": 48366.103833,
              "total_score": 158624.853833
            },
            {
              "child_quantity": 1000,
              "residual_quantity": 9000,
              "immediate_cost_score": 2035,
              "opportunity_cost_score": 103500,
              "inventory_risk_score": 45820.519421,
              "total_score": 151355.519421
            }
          ],
          "state": "execute-now"
        },
        "outputElided": null,
        "outputShape": "object with 14 fields: side, decision_price_atoms, current_price_atoms, signed_move_bps, adverse_move_bps, remaining_quantity, selected_child_quantity, post_child_quantity, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f02-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "The Implementation Shortfall: Paper versus Reality",
          "author": "Andre F. Perold",
          "url": "https://doi.org/10.3905/jpm.1988.409150"
        },
        {
          "key": "S2",
          "title": "Optimal Execution of Portfolio Transactions",
          "author": "Robert Almgren and Neil Chriss",
          "url": "https://doi.org/10.21314/JOR.2001.041"
        },
        {
          "key": "S3",
          "title": "Staff Report on Algorithmic Trading in U.S. Capital Markets",
          "author": "Staff of the U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/about/reports-publications/algo_trading_report_2020"
        },
        {
          "key": "S4",
          "title": "FIX Algorithmic Trading Definition Language Online Specification",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/standards/fixatdl-online/"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/execution-and-transaction-cost-analysis/cost-risk-optimization/implementation-shortfall-execution/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/execution-and-transaction-cost-analysis/cost-risk-optimization/implementation-shortfall-execution/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D13-F02-A03",
      "name": "Arrival-Price Execution",
      "headline": null,
      "slug": "arrival-price-execution",
      "path": "execution-and-transaction-cost-analysis/cost-risk-optimization/arrival-price-execution",
      "taxonomy": {
        "domainId": "D13",
        "domain": "Execution and Transaction Cost Analysis",
        "familyId": "D13-F02",
        "family": "Cost/Risk Optimization",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/execution-and-transaction-cost-analysis/cost-risk-optimization/arrival-price-execution",
        "entry": "arrivalPriceExecution",
        "params": [
          "input"
        ],
        "exports": [
          "almgrenChrissOptimalExecution",
          "implementationShortfallExecution",
          "arrivalPriceExecution",
          "liquiditySeekingExecution",
          "opportunisticDarkPoolExecution",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "arrivalPriceExecution(input)"
      },
      "api": {
        "summary": "Benchmarks against the price at the moment the decision was made, which front-loads execution. The most demanding common benchmark, because every second of delay is measured against it.",
        "params": [
          {
            "name": "input",
            "type": "ArrivalPriceInput",
            "required": true,
            "description": "Arrival price, quantity, horizon, and the aggression parameter controlling how quickly the order is worked.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ schedule, front_loading, expected_slippage_bps, … }",
          "description": "The schedule with its front-loading and expected slippage against arrival."
        },
        "warmup": null,
        "errors": [
          {
            "when": "aggression falls outside its permitted range",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(steps)",
          "space": "O(steps)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "arrivalPriceExecution({\"remaining_quantity\":8000,\"side\":\"buy\",\"arrival_price_atoms\":1000000,\"current_price_atoms\":1000500,\"tolerance_bps\":8,\"observed_market_volume\":50000,\"base_participation_bps\":1000,\"defensive_participation_bps\":300,\"max_participation_bps\":2000,\"intervals_remaining\":10,\"deadline_threshold_intervals\":2,\"max_child_quantity\":1500,\"lot_size\":100})",
        "args": [
          {
            "value": {
              "remaining_quantity": 8000,
              "side": "buy",
              "arrival_price_atoms": 1000000,
              "current_price_atoms": 1000500,
              "tolerance_bps": 8,
              "observed_market_volume": 50000,
              "base_participation_bps": 1000,
              "defensive_participation_bps": 300,
              "max_participation_bps": 2000,
              "intervals_remaining": 10,
              "deadline_threshold_intervals": 2,
              "max_child_quantity": 1500,
              "lot_size": 100
            },
            "elided": null
          }
        ],
        "output": {
          "side": "buy",
          "arrival_price_atoms": 1000000,
          "current_price_atoms": 1000500,
          "signed_move_bps": 5,
          "tolerance_bps": 8,
          "price_state": "inside-band",
          "chosen_participation_bps": 1000,
          "observed_market_volume": 50000,
          "target_from_volume_quantity": 5000,
          "child_quantity": 1500,
          "remaining_quantity": 6500,
          "state": "inside-band"
        },
        "outputElided": null,
        "outputShape": "object with 12 fields: side, arrival_price_atoms, current_price_atoms, signed_move_bps, tolerance_bps, price_state, chosen_participation_bps, observed_market_volume, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f02-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "The Implementation Shortfall: Paper versus Reality",
          "author": "Andre F. Perold",
          "url": "https://doi.org/10.3905/jpm.1988.409150"
        },
        {
          "key": "S2",
          "title": "Staff Report on Algorithmic Trading in U.S. Capital Markets",
          "author": "Staff of the U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/about/reports-publications/algo_trading_report_2020"
        },
        {
          "key": "S3",
          "title": "FIX Algorithmic Trading Definition Language Online Specification",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/standards/fixatdl-online/"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/execution-and-transaction-cost-analysis/cost-risk-optimization/arrival-price-execution/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/execution-and-transaction-cost-analysis/cost-risk-optimization/arrival-price-execution/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D13-F02-A04",
      "name": "Liquidity-Seeking Execution",
      "headline": null,
      "slug": "liquidity-seeking-execution",
      "path": "execution-and-transaction-cost-analysis/cost-risk-optimization/liquidity-seeking-execution",
      "taxonomy": {
        "domainId": "D13",
        "domain": "Execution and Transaction Cost Analysis",
        "familyId": "D13-F02",
        "family": "Cost/Risk Optimization",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/execution-and-transaction-cost-analysis/cost-risk-optimization/liquidity-seeking-execution",
        "entry": "liquiditySeekingExecution",
        "params": [
          "input"
        ],
        "exports": [
          "almgrenChrissOptimalExecution",
          "implementationShortfallExecution",
          "arrivalPriceExecution",
          "liquiditySeekingExecution",
          "opportunisticDarkPoolExecution",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "liquiditySeekingExecution(input)"
      },
      "api": {
        "summary": "Trades opportunistically when liquidity appears rather than on a schedule. Completion time is uncertain by construction — the strategy trades schedule certainty for better prices.",
        "params": [
          {
            "name": "input",
            "type": "LiquiditySeekingInput",
            "required": true,
            "description": "Quantity, the liquidity signals to react to, minimum acceptable size, and the price limit beyond which liquidity is declined.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ opportunities, executed, remaining, completion_estimate, … }",
          "description": "Opportunities taken and passed, with the completion estimate that remains genuinely an estimate."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the minimum size exceeds the total quantity",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(signals)",
          "space": "O(opportunities)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "liquiditySeekingExecution({\"total_quantity\":4000,\"side\":\"buy\",\"limit_price_atoms\":1000200,\"minimum_confidence_bps\":7500,\"maximum_age_ms\":50,\"max_take_per_event\":700,\"lot_size\":100,\"liquidity_events\":[{\"event_id\":\"LQ-01\",\"price_atoms\":1000000,\"available_quantity\":500,\"age_ms\":12,\"confidence_bps\":8500},{\"event_id\":\"LQ-02\",\"price_atoms\":1000100,\"available_quantity\":900,\"age_ms\":18,\"confidence_bps\":7800},{\"event_id\":\"LQ-03\",\"price_atoms\":1000300,\"available_quantity\":700,\"age_ms\":8,\"confidence_bps\":9200}]})",
        "args": [
          {
            "value": {
              "total_quantity": 4000,
              "side": "buy",
              "limit_price_atoms": 1000200,
              "minimum_confidence_bps": 7500,
              "maximum_age_ms": 50,
              "max_take_per_event": 700,
              "lot_size": 100,
              "liquidity_events": [
                {
                  "event_id": "LQ-01",
                  "price_atoms": 1000000,
                  "available_quantity": 500,
                  "age_ms": 12,
                  "confidence_bps": 8500
                },
                {
                  "event_id": "LQ-02",
                  "price_atoms": 1000100,
                  "available_quantity": 900,
                  "age_ms": 18,
                  "confidence_bps": 7800
                },
                {
                  "event_id": "LQ-03",
                  "price_atoms": 1000300,
                  "available_quantity": 700,
                  "age_ms": 8,
                  "confidence_bps": 9200
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "side": "buy",
          "limit_price_atoms": 1000200,
          "total_quantity": 4000,
          "accepted_quantity": 4000,
          "remaining_quantity": 0,
          "accepted_event_count": 7,
          "rejected_event_count": 5,
          "events": [
            {
              "event_id": "LQ-01",
              "price_atoms": 1000000,
              "available_quantity": 500,
              "age_ms": 12,
              "confidence_bps": 8500,
              "planned_take_quantity": 500,
              "reason": "accepted",
              "remaining_quantity": 3500
            },
            {
              "event_id": "LQ-02",
              "price_atoms": 1000100,
              "available_quantity": 900,
              "age_ms": 18,
              "confidence_bps": 7800,
              "planned_take_quantity": 700,
              "reason": "accepted",
              "remaining_quantity": 2800
            },
            {
              "event_id": "LQ-03",
              "price_atoms": 1000300,
              "available_quantity": 700,
              "age_ms": 8,
              "confidence_bps": 9200,
              "planned_take_quantity": 0,
              "reason": "outside-limit",
              "remaining_quantity": 2800
            }
          ],
          "state": "parent-complete"
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: side, limit_price_atoms, total_quantity, accepted_quantity, remaining_quantity, accepted_event_count, rejected_event_count, events, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f02-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Remarks Before the Security Traders Association",
          "author": "SEC Chair Mary L. Schapiro",
          "url": "https://www.sec.gov/news/speech/2010/spch092210mls.htm"
        },
        {
          "key": "S2",
          "title": "Staff Report on Algorithmic Trading in U.S. Capital Markets",
          "author": "Staff of the U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/about/reports-publications/algo_trading_report_2020"
        },
        {
          "key": "S3",
          "title": "FIX Algorithmic Trading Definition Language Online Specification",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/standards/fixatdl-online/"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/execution-and-transaction-cost-analysis/cost-risk-optimization/liquidity-seeking-execution/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/execution-and-transaction-cost-analysis/cost-risk-optimization/liquidity-seeking-execution/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D13-F02-A05",
      "name": "Opportunistic Dark-Pool Execution",
      "headline": null,
      "slug": "opportunistic-dark-pool-execution",
      "path": "execution-and-transaction-cost-analysis/cost-risk-optimization/opportunistic-dark-pool-execution",
      "taxonomy": {
        "domainId": "D13",
        "domain": "Execution and Transaction Cost Analysis",
        "familyId": "D13-F02",
        "family": "Cost/Risk Optimization",
        "difficulty": 5
      },
      "import": {
        "subpath": "fintech-algorithms/execution-and-transaction-cost-analysis/cost-risk-optimization/opportunistic-dark-pool-execution",
        "entry": "opportunisticDarkPoolExecution",
        "params": [
          "input"
        ],
        "exports": [
          "almgrenChrissOptimalExecution",
          "implementationShortfallExecution",
          "arrivalPriceExecution",
          "liquiditySeekingExecution",
          "opportunisticDarkPoolExecution",
          "calculate"
        ],
        "archetype": "record-transform",
        "signature": "opportunisticDarkPoolExecution(input)"
      },
      "api": {
        "summary": "Routes to non-displayed venues to avoid signalling. The counter-risk is adverse selection: filling in the dark exactly when the lit market is about to move against you, which the fill-rate and reversion outputs are there to expose.",
        "params": [
          {
            "name": "input",
            "type": "DarkPoolInput",
            "required": true,
            "description": "Quantity, venue list with their fill characteristics, minimum acceptable quantity, and the reference price constraining acceptable fills.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ routes, expected_fill_rate, adverse_selection_estimate, … }",
          "description": "Routing plan with expected fill rate and an adverse-selection estimate — the cost that dark execution trades for invisibility."
        },
        "warmup": null,
        "errors": [
          {
            "when": "no venue is supplied",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(venues)",
          "space": "O(venues)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "opportunisticDarkPoolExecution({\"total_quantity\":6000,\"lot_size\":100,\"maximum_dark_fraction_bps\":6000,\"minimum_firm_probability_bps\":7500,\"minimum_price_improvement_atoms\":30,\"minimum_execution_quantity\":300,\"max_exposure_per_window\":1000,\"fallback_window\":8,\"dark_opportunities\":[{\"opportunity_id\":\"DK-01\",\"window\":1,\"indicated_quantity\":500,\"firm_probability_bps\":8200,\"price_improvement_atoms\":50},{\"opportunity_id\":\"DK-02\",\"window\":2,\"indicated_quantity\":900,\"firm_probability_bps\":7600,\"price_improvement_atoms\":40},{\"opportunity_id\":\"DK-03\",\"window\":3,\"indicated_quantity\":300,\"firm_probability_bps\":9100,\"price_improvement_atoms\":60}]})",
        "args": [
          {
            "value": {
              "total_quantity": 6000,
              "lot_size": 100,
              "maximum_dark_fraction_bps": 6000,
              "minimum_firm_probability_bps": 7500,
              "minimum_price_improvement_atoms": 30,
              "minimum_execution_quantity": 300,
              "max_exposure_per_window": 1000,
              "fallback_window": 8,
              "dark_opportunities": [
                {
                  "opportunity_id": "DK-01",
                  "window": 1,
                  "indicated_quantity": 500,
                  "firm_probability_bps": 8200,
                  "price_improvement_atoms": 50
                },
                {
                  "opportunity_id": "DK-02",
                  "window": 2,
                  "indicated_quantity": 900,
                  "firm_probability_bps": 7600,
                  "price_improvement_atoms": 40
                },
                {
                  "opportunity_id": "DK-03",
                  "window": 3,
                  "indicated_quantity": 300,
                  "firm_probability_bps": 9100,
                  "price_improvement_atoms": 60
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "total_quantity": 6000,
          "maximum_dark_fraction_bps": 6000,
          "dark_quantity_cap": 3600,
          "planned_dark_exposure_quantity": 3300,
          "lit_fallback_quantity": 2700,
          "dark_opportunity_count": 10,
          "accepted_dark_window_count": 5,
          "opportunities": [
            {
              "opportunity_id": "DK-01",
              "window": 1,
              "indicated_quantity": 500,
              "firm_probability_bps": 8200,
              "price_improvement_atoms": 50,
              "planned_dark_exposure_quantity": 500,
              "reason": "expose-dark",
              "dark_cap_remaining_quantity": 3100
            },
            {
              "opportunity_id": "DK-02",
              "window": 2,
              "indicated_quantity": 900,
              "firm_probability_bps": 7600,
              "price_improvement_atoms": 40,
              "planned_dark_exposure_quantity": 900,
              "reason": "expose-dark",
              "dark_cap_remaining_quantity": 2200
            },
            {
              "opportunity_id": "DK-03",
              "window": 3,
              "indicated_quantity": 300,
              "firm_probability_bps": 9100,
              "price_improvement_atoms": 60,
              "planned_dark_exposure_quantity": 300,
              "reason": "expose-dark",
              "dark_cap_remaining_quantity": 1900
            }
          ],
          "state": "lit-fallback-required"
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: total_quantity, maximum_dark_fraction_bps, dark_quantity_cap, planned_dark_exposure_quantity, lit_fallback_quantity, dark_opportunity_count, accepted_dark_window_count, opportunities, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d13-f02-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "S1",
          "title": "Regulation of NMS Stock Alternative Trading Systems",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/rules-regulations/2018/07/regulation-nms-stock-alternative-trading-systems"
        },
        {
          "key": "S2",
          "title": "Alternative Trading System (ATS) List",
          "author": "U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/foia/frequently-requested-documents/alternative-trading-system-ats-list"
        },
        {
          "key": "S3",
          "title": "OTC (ATS and Non-ATS) Transparency",
          "author": "Financial Industry Regulatory Authority",
          "url": "https://www.finra.org/filing-reporting/otc-transparency"
        },
        {
          "key": "S4",
          "title": "Staff Report on Algorithmic Trading in U.S. Capital Markets",
          "author": "Staff of the U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/about/reports-publications/algo_trading_report_2020"
        },
        {
          "key": "S5",
          "title": "FIX Algorithmic Trading Definition Language Online Specification",
          "author": "FIX Trading Community",
          "url": "https://www.fixtrading.org/standards/fixatdl-online/"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/execution-and-transaction-cost-analysis/cost-risk-optimization/opportunistic-dark-pool-execution/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/execution-and-transaction-cost-analysis/cost-risk-optimization/opportunistic-dark-pool-execution/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D25-F01-A01",
      "name": "Constant-Product AMM",
      "headline": null,
      "slug": "constant-product-amm",
      "path": "digital-assets-and-on-chain-finance/amm-pricing/constant-product-amm",
      "taxonomy": {
        "domainId": "D25",
        "domain": "Digital Assets and On-Chain Finance",
        "familyId": "D25-F01",
        "family": "AMM Pricing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/digital-assets-and-on-chain-finance/amm-pricing/constant-product-amm",
        "entry": "constantProductQuote",
        "params": [
          "reserve0",
          "reserve1",
          "amount0In",
          "feeRate"
        ],
        "exports": [
          "constantProductQuote",
          "constantSumQuote",
          "stableSwapInvariant",
          "stableSwapQuote",
          "weightedProductQuote",
          "concentratedLiquidityPosition"
        ],
        "archetype": "record-transform",
        "signature": "constantProductQuote(reserve0, reserve1, amount0In, feeRate)"
      },
      "api": {
        "summary": "The `x · y = k` curve behind Uniswap v2. Price is set by the reserve ratio, so every trade moves it — and the slippage a trade suffers is a deterministic function of its size relative to the pool.",
        "params": [
          {
            "name": "reserve0",
            "type": "number",
            "required": true,
            "description": "Reserve of the input token.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "reserve1",
            "type": "number",
            "required": true,
            "description": "Reserve of the output token.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "amount0In",
            "type": "number",
            "required": true,
            "description": "Input amount.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "feeRate",
            "type": "number",
            "required": true,
            "description": "Fee as a fraction, taken from the input before the swap.",
            "constraints": {
              "min": 0,
              "max": 1
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ amountOut, priceImpact, effectivePrice, spotPriceAfter, … }",
          "description": "Output amount with the price impact and the post-trade spot price."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a reserve is zero, or feeRate falls outside 0…1",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "constantProductQuote(1000, 1000, 10, 0.003)",
        "args": [
          {
            "value": 1000,
            "elided": null
          },
          {
            "value": 1000,
            "elided": null
          },
          {
            "value": 10,
            "elided": null
          },
          {
            "value": 0.003,
            "elided": null
          }
        ],
        "output": {
          "model": "constant-product",
          "reserve0Before": 1000,
          "reserve1Before": 1000,
          "amount0In": 10,
          "effectiveAmount0In": 9.97,
          "feeAmount0": 0.03,
          "amount1Out": 9.871580343971,
          "reserve0After": 1010,
          "reserve1After": 990.128419656029,
          "invariantBefore": 1000000,
          "invariantAfter": 1000029.7038525896,
          "spotPriceBeforeToken1PerToken0": 1,
          "spotPriceAfterToken1PerToken0": 0.980325167976,
          "executionPriceToken1PerToken0": 0.987158034397
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 16
        },
        "outputShape": "object with 16 fields: model, reserve0Before, reserve1Before, amount0In, effectiveAmount0In, feeAmount0, amount1Out, reserve0After, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d25-f01-a01/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "Uniswap v2 Core whitepaper",
          "author": "Uniswap",
          "url": null
        },
        {
          "key": "SRC-02",
          "title": "StableSwap whitepaper",
          "author": "Curve Finance / Michael Egorov",
          "url": null
        },
        {
          "key": "SRC-03",
          "title": "Balancer whitepaper",
          "author": "Balancer Labs",
          "url": null
        },
        {
          "key": "SRC-04",
          "title": "Uniswap v3 Core whitepaper",
          "author": "Uniswap",
          "url": null
        },
        {
          "key": "Source discipline",
          "title": "Source discipline",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/digital-assets-and-on-chain-finance/amm-pricing/constant-product-amm/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/digital-assets-and-on-chain-finance/amm-pricing/constant-product-amm/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D25-F01-A02",
      "name": "Constant-Sum AMM",
      "headline": null,
      "slug": "constant-sum-amm",
      "path": "digital-assets-and-on-chain-finance/amm-pricing/constant-sum-amm",
      "taxonomy": {
        "domainId": "D25",
        "domain": "Digital Assets and On-Chain Finance",
        "familyId": "D25-F01",
        "family": "AMM Pricing",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/digital-assets-and-on-chain-finance/amm-pricing/constant-sum-amm",
        "entry": "constantSumQuote",
        "params": [
          "reserve0",
          "reserve1",
          "amount0In",
          "feeRate"
        ],
        "exports": [
          "constantProductQuote",
          "constantSumQuote",
          "stableSwapInvariant",
          "stableSwapQuote",
          "weightedProductQuote",
          "concentratedLiquidityPosition"
        ],
        "archetype": "record-transform",
        "signature": "constantSumQuote(reserve0, reserve1, amount0In, feeRate)"
      },
      "api": {
        "summary": "The `x + y = k` curve: zero slippage, and the pool can be fully drained of one asset. Never used alone for that reason — it is the component that makes stableswap flat near the peg.",
        "params": [
          {
            "name": "reserve0",
            "type": "number",
            "required": true,
            "description": "Reserve of the input token.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "reserve1",
            "type": "number",
            "required": true,
            "description": "Reserve of the output token.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "amount0In",
            "type": "number",
            "required": true,
            "description": "Input amount.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "feeRate",
            "type": "number",
            "required": true,
            "description": "Fee as a fraction.",
            "constraints": {
              "min": 0,
              "max": 1
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ amountOut, depleted, effectivePrice, … }",
          "description": "Output amount with an explicit depletion flag for the case the curve permits and reality does not."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the output reserve cannot cover the trade",
            "behaviour": "reported as depleted rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "constantSumQuote(1000, 1000, 10, 0.003)",
        "args": [
          {
            "value": 1000,
            "elided": null
          },
          {
            "value": 1000,
            "elided": null
          },
          {
            "value": 10,
            "elided": null
          },
          {
            "value": 0.003,
            "elided": null
          }
        ],
        "output": {
          "model": "constant-sum",
          "reserve0Before": 1000,
          "reserve1Before": 1000,
          "amount0In": 10,
          "effectiveAmount0In": 9.97,
          "feeAmount0": 0.03,
          "amount1Out": 9.97,
          "reserve0After": 1010,
          "reserve1After": 990.03,
          "invariantBefore": 2000,
          "invariantAfter": 2000.03,
          "spotPriceBeforeToken1PerToken0": 1,
          "executionPriceToken1PerToken0": 0.997,
          "remainingExactFillCapacityToken0": 993.009027081244
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 16
        },
        "outputShape": "object with 16 fields: model, reserve0Before, reserve1Before, amount0In, effectiveAmount0In, feeAmount0, amount1Out, reserve0After, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d25-f01-a02/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "Uniswap v2 Core whitepaper",
          "author": "Uniswap",
          "url": null
        },
        {
          "key": "SRC-02",
          "title": "StableSwap whitepaper",
          "author": "Curve Finance / Michael Egorov",
          "url": null
        },
        {
          "key": "SRC-03",
          "title": "Balancer whitepaper",
          "author": "Balancer Labs",
          "url": null
        },
        {
          "key": "SRC-04",
          "title": "Uniswap v3 Core whitepaper",
          "author": "Uniswap",
          "url": null
        },
        {
          "key": "Source discipline",
          "title": "Source discipline",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/digital-assets-and-on-chain-finance/amm-pricing/constant-sum-amm/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/digital-assets-and-on-chain-finance/amm-pricing/constant-sum-amm/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D25-F01-A03",
      "name": "StableSwap Invariant",
      "headline": null,
      "slug": "stableswap-invariant",
      "path": "digital-assets-and-on-chain-finance/amm-pricing/stableswap-invariant",
      "taxonomy": {
        "domainId": "D25",
        "domain": "Digital Assets and On-Chain Finance",
        "familyId": "D25-F01",
        "family": "AMM Pricing",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/digital-assets-and-on-chain-finance/amm-pricing/stableswap-invariant",
        "entry": "stableSwapQuote",
        "params": [
          "balances",
          "amountIn",
          "amplification",
          "feeRate",
          "inputIndex",
          "outputIndex"
        ],
        "exports": [
          "constantProductQuote",
          "constantSumQuote",
          "stableSwapInvariant",
          "stableSwapQuote",
          "weightedProductQuote",
          "concentratedLiquidityPosition"
        ],
        "archetype": "record-transform",
        "signature": "stableSwapQuote(balances, amountIn, amplification, feeRate, inputIndex, outputIndex)"
      },
      "api": {
        "summary": "Curve's invariant: nearly constant-sum near the peg, constant-product away from it. The amplification coefficient sets where that transition happens, and it is what lets a stablecoin pool quote size with almost no slippage until it suddenly cannot.",
        "params": [
          {
            "name": "balances",
            "type": "number[]",
            "required": true,
            "description": "Pool balances for every asset.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "amountIn",
            "type": "number",
            "required": true,
            "description": "Input amount.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "amplification",
            "type": "number",
            "required": true,
            "description": "Amplification coefficient. Higher keeps the curve flat further from the peg — and makes depegging more violent when it comes.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "feeRate",
            "type": "number",
            "required": true,
            "description": "Fee as a fraction.",
            "constraints": {
              "min": 0,
              "max": 1
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "inputIndex",
            "type": "number",
            "required": true,
            "description": "Index of the input asset in balances.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "outputIndex",
            "type": "number",
            "required": true,
            "description": "Index of the output asset.",
            "constraints": {
              "min": 0,
              "integer": true
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ amountOut, invariant, priceImpact, iterations, converged, … }",
          "description": "Output with the invariant D and whether the Newton solve converged — an unconverged quote must not be traded on."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the indices are equal or out of range, or the solve fails to converge",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(assets × iterations)",
          "space": "O(assets)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "stableSwapQuote([1000,1000], 10, 100, 0.0004)",
        "args": [
          {
            "value": [
              1000,
              1000
            ],
            "elided": null
          },
          {
            "value": 10,
            "elided": null
          },
          {
            "value": 100,
            "elided": null
          },
          {
            "value": 0.0004,
            "elided": null
          }
        ],
        "output": {
          "model": "stableswap",
          "balancesBefore": [
            1000,
            1000
          ],
          "balancesAfter": [
            1010,
            990.004497337927
          ],
          "inputIndex": 0,
          "outputIndex": 1,
          "amountIn": 10,
          "grossAmountOut": 9.999502463058,
          "feeAmountOut": 0.003999800985,
          "amountOut": 9.995502662073,
          "executionPriceOutputPerInput": 0.999550266207,
          "priceImpactFromPegFraction": 0.000049753694,
          "DBefore": 2000,
          "DAfterFeeRetained": 2000.004000000989,
          "DIterations": 1
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 18
        },
        "outputShape": "object with 18 fields: model, balancesBefore, balancesAfter, inputIndex, outputIndex, amountIn, grossAmountOut, feeAmountOut, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d25-f01-a03/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "Uniswap v2 Core whitepaper",
          "author": "Uniswap",
          "url": null
        },
        {
          "key": "SRC-02",
          "title": "StableSwap whitepaper",
          "author": "Curve Finance / Michael Egorov",
          "url": null
        },
        {
          "key": "SRC-03",
          "title": "Balancer whitepaper",
          "author": "Balancer Labs",
          "url": null
        },
        {
          "key": "SRC-04",
          "title": "Uniswap v3 Core whitepaper",
          "author": "Uniswap",
          "url": null
        },
        {
          "key": "Source discipline",
          "title": "Source discipline",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/digital-assets-and-on-chain-finance/amm-pricing/stableswap-invariant/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/digital-assets-and-on-chain-finance/amm-pricing/stableswap-invariant/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D25-F01-A04",
      "name": "Weighted-Product AMM",
      "headline": null,
      "slug": "weighted-product-amm",
      "path": "digital-assets-and-on-chain-finance/amm-pricing/weighted-product-amm",
      "taxonomy": {
        "domainId": "D25",
        "domain": "Digital Assets and On-Chain Finance",
        "familyId": "D25-F01",
        "family": "AMM Pricing",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/digital-assets-and-on-chain-finance/amm-pricing/weighted-product-amm",
        "entry": "weightedProductQuote",
        "params": [
          "balanceIn",
          "balanceOut",
          "weightIn",
          "weightOut",
          "amountIn",
          "feeRate"
        ],
        "exports": [
          "constantProductQuote",
          "constantSumQuote",
          "stableSwapInvariant",
          "stableSwapQuote",
          "weightedProductQuote",
          "concentratedLiquidityPosition"
        ],
        "archetype": "record-transform",
        "signature": "weightedProductQuote(balanceIn, balanceOut, weightIn, weightOut, amountIn, feeRate)"
      },
      "api": {
        "summary": "Balancer's generalisation of constant product to arbitrary weights, so a pool can hold 80/20 rather than 50/50. The weights set both the target allocation and the slippage profile.",
        "params": [
          {
            "name": "balanceIn",
            "type": "number",
            "required": true,
            "description": "Balance of the input token.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "balanceOut",
            "type": "number",
            "required": true,
            "description": "Balance of the output token.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "weightIn",
            "type": "number",
            "required": true,
            "description": "Normalised weight of the input token.",
            "constraints": {
              "min": 0,
              "max": 1
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "weightOut",
            "type": "number",
            "required": true,
            "description": "Normalised weight of the output token.",
            "constraints": {
              "min": 0,
              "max": 1
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "amountIn",
            "type": "number",
            "required": true,
            "description": "Input amount.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "feeRate",
            "type": "number",
            "required": true,
            "description": "Fee as a fraction.",
            "constraints": {
              "min": 0,
              "max": 1
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ amountOut, priceImpact, spotPrice, … }",
          "description": "Output amount with the weighted spot price."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a weight is zero, or a balance is not positive",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "weightedProductQuote(800, 200, 0.8, 0.2, 40, 0.003)",
        "args": [
          {
            "value": 800,
            "elided": null
          },
          {
            "value": 200,
            "elided": null
          },
          {
            "value": 0.8,
            "elided": null
          },
          {
            "value": 0.2,
            "elided": null
          },
          {
            "value": 40,
            "elided": null
          },
          {
            "value": 0.003,
            "elided": null
          }
        ],
        "output": {
          "model": "weighted-product",
          "balanceInBefore": 800,
          "balanceOutBefore": 200,
          "weightIn": 0.8,
          "weightOut": 0.2,
          "amountIn": 40,
          "effectiveAmountIn": 39.88,
          "feeAmountIn": 0.12,
          "amountOut": 35.365448312358,
          "balanceInAfter": 840,
          "balanceOutAfter": 164.634551687642,
          "invariantBefore": 606.286626604159,
          "invariantAfterFeeRetained": 606.355925414232,
          "spotPriceBeforeOutputPerInput": 1
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 18
        },
        "outputShape": "object with 18 fields: model, balanceInBefore, balanceOutBefore, weightIn, weightOut, amountIn, effectiveAmountIn, feeAmountIn, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d25-f01-a04/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "Uniswap v2 Core whitepaper",
          "author": "Uniswap",
          "url": null
        },
        {
          "key": "SRC-02",
          "title": "StableSwap whitepaper",
          "author": "Curve Finance / Michael Egorov",
          "url": null
        },
        {
          "key": "SRC-03",
          "title": "Balancer whitepaper",
          "author": "Balancer Labs",
          "url": null
        },
        {
          "key": "SRC-04",
          "title": "Uniswap v3 Core whitepaper",
          "author": "Uniswap",
          "url": null
        },
        {
          "key": "Source discipline",
          "title": "Source discipline",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/digital-assets-and-on-chain-finance/amm-pricing/weighted-product-amm/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/digital-assets-and-on-chain-finance/amm-pricing/weighted-product-amm/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D25-F01-A05",
      "name": "Concentrated-Liquidity Position",
      "headline": null,
      "slug": "concentrated-liquidity-position",
      "path": "digital-assets-and-on-chain-finance/amm-pricing/concentrated-liquidity-position",
      "taxonomy": {
        "domainId": "D25",
        "domain": "Digital Assets and On-Chain Finance",
        "familyId": "D25-F01",
        "family": "AMM Pricing",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/digital-assets-and-on-chain-finance/amm-pricing/concentrated-liquidity-position",
        "entry": "concentratedLiquidityPosition",
        "params": [
          "liquidity",
          "priceLower",
          "priceUpper",
          "currentPrice"
        ],
        "exports": [
          "constantProductQuote",
          "constantSumQuote",
          "stableSwapInvariant",
          "stableSwapQuote",
          "weightedProductQuote",
          "concentratedLiquidityPosition"
        ],
        "archetype": "record-transform",
        "signature": "concentratedLiquidityPosition(liquidity, priceLower, priceUpper, currentPrice)"
      },
      "api": {
        "summary": "Uniswap v3 positions: liquidity supplied only within a price range. Far more capital-efficient inside the range, and entirely one-sided outside it — a position whose price has left its range is holding only the losing asset.",
        "params": [
          {
            "name": "liquidity",
            "type": "number",
            "required": true,
            "description": "Position liquidity L.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "priceLower",
            "type": "number",
            "required": true,
            "description": "Lower bound of the range.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "priceUpper",
            "type": "number",
            "required": true,
            "description": "Upper bound of the range.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          },
          {
            "name": "currentPrice",
            "type": "number",
            "required": true,
            "description": "Current pool price.",
            "constraints": {
              "min": 0
            },
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ amount0, amount1, inRange, … }",
          "description": "Token amounts held with an explicit in-range flag — out of range is the state that surprises position holders."
        },
        "warmup": null,
        "errors": [
          {
            "when": "priceLower is not below priceUpper",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "concentratedLiquidityPosition(1000, 0.81, 1.21, 0.7)",
        "args": [
          {
            "value": 1000,
            "elided": null
          },
          {
            "value": 0.81,
            "elided": null
          },
          {
            "value": 1.21,
            "elided": null
          },
          {
            "value": 0.7,
            "elided": null
          }
        ],
        "output": {
          "model": "concentrated-liquidity-position",
          "liquidity": 1000,
          "priceLowerToken1PerToken0": 0.81,
          "priceUpperToken1PerToken0": 1.21,
          "currentPriceToken1PerToken0": 0.7,
          "sqrtPriceLower": 0.9,
          "sqrtPriceUpper": 1.1,
          "sqrtPriceCurrent": 0.836660026534,
          "amount0": 202.020202020202,
          "amount1": 0,
          "valueInToken1AtCurrentPrice": 141.414141414141,
          "state": "below-range",
          "active": false,
          "boundaryConvention": "price<=lower is below; lower<price<upper is active; price>=upper is above"
        },
        "outputElided": null,
        "outputShape": "object with 14 fields: model, liquidity, priceLowerToken1PerToken0, priceUpperToken1PerToken0, currentPriceToken1PerToken0, sqrtPriceLower, sqrtPriceUpper, sqrtPriceCurrent, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "system-map.svg",
            "url": "https://thefintechbuilder.com/content/d25-f01-a05/static/system-map.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "SRC-01",
          "title": "Uniswap v2 Core whitepaper",
          "author": "Uniswap",
          "url": null
        },
        {
          "key": "SRC-02",
          "title": "StableSwap whitepaper",
          "author": "Curve Finance / Michael Egorov",
          "url": null
        },
        {
          "key": "SRC-03",
          "title": "Balancer whitepaper",
          "author": "Balancer Labs",
          "url": null
        },
        {
          "key": "SRC-04",
          "title": "Uniswap v3 Core whitepaper",
          "author": "Uniswap",
          "url": null
        },
        {
          "key": "SRC-05",
          "title": "Uniswap concentrated-liquidity concept guide",
          "author": "Uniswap Labs",
          "url": null
        },
        {
          "key": "Source discipline",
          "title": "Source discipline",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/digital-assets-and-on-chain-finance/amm-pricing/concentrated-liquidity-position/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/digital-assets-and-on-chain-finance/amm-pricing/concentrated-liquidity-position/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D25-F02-A01",
      "name": "Impermanent-Loss Calculation",
      "headline": null,
      "slug": "impermanent-loss-calculation",
      "path": "digital-assets-and-on-chain-finance/liquidity-and-liquidation/impermanent-loss-calculation",
      "taxonomy": {
        "domainId": "D25",
        "domain": "Digital Assets and On-Chain Finance",
        "familyId": "D25-F02",
        "family": "Liquidity and Liquidation",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/digital-assets-and-on-chain-finance/liquidity-and-liquidation/impermanent-loss-calculation",
        "entry": "impermanentLoss",
        "params": [
          "data",
          "config"
        ],
        "exports": [
          "impermanentLoss",
          "feeApr",
          "healthFactor",
          "liquidationPrice",
          "liquidationWaterfall",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "impermanentLoss(data, config)"
      },
      "api": {
        "summary": "Value lost by providing liquidity rather than simply holding the two assets. Called impermanent because it reverses if the price returns — which it frequently does not, and the loss is realised on withdrawal.",
        "params": [
          {
            "name": "data",
            "type": "PositionInput",
            "required": true,
            "description": "Position state — balances, prices, and the protocol parameters the calculation depends on.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "ProtocolConfig",
            "required": true,
            "description": "Protocol-specific thresholds and factors. These differ per protocol and per asset, so a figure computed under the wrong config is confidently wrong.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, value, components, diagnostics }",
          "description": "The result with every component, so a position's state can be reconciled against the protocol's own interface."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a required protocol parameter is missing",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(assets)",
          "space": "O(assets)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "impermanentLoss({\"initial_pool_value\":10000,\"price_ratio\":2}, {\"fee_return_fraction\":0})",
        "args": [
          {
            "value": {
              "initial_pool_value": 10000,
              "price_ratio": 2
            },
            "elided": null
          },
          {
            "value": {
              "fee_return_fraction": 0
            },
            "elided": null
          }
        ],
        "output": {
          "initial_pool_value": 10000,
          "price_ratio": 2,
          "hold_value": 15000,
          "pool_value_excluding_fees": 14142.135623731,
          "impermanent_loss_fraction": -0.0571909584,
          "impermanent_loss_amount": -857.864376269,
          "fee_income": 0,
          "net_pool_value": 14142.135623731,
          "net_vs_hold_fraction": -0.0571909584,
          "trace": [
            {
              "price_ratio": 0.2,
              "impermanent_loss": -0.2546440075,
              "hold_value": 6000,
              "pool_value": 4472.1359549996,
              "net_pool_value": 4472.1359549996
            },
            {
              "price_ratio": 0.2027004653,
              "impermanent_loss": -0.2513136942,
              "hold_value": 6013.5023266882,
              "pool_value": 4502.2268416601,
              "net_pool_value": 4502.2268416601
            },
            {
              "price_ratio": 0.2054373932,
              "impermanent_loss": -0.2479874573,
              "hold_value": 6027.1869662025,
              "pool_value": 4532.5201956582,
              "net_pool_value": 4532.5201956582
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: initial_pool_value, price_ratio, hold_value, pool_value_excluding_fees, impermanent_loss_fraction, impermanent_loss_amount, fee_income, net_pool_value, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "boundary-audit.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a01/static/boundary-audit.svg"
          },
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a01/static/calculation-map.svg"
          },
          {
            "file": "diagnostic-deep-dive.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a01/static/diagnostic-deep-dive.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a01/static/family-handoff.svg"
          },
          {
            "file": "parameter-sensitivity.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a01/static/parameter-sensitivity.svg"
          },
          {
            "file": "scenario-suite.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a01/static/scenario-suite.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "UNISWAP_V2",
          "title": "Uniswap v2 Core",
          "author": "Uniswap; Hayden Adams, Noah Zinsmeister, and Dan Robinson",
          "url": "https://app.uniswap.org/whitepaper.pdf"
        },
        {
          "key": "UNISWAP_V3",
          "title": "Uniswap v3 Core",
          "author": "Uniswap; Hayden Adams, Noah Zinsmeister, Moody Salem, River Keefer, and Dan Robinson",
          "url": "https://blog.uniswap.org/whitepaper-v3.pdf"
        },
        {
          "key": "CFMM_ANALYSIS",
          "title": "An Analysis of Uniswap Markets",
          "author": "Authors via arXiv; Guillermo Angeris, Hsien-Tang Kao, Rei Chiang, Charlie Noyes, and Tarun Chitra",
          "url": "https://arxiv.org/abs/1911.03380"
        },
        {
          "key": "IL_PAPER",
          "title": "UNISWAP: Impermanent Loss and Risk Profile of a Liquidity Provider",
          "author": "Authors via arXiv; Andreas Aigner and Gurvinder Dhaliwal",
          "url": "https://arxiv.org/abs/2106.14404"
        },
        {
          "key": "GENERAL_IL",
          "title": "Generalizing Impermanent Loss on Decentralized Exchanges with Constant Function Market Makers",
          "author": "Authors via arXiv; Rohan Tangri, Peter Yatsyshin, Elisabeth A. Duijnstee, and Danilo Mandic",
          "url": "https://arxiv.org/abs/2301.06831"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/digital-assets-and-on-chain-finance/liquidity-and-liquidation/impermanent-loss-calculation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/digital-assets-and-on-chain-finance/liquidity-and-liquidation/impermanent-loss-calculation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D25-F02-A02",
      "name": "Liquidity-Provider Fee APR",
      "headline": null,
      "slug": "liquidity-provider-fee-apr",
      "path": "digital-assets-and-on-chain-finance/liquidity-and-liquidation/liquidity-provider-fee-apr",
      "taxonomy": {
        "domainId": "D25",
        "domain": "Digital Assets and On-Chain Finance",
        "familyId": "D25-F02",
        "family": "Liquidity and Liquidation",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/digital-assets-and-on-chain-finance/liquidity-and-liquidation/liquidity-provider-fee-apr",
        "entry": "feeApr",
        "params": [
          "data",
          "config"
        ],
        "exports": [
          "impermanentLoss",
          "feeApr",
          "healthFactor",
          "liquidationPrice",
          "liquidationWaterfall",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "feeApr(data, config)"
      },
      "api": {
        "summary": "Annualised fee return for a liquidity position. Meaningful only net of impermanent loss: a headline APR quoted against a divergent pair routinely describes a losing position.",
        "params": [
          {
            "name": "data",
            "type": "PositionInput",
            "required": true,
            "description": "Position state — balances, prices, and the protocol parameters the calculation depends on.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "ProtocolConfig",
            "required": true,
            "description": "Protocol-specific thresholds and factors. These differ per protocol and per asset, so a figure computed under the wrong config is confidently wrong.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, value, components, diagnostics }",
          "description": "The result with every component, so a position's state can be reconciled against the protocol's own interface."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a required protocol parameter is missing",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(assets)",
          "space": "O(assets)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "feeApr({\"rows\":[{\"timestamp\":\"2026-01-01T00:00:00Z\",\"duration_days\":1,\"volume\":2500000,\"fee_rate\":0.003,\"lp_share\":0.02,\"lp_capital\":1000000},{\"timestamp\":\"2026-01-02T00:00:00Z\",\"duration_days\":1,\"volume\":2738636.056514657,\"fee_rate\":0.003,\"lp_share\":0.02,\"lp_capital\":1000000},{\"timestamp\":\"2026-01-03T00:00:00Z\",\"duration_days\":1,\"volume\":2930007.3153574164,\"fee_rate\":0.003,\"lp_share\":0.02,\"lp_capital\":1000000}]}, {\"annualization_days\":365,\"protocol_fee_share\":0,\"capital_basis\":\"time_weighted\"})",
        "args": [
          {
            "value": {
              "rows": [
                {
                  "timestamp": "2026-01-01T00:00:00Z",
                  "duration_days": 1,
                  "volume": 2500000,
                  "fee_rate": 0.003,
                  "lp_share": 0.02,
                  "lp_capital": 1000000
                },
                {
                  "timestamp": "2026-01-02T00:00:00Z",
                  "duration_days": 1,
                  "volume": 2738636.056514657,
                  "fee_rate": 0.003,
                  "lp_share": 0.02,
                  "lp_capital": 1000000
                },
                {
                  "timestamp": "2026-01-03T00:00:00Z",
                  "duration_days": 1,
                  "volume": 2930007.3153574164,
                  "fee_rate": 0.003,
                  "lp_share": 0.02,
                  "lp_capital": 1000000
                }
              ]
            },
            "elided": null
          },
          {
            "value": {
              "annualization_days": 365,
              "protocol_fee_share": 0,
              "capital_basis": "time_weighted"
            },
            "elided": null
          }
        ],
        "output": {
          "elapsed_days": 365,
          "gross_volume": 912500000,
          "lp_fee_income": 54750,
          "time_weighted_average_capital": 1000000,
          "capital_denominator": 1000000,
          "capital_basis": "time_weighted",
          "protocol_fee_share": 0,
          "simple_fee_apr": 0.05475,
          "period_fee_return": 0.05475,
          "annualization_days": 365,
          "trace": [
            {
              "index": 0,
              "timestamp": "2026-01-01T00:00:00Z",
              "volume": 2500000,
              "lp_capital": 1000000,
              "daily_fee_income": 150,
              "cumulative_fee_income": 150,
              "running_apr": 0.05475
            },
            {
              "index": 1,
              "timestamp": "2026-01-02T00:00:00Z",
              "volume": 2738636.056514657,
              "lp_capital": 1000000,
              "daily_fee_income": 164.3181633909,
              "cumulative_fee_income": 314.3181633909,
              "running_apr": 0.0573630648
            },
            {
              "index": 2,
              "timestamp": "2026-01-03T00:00:00Z",
              "volume": 2930007.3153574164,
              "lp_capital": 1000000,
              "daily_fee_income": 175.8004389214,
              "cumulative_fee_income": 490.1186023123,
              "running_apr": 0.0596310966
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: elapsed_days, gross_volume, lp_fee_income, time_weighted_average_capital, capital_denominator, capital_basis, protocol_fee_share, simple_fee_apr, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "boundary-audit.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a02/static/boundary-audit.svg"
          },
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a02/static/calculation-map.svg"
          },
          {
            "file": "diagnostic-deep-dive.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a02/static/diagnostic-deep-dive.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a02/static/family-handoff.svg"
          },
          {
            "file": "parameter-sensitivity.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a02/static/parameter-sensitivity.svg"
          },
          {
            "file": "scenario-suite.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a02/static/scenario-suite.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "UNISWAP_V2",
          "title": "Uniswap v2 Core",
          "author": "Uniswap; Hayden Adams, Noah Zinsmeister, and Dan Robinson",
          "url": "https://app.uniswap.org/whitepaper.pdf"
        },
        {
          "key": "UNISWAP_V3",
          "title": "Uniswap v3 Core",
          "author": "Uniswap; Hayden Adams, Noah Zinsmeister, Moody Salem, River Keefer, and Dan Robinson",
          "url": "https://blog.uniswap.org/whitepaper-v3.pdf"
        },
        {
          "key": "UNISWAP_V3_CORE",
          "title": "UniswapV3Pool.sol",
          "author": "Uniswap; Uniswap Labs and protocol contributors",
          "url": "https://github.com/Uniswap/v3-core/blob/main/contracts/UniswapV3Pool.sol"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/digital-assets-and-on-chain-finance/liquidity-and-liquidation/liquidity-provider-fee-apr/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/digital-assets-and-on-chain-finance/liquidity-and-liquidation/liquidity-provider-fee-apr/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D25-F02-A03",
      "name": "Collateral-Health Factor",
      "headline": null,
      "slug": "collateral-health-factor",
      "path": "digital-assets-and-on-chain-finance/liquidity-and-liquidation/collateral-health-factor",
      "taxonomy": {
        "domainId": "D25",
        "domain": "Digital Assets and On-Chain Finance",
        "familyId": "D25-F02",
        "family": "Liquidity and Liquidation",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/digital-assets-and-on-chain-finance/liquidity-and-liquidation/collateral-health-factor",
        "entry": "healthFactor",
        "params": [
          "data",
          "config"
        ],
        "exports": [
          "impermanentLoss",
          "feeApr",
          "healthFactor",
          "liquidationPrice",
          "liquidationWaterfall",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "healthFactor(data, config)"
      },
      "api": {
        "summary": "The ratio of weighted collateral to debt in a lending position. Below 1 the position is liquidatable, which makes it the single number a borrower has to watch.",
        "params": [
          {
            "name": "data",
            "type": "PositionInput",
            "required": true,
            "description": "Position state — balances, prices, and the protocol parameters the calculation depends on.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "ProtocolConfig",
            "required": true,
            "description": "Protocol-specific thresholds and factors. These differ per protocol and per asset, so a figure computed under the wrong config is confidently wrong.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, value, components, diagnostics }",
          "description": "The result with every component, so a position's state can be reconciled against the protocol's own interface."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a required protocol parameter is missing",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(assets)",
          "space": "O(assets)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "healthFactor({\"collateral\":[{\"asset\":\"WETH\",\"quantity\":2,\"price\":2000,\"liquidation_threshold\":0.8,\"eligible\":true}],\"debts\":[{\"asset\":\"USDC\",\"quantity\":2500,\"price\":1}],\"selected_asset\":\"WETH\"}, {\"collateral_price_multiplier\":1,\"debt_price_multiplier\":1})",
        "args": [
          {
            "value": {
              "collateral": [
                {
                  "asset": "WETH",
                  "quantity": 2,
                  "price": 2000,
                  "liquidation_threshold": 0.8,
                  "eligible": true
                }
              ],
              "debts": [
                {
                  "asset": "USDC",
                  "quantity": 2500,
                  "price": 1
                }
              ],
              "selected_asset": "WETH"
            },
            "elided": null
          },
          {
            "value": {
              "collateral_price_multiplier": 1,
              "debt_price_multiplier": 1
            },
            "elided": null
          }
        ],
        "output": {
          "total_collateral_value": 4000,
          "threshold_adjusted_collateral_value": 3200,
          "total_debt_value": 2500,
          "weighted_average_liquidation_threshold": 0.8,
          "health_factor": 1.28,
          "buffer_value": 700,
          "state": "above-threshold",
          "collateral_ledger": [
            {
              "asset": "WETH",
              "value": 4000,
              "threshold": 0.8,
              "eligible": true,
              "adjusted_contribution": 3200
            }
          ],
          "debt_ledger": [
            {
              "asset": "USDC",
              "value": 2500
            }
          ],
          "trace": [
            {
              "collateral_price_multiplier": 0.4,
              "health_factor": 0.512,
              "adjusted_collateral_value": 1280
            },
            {
              "collateral_price_multiplier": 0.4041666667,
              "health_factor": 0.5173333333,
              "adjusted_collateral_value": 1293.3333333333
            },
            {
              "collateral_price_multiplier": 0.4083333333,
              "health_factor": 0.5226666667,
              "adjusted_collateral_value": 1306.6666666667
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 10 fields: total_collateral_value, threshold_adjusted_collateral_value, total_debt_value, weighted_average_liquidation_threshold, health_factor, buffer_value, state, collateral_ledger, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "boundary-audit.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a03/static/boundary-audit.svg"
          },
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a03/static/calculation-map.svg"
          },
          {
            "file": "diagnostic-deep-dive.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a03/static/diagnostic-deep-dive.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a03/static/family-handoff.svg"
          },
          {
            "file": "parameter-sensitivity.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a03/static/parameter-sensitivity.svg"
          },
          {
            "file": "scenario-suite.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a03/static/scenario-suite.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "AAVE_LIQUIDATIONS",
          "title": "Health Factor & Liquidations",
          "author": "Aave; Aave Labs documentation team",
          "url": "https://aave.com/help/borrowing/liquidations"
        },
        {
          "key": "AAVE_RISK_PARAMETERS",
          "title": "Aave V3 Risk Parameters",
          "author": "Aave; Aave risk contributors",
          "url": "https://github.com/aave/risk-v3/blob/main/asset-risk/risk-parameters.md"
        },
        {
          "key": "AAVE_V3_LOGIC",
          "title": "Aave V3 LiquidationLogic.sol",
          "author": "Aave; Aave protocol contributors",
          "url": "https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/logic/LiquidationLogic.sol"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/digital-assets-and-on-chain-finance/liquidity-and-liquidation/collateral-health-factor/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/digital-assets-and-on-chain-finance/liquidity-and-liquidation/collateral-health-factor/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D25-F02-A04",
      "name": "Liquidation-Price Calculation",
      "headline": null,
      "slug": "liquidation-price-calculation",
      "path": "digital-assets-and-on-chain-finance/liquidity-and-liquidation/liquidation-price-calculation",
      "taxonomy": {
        "domainId": "D25",
        "domain": "Digital Assets and On-Chain Finance",
        "familyId": "D25-F02",
        "family": "Liquidity and Liquidation",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/digital-assets-and-on-chain-finance/liquidity-and-liquidation/liquidation-price-calculation",
        "entry": "liquidationPrice",
        "params": [
          "data",
          "config"
        ],
        "exports": [
          "impermanentLoss",
          "feeApr",
          "healthFactor",
          "liquidationPrice",
          "liquidationWaterfall",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "liquidationPrice(data, config)"
      },
      "api": {
        "summary": "The collateral price at which a position becomes liquidatable. The number a borrower actually needs — a health factor is abstract, a price is something you can set an alert on.",
        "params": [
          {
            "name": "data",
            "type": "PositionInput",
            "required": true,
            "description": "Position state — balances, prices, and the protocol parameters the calculation depends on.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "ProtocolConfig",
            "required": true,
            "description": "Protocol-specific thresholds and factors. These differ per protocol and per asset, so a figure computed under the wrong config is confidently wrong.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, value, components, diagnostics }",
          "description": "The result with every component, so a position's state can be reconciled against the protocol's own interface."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a required protocol parameter is missing",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(assets)",
          "space": "O(assets)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "liquidationPrice({\"collateral\":[{\"asset\":\"WETH\",\"quantity\":2,\"price\":2000,\"liquidation_threshold\":0.8,\"eligible\":true}],\"debts\":[{\"asset\":\"USDC\",\"quantity\":2500,\"price\":1}],\"selected_asset\":\"WETH\"}, {\"debt_multiplier\":1,\"threshold_shift\":0})",
        "args": [
          {
            "value": {
              "collateral": [
                {
                  "asset": "WETH",
                  "quantity": 2,
                  "price": 2000,
                  "liquidation_threshold": 0.8,
                  "eligible": true
                }
              ],
              "debts": [
                {
                  "asset": "USDC",
                  "quantity": 2500,
                  "price": 1
                }
              ],
              "selected_asset": "WETH"
            },
            "elided": null
          },
          {
            "value": {
              "debt_multiplier": 1,
              "threshold_shift": 0
            },
            "elided": null
          }
        ],
        "output": {
          "selected_asset": "WETH",
          "selected_quantity": 2,
          "current_selected_price": 2000,
          "effective_selected_liquidation_threshold": 0.8,
          "total_debt_value": 2500,
          "other_adjusted_collateral_value": 0,
          "liquidation_price": 1562.5,
          "distance_to_liquidation_fraction": 0.21875,
          "current_health_factor": 1.28,
          "reason": "finite break-even price",
          "trace": [
            {
              "price_multiplier": 0.4,
              "selected_price": 800,
              "health_factor": 0.512
            },
            {
              "price_multiplier": 0.4041666667,
              "selected_price": 808.3333333333,
              "health_factor": 0.5173333333
            },
            {
              "price_multiplier": 0.4083333333,
              "selected_price": 816.6666666667,
              "health_factor": 0.5226666667
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 11 fields: selected_asset, selected_quantity, current_selected_price, effective_selected_liquidation_threshold, total_debt_value, other_adjusted_collateral_value, liquidation_price, distance_to_liquidation_fraction, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "boundary-audit.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a04/static/boundary-audit.svg"
          },
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a04/static/calculation-map.svg"
          },
          {
            "file": "diagnostic-deep-dive.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a04/static/diagnostic-deep-dive.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a04/static/family-handoff.svg"
          },
          {
            "file": "parameter-sensitivity.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a04/static/parameter-sensitivity.svg"
          },
          {
            "file": "scenario-suite.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a04/static/scenario-suite.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "AAVE_LIQUIDATIONS",
          "title": "Health Factor & Liquidations",
          "author": "Aave; Aave Labs documentation team",
          "url": "https://aave.com/help/borrowing/liquidations"
        },
        {
          "key": "AAVE_RISK_PARAMETERS",
          "title": "Aave V3 Risk Parameters",
          "author": "Aave; Aave risk contributors",
          "url": "https://github.com/aave/risk-v3/blob/main/asset-risk/risk-parameters.md"
        },
        {
          "key": "AAVE_V3_LOGIC",
          "title": "Aave V3 LiquidationLogic.sol",
          "author": "Aave; Aave protocol contributors",
          "url": "https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/logic/LiquidationLogic.sol"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/digital-assets-and-on-chain-finance/liquidity-and-liquidation/liquidation-price-calculation/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/digital-assets-and-on-chain-finance/liquidity-and-liquidation/liquidation-price-calculation/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D25-F02-A05",
      "name": "Liquidation Waterfall",
      "headline": null,
      "slug": "liquidation-waterfall",
      "path": "digital-assets-and-on-chain-finance/liquidity-and-liquidation/liquidation-waterfall",
      "taxonomy": {
        "domainId": "D25",
        "domain": "Digital Assets and On-Chain Finance",
        "familyId": "D25-F02",
        "family": "Liquidity and Liquidation",
        "difficulty": 4
      },
      "import": {
        "subpath": "fintech-algorithms/digital-assets-and-on-chain-finance/liquidity-and-liquidation/liquidation-waterfall",
        "entry": "liquidationWaterfall",
        "params": [
          "data",
          "config"
        ],
        "exports": [
          "impermanentLoss",
          "feeApr",
          "healthFactor",
          "liquidationPrice",
          "liquidationWaterfall",
          "runTopic"
        ],
        "archetype": "record-transform",
        "signature": "liquidationWaterfall(data, config)"
      },
      "api": {
        "summary": "The order in which collateral is seized and debt repaid, including liquidation bonus and any protocol fee. Determines what a borrower recovers, and it is rarely proportional.",
        "params": [
          {
            "name": "data",
            "type": "PositionInput",
            "required": true,
            "description": "Position state — balances, prices, and the protocol parameters the calculation depends on.",
            "constraints": null,
            "nulls": null,
            "default": null
          },
          {
            "name": "config",
            "type": "ProtocolConfig",
            "required": true,
            "description": "Protocol-specific thresholds and factors. These differ per protocol and per asset, so a figure computed under the wrong config is confidently wrong.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ status, value, components, diagnostics }",
          "description": "The result with every component, so a position's state can be reconciled against the protocol's own interface."
        },
        "warmup": null,
        "errors": [
          {
            "when": "a required protocol parameter is missing",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(assets)",
          "space": "O(assets)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "liquidationWaterfall({\"debt_value\":10000,\"collateral_sale_proceeds\":7000,\"protocol_reserve\":1000,\"insurance_fund\":2500,\"backstop_capacity\":1000}, {\"collateral_recovery_rate\":1,\"backstop_enabled\":true})",
        "args": [
          {
            "value": {
              "debt_value": 10000,
              "collateral_sale_proceeds": 7000,
              "protocol_reserve": 1000,
              "insurance_fund": 2500,
              "backstop_capacity": 1000
            },
            "elided": null
          },
          {
            "value": {
              "collateral_recovery_rate": 1,
              "backstop_enabled": true
            },
            "elided": null
          }
        ],
        "output": {
          "debt_value": 10000,
          "effective_collateral_proceeds": 7000,
          "total_buffer_capacity": 4500,
          "covered_debt": 10000,
          "uncovered_bad_debt": 0,
          "coverage_fraction": 1,
          "backstop_enabled": true,
          "ledger": [
            {
              "layer": "collateral-recovery",
              "available_capacity": 7000,
              "absorbed": 7000,
              "remaining_debt": 3000,
              "cumulative_absorbed": 7000
            },
            {
              "layer": "protocol-reserve",
              "available_capacity": 1000,
              "absorbed": 1000,
              "remaining_debt": 2000,
              "cumulative_absorbed": 8000
            },
            {
              "layer": "insurance-fund",
              "available_capacity": 2500,
              "absorbed": 2000,
              "remaining_debt": 0,
              "cumulative_absorbed": 10000
            }
          ],
          "trace": [
            {
              "collateral_proceeds_multiplier": 0,
              "covered_debt": 4500,
              "uncovered_bad_debt": 5500
            },
            {
              "collateral_proceeds_multiplier": 0.005,
              "covered_debt": 4535,
              "uncovered_bad_debt": 5465
            },
            {
              "collateral_proceeds_multiplier": 0.01,
              "covered_debt": 4570,
              "uncovered_bad_debt": 5430
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 9 fields: debt_value, effective_collateral_proceeds, total_buffer_capacity, covered_debt, uncovered_bad_debt, coverage_fraction, backstop_enabled, ledger, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "boundary-audit.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a05/static/boundary-audit.svg"
          },
          {
            "file": "calculation-map.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a05/static/calculation-map.svg"
          },
          {
            "file": "diagnostic-deep-dive.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a05/static/diagnostic-deep-dive.svg"
          },
          {
            "file": "family-handoff.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a05/static/family-handoff.svg"
          },
          {
            "file": "parameter-sensitivity.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a05/static/parameter-sensitivity.svg"
          },
          {
            "file": "scenario-suite.svg",
            "url": "https://thefintechbuilder.com/content/d25-f02-a05/static/scenario-suite.svg"
          }
        ],
        "mermaid": []
      },
      "references": [
        {
          "key": "COMPOUND_III",
          "title": "Compound III Liquidation",
          "author": "Compound; Compound documentation team",
          "url": "https://docs.compound.finance/liquidation/"
        },
        {
          "key": "MAKER_LIQUIDATION",
          "title": "Liquidation 2.0 Module",
          "author": "MakerDAO; Maker Protocol documentation contributors",
          "url": "https://docs.makerdao.com/smart-contract-modules/dog-and-clipper-detailed-documentation"
        },
        {
          "key": "AAVE_LIQUIDATIONS",
          "title": "Health Factor & Liquidations",
          "author": "Aave; Aave Labs documentation team",
          "url": "https://aave.com/help/borrowing/liquidations"
        },
        {
          "key": "AAVE_V3_LOGIC",
          "title": "Aave V3 LiquidationLogic.sol",
          "author": "Aave; Aave protocol contributors",
          "url": "https://github.com/aave/aave-v3-core/blob/master/contracts/protocol/libraries/logic/LiquidationLogic.sol"
        },
        {
          "key": "Evidence boundary",
          "title": "Evidence boundary",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/digital-assets-and-on-chain-finance/liquidity-and-liquidation/liquidation-waterfall/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/digital-assets-and-on-chain-finance/liquidity-and-liquidation/liquidation-waterfall/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D46-F01-A05",
      "name": "Stock-Split/Consolidation EPS Restatement",
      "headline": null,
      "slug": "stock-split-consolidation-eps-restatement",
      "path": "earnings-and-per-share-analytics/earnings-and-share-foundations/stock-split-consolidation-eps-restatement",
      "taxonomy": {
        "domainId": "D46",
        "domain": "Earnings and Per-Share Analytics",
        "familyId": "D46-F01",
        "family": "Earnings and Share Foundations",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/earnings-and-per-share-analytics/earnings-and-share-foundations/stock-split-consolidation-eps-restatement",
        "entry": "restateEpsForCapitalEvents",
        "params": [
          "input"
        ],
        "exports": [
          "restateEpsForCapitalEvents"
        ],
        "archetype": "record-transform",
        "signature": "restateEpsForCapitalEvents(input)"
      },
      "api": {
        "summary": "Restates EPS for splits and consolidations across every period presented. Accounting standards require retrospective restatement — comparatives must be restated too, and a table where only the current period was adjusted is wrong in a way that looks like growth.",
        "params": [
          {
            "name": "input",
            "type": "RestatementInput",
            "required": true,
            "description": "`accounting_framework` selects IFRS or US GAAP treatment. The scale and rounding fields (`earnings_scale`, `share_scale`, `share_decimal_places`, `eps_decimal_places`, `rounding_mode`) are part of the contract because published EPS is a rounded figure and reproducing it requires the same rounding.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ metric, accounting_framework, currency, status, rows }",
          "description": "Restated figures per period with the framework and rounding that produced them."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the accounting framework or rounding mode is unrecognised",
            "behaviour": "throws"
          }
        ],
        "complexity": {
          "time": "O(periods × events)",
          "space": "O(periods)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "restateEpsForCapitalEvents({\"accounting_framework\":\"IFRS\",\"currency\":\"USD\",\"statements_authorized_for_issue_date\":\"2026-02-20\",\"earnings_scale\":\"1000\",\"share_scale\":\"1000\",\"share_decimal_places\":0,\"eps_decimal_places\":4,\"rounding_mode\":\"half_even\",\"restatement_policy\":\"Apply IAS 33.64 retrospectively through authorization.\",\"event_source_policy\":\"Board-approved and legally effective capital events.\",\"events\":[{\"event_id\":\"SPLIT-2026-01\",\"effective_date\":\"2026-01-15\",\"event_type\":\"stock_split\",\"post_split_shares\":\"2\",\"pre_split_shares\":\"1\",\"event_is_effective\":true,\"changes_resources\":false}],\"periods\":[{\"period_id\":\"FY2025\",\"period_start\":\"2025-01-01\",\"period_end\":\"2025-12-31\",\"basis_date\":\"2025-12-31\",\"basis_is_uniform\":true,\"earnings_available_to_ordinary_shareholders\":\"8000\",\"weighted_average_ordinary_shares\":\"2000\",\"is_final\":true}]})",
        "args": [
          {
            "value": {
              "accounting_framework": "IFRS",
              "currency": "USD",
              "statements_authorized_for_issue_date": "2026-02-20",
              "earnings_scale": "1000",
              "share_scale": "1000",
              "share_decimal_places": 0,
              "eps_decimal_places": 4,
              "rounding_mode": "half_even",
              "restatement_policy": "Apply IAS 33.64 retrospectively through authorization.",
              "event_source_policy": "Board-approved and legally effective capital events.",
              "events": [
                {
                  "event_id": "SPLIT-2026-01",
                  "effective_date": "2026-01-15",
                  "event_type": "stock_split",
                  "post_split_shares": "2",
                  "pre_split_shares": "1",
                  "event_is_effective": true,
                  "changes_resources": false
                }
              ],
              "periods": [
                {
                  "period_id": "FY2025",
                  "period_start": "2025-01-01",
                  "period_end": "2025-12-31",
                  "basis_date": "2025-12-31",
                  "basis_is_uniform": true,
                  "earnings_available_to_ordinary_shareholders": "8000",
                  "weighted_average_ordinary_shares": "2000",
                  "is_final": true
                }
              ]
            },
            "elided": null
          }
        ],
        "output": {
          "metric": "stock_split_consolidation_eps_restatement",
          "accounting_framework": "IFRS",
          "currency": "USD",
          "statements_authorized_for_issue_date": "2026-02-20",
          "status": "final",
          "rows": [
            {
              "period_id": "FY2025",
              "period_start": "2025-01-01",
              "period_end": "2025-12-31",
              "source_basis_date": "2025-12-31",
              "applied_event_ids": [
                "SPLIT-2026-01"
              ],
              "factor_numerator": "2",
              "factor_denominator": "1",
              "earnings_available_to_ordinary_shareholders": "8000000",
              "pre_restatement_shares": "2000000",
              "restated_shares": "4000000",
              "pre_restatement_basic_eps": "4.0000",
              "restated_basic_eps": "2.0000",
              "share_rounding_adjusted": false,
              "eps_rounding_adjusted": false
            }
          ]
        },
        "outputElided": null,
        "outputShape": "object with 6 fields: metric, accounting_framework, currency, statements_authorized_for_issue_date, status, rows"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "post-period-restatement-timeline.svg",
            "url": "https://thefintechbuilder.com/content/d46-f01-a05/static/post-period-restatement-timeline.svg"
          },
          {
            "file": "split-direction-bridge.svg",
            "url": "https://thefintechbuilder.com/content/d46-f01-a05/static/split-direction-bridge.svg"
          }
        ],
        "mermaid": [
          {
            "file": "authorization-window.md",
            "caption": "Post-period authorization window",
            "source": "sequenceDiagram\n  participant P as \"FY2025 ends\"\n  participant S as \"2-for-1 split\"\n  participant A as \"Statements authorized\"\n  P->>S: \"2025-12-31\"\n  S->>A: \"Effective 2026-01-15\"\n  A-->>P: \"Present FY2025 on the new share basis\""
          },
          {
            "file": "restatement-flow.md",
            "caption": "Restatement calculation flow",
            "source": "flowchart LR\n  A[\"Validated period row\"] --> B[\"Read uniform source basis date\"]\n  E[\"Effective ordered events through authorization\"] --> C[\"Select events after basis date\"]\n  B --> C\n  C --> D[\"Multiply exact factors\"]\n  D --> F[\"Restated shares = source shares × factor\"]\n  A --> G[\"Preserve earnings numerator\"]\n  F --> H[\"Restated EPS = earnings ÷ restated shares\"]\n  G --> H\n  H --> I[\"Round display fields and emit diagnostics\"]"
          }
        ]
      },
      "references": [
        {
          "key": "Primary accounting sources",
          "title": "Primary accounting sources",
          "author": null,
          "url": null
        },
        {
          "key": "Historical case sources",
          "title": "Historical case sources",
          "author": null,
          "url": null
        },
        {
          "key": "Technical sources",
          "title": "Technical sources",
          "author": null,
          "url": null
        },
        {
          "key": "Applicability and limitations",
          "title": "Applicability and limitations",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/earnings-and-per-share-analytics/earnings-and-share-foundations/stock-split-consolidation-eps-restatement/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/earnings-and-per-share-analytics/earnings-and-share-foundations/stock-split-consolidation-eps-restatement/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D46-F01-A08",
      "name": "Basic EPS",
      "headline": null,
      "slug": "basic-eps",
      "path": "earnings-and-per-share-analytics/earnings-and-share-foundations/basic-eps",
      "taxonomy": {
        "domainId": "D46",
        "domain": "Earnings and Per-Share Analytics",
        "familyId": "D46-F01",
        "family": "Earnings and Share Foundations",
        "difficulty": 2
      },
      "import": {
        "subpath": "fintech-algorithms/earnings-and-per-share-analytics/earnings-and-share-foundations/basic-eps",
        "entry": "calculateBasicEps",
        "params": [
          "input"
        ],
        "exports": [
          "calculateBasicEps"
        ],
        "archetype": "record-transform",
        "signature": "calculateBasicEps(input)"
      },
      "api": {
        "summary": "Basic earnings per share: profit attributable to ordinary shareholders over the weighted average shares outstanding. Both halves are subtler than they look — the numerator is after preference dividends, and the denominator is time-weighted, not a period-end count.",
        "params": [
          {
            "name": "input",
            "type": "BasicEpsInput",
            "required": true,
            "description": "`profit_loss_attributable_to_owners` and `preference_dividend_adjustments` form the numerator; the share records form the time-weighted denominator. `as_of` bounds which filings are usable, and `statement_scope` distinguishes consolidated from separate statements.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ metric, entity_id, period_start, period_end, accounting_framework, statement_scope, … }",
          "description": "The EPS figure with both components and the weighting applied, so a disagreement with a published number can be localised to numerator or denominator."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the weighted average share count is zero or negative",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(share events)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculateBasicEps({\"entity_id\":\"EXAMPLE-PLC\",\"period_start\":\"2025-01-01\",\"period_end\":\"2025-12-31\",\"as_of\":\"2026-02-20T16:30:00Z\",\"accounting_framework\":\"IFRS\",\"statement_scope\":\"consolidated\",\"currency\":\"USD\",\"profit_loss_attributable_to_owners\":\"12500\",\"preference_dividend_adjustment\":\"500\",\"participating_security_allocation\":\"0\",\"other_numerator_adjustment\":\"0\",\"earnings_scale\":\"1000\",\"weighted_average_ordinary_shares\":\"6000\",\"share_scale\":\"1000\"})",
        "args": [
          {
            "value": {
              "entity_id": "EXAMPLE-PLC",
              "period_start": "2025-01-01",
              "period_end": "2025-12-31",
              "as_of": "2026-02-20T16:30:00Z",
              "accounting_framework": "IFRS",
              "statement_scope": "consolidated",
              "currency": "USD",
              "profit_loss_attributable_to_owners": "12500",
              "preference_dividend_adjustment": "500",
              "participating_security_allocation": "0",
              "other_numerator_adjustment": "0",
              "earnings_scale": "1000",
              "weighted_average_ordinary_shares": "6000",
              "share_scale": "1000"
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 21
            }
          }
        ],
        "output": {
          "metric": "basic_earnings_per_ordinary_share",
          "entity_id": "EXAMPLE-PLC",
          "period_start": "2025-01-01",
          "period_end": "2025-12-31",
          "as_of": "2026-02-20T16:30:00Z",
          "accounting_framework": "IFRS",
          "statement_scope": "consolidated",
          "currency": "USD",
          "numerator_policy": "Profit attributable to owners less after-tax preference dividends.",
          "denominator_policy": "IAS 33 weighted-average ordinary shares, retrospectively restated.",
          "earnings_available_to_ordinary_shareholders": "12000000",
          "weighted_average_ordinary_shares_base": "6000000",
          "basic_eps": "2.0000",
          "decimal_places": 4
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 19
        },
        "outputShape": "object with 19 fields: metric, entity_id, period_start, period_end, as_of, accounting_framework, statement_scope, currency, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "basic-eps-fraction.svg",
            "url": "https://thefintechbuilder.com/content/d46-f01-a08/static/basic-eps-fraction.svg"
          },
          {
            "file": "same-earnings-different-shares.svg",
            "url": "https://thefintechbuilder.com/content/d46-f01-a08/static/same-earnings-different-shares.svg"
          }
        ],
        "mermaid": [
          {
            "file": "basic-versus-diluted.md",
            "caption": "Basic EPS boundary",
            "source": "flowchart TB\n  P[\"Profit or loss attributable to owners\"] --> N[\"Less preference adjustment\"]\n  S[\"Participating-security allocation\"] --> N\n  O[\"Signed other adjustment\"] --> N\n  N --> E[\"Earnings available to ordinary shareholders\"]\n  W[\"Restated weighted-average ordinary shares\"] --> B[\"Basic EPS\"]\n  E --> B\n  Q[\"Potential ordinary shares\"] --> D[\"Diluted EPS — separate topic\"]\n  B -. \"starting point\" .-> D"
          },
          {
            "file": "calculation-gates.md",
            "caption": "Calculation gates",
            "source": "flowchart LR\n  A[\"Reporting identity and period\"] --> B{\"Framework and scope declared?\"}\n  B -- \"No\" --> X[\"Reject\"]\n  B -- \"Yes\" --> C{\"Numerator attribution complete?\"}\n  C -- \"No\" --> X\n  C -- \"Yes\" --> D{\"Denominator restatement complete?\"}\n  D -- \"No\" --> X\n  D -- \"Yes\" --> E[\"Apply explicit unit scales\"]\n  E --> F[\"Divide exact decimals\"]\n  F --> G[\"Round by declared policy\"]\n  G --> H[\"Basic EPS plus audit diagnostics\"]"
          }
        ]
      },
      "references": [
        {
          "key": "IAS33",
          "title": "IAS 33 Earnings per Share",
          "author": "IFRS Foundation and International Accounting Standards Board",
          "url": null
        },
        {
          "key": "ASC260",
          "title": "FASB Accounting Standards Codification Topic 260",
          "author": "Financial Accounting Standards Board",
          "url": null
        },
        {
          "key": "FMAO-10Q",
          "title": "Farmers & Merchants Bancorp, Inc. 2025 second-quarter Form 10-Q",
          "author": "Farmers & Merchants Bancorp, Inc.; filed with the U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "SEC-SUBMISSIONS",
          "title": "SEC EDGAR submissions metadata for CIK 0000792966",
          "author": "U.S. Securities and Exchange Commission",
          "url": null
        },
        {
          "key": "RFC3339",
          "title": "Date and Time on the Internet: Timestamps",
          "author": "Internet Engineering Task Force",
          "url": null
        },
        {
          "key": "ECMASCRIPT-BIGINT",
          "title": "ECMAScript BigInt Objects",
          "author": "Ecma International",
          "url": null
        },
        {
          "key": "PYTHON-INT",
          "title": "Python integer numeric type",
          "author": "Python Software Foundation",
          "url": null
        },
        {
          "key": "Research notes and limits",
          "title": "Research notes and limits",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/earnings-and-per-share-analytics/earnings-and-share-foundations/basic-eps/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/earnings-and-per-share-analytics/earnings-and-share-foundations/basic-eps/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D46-F02-A02",
      "name": "If-Converted Convertible-Preference Dilution",
      "headline": null,
      "slug": "if-converted-convertible-preference-dilution",
      "path": "earnings-and-per-share-analytics/basic-and-diluted-eps/if-converted-convertible-preference-dilution",
      "taxonomy": {
        "domainId": "D46",
        "domain": "Earnings and Per-Share Analytics",
        "familyId": "D46-F02",
        "family": "Basic and Diluted EPS",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/earnings-and-per-share-analytics/basic-and-diluted-eps/if-converted-convertible-preference-dilution",
        "entry": "calculateConvertiblePreferenceDilution",
        "params": [
          "input"
        ],
        "exports": [
          "calculateConvertiblePreferenceDilution"
        ],
        "archetype": "record-transform",
        "signature": "calculateConvertiblePreferenceDilution(input)"
      },
      "api": {
        "summary": "The if-converted method for convertible preference shares: assume conversion, add the shares, add back the preference dividend. Conversion is only included when it is **dilutive** — an anti-dilutive instrument is excluded, and including it overstates EPS.",
        "params": [
          {
            "name": "input",
            "type": "DilutionInput",
            "required": true,
            "description": "The instrument's conversion terms plus `basic_control_numerator` and `basic_weighted_average_shares`, which are the control figures the dilution test is measured against.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ metric, loss_making_period_flag, dilutive, diluted_eps, … }",
          "description": "The diluted figure with an explicit dilutive/anti-dilutive determination, and a loss-making flag — in a loss period potential shares are anti-dilutive by definition, which reverses the usual test."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the conversion ratio is missing or not positive",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculateConvertiblePreferenceDilution({\"entity_id\":\"EXAMPLE-PLC\",\"instrument_id\":\"SERIES-A-CPS\",\"period_start\":\"2025-01-01\",\"period_end\":\"2025-12-31\",\"as_of\":\"2026-02-20T16:30:00Z\",\"accounting_framework\":\"IFRS\",\"currency\":\"USD\",\"basic_control_numerator\":\"90\",\"basic_weighted_average_shares\":\"30\",\"earnings_scale\":\"1000000\",\"share_scale\":\"1000000\",\"preferred_dividend_adjustment_deducted_from_basic\":\"6\",\"other_pre_tax_income_adjustment_if_converted\":\"0\",\"income_tax_effect_of_other_adjustment_if_converted\":\"0\"})",
        "args": [
          {
            "value": {
              "entity_id": "EXAMPLE-PLC",
              "instrument_id": "SERIES-A-CPS",
              "period_start": "2025-01-01",
              "period_end": "2025-12-31",
              "as_of": "2026-02-20T16:30:00Z",
              "accounting_framework": "IFRS",
              "currency": "USD",
              "basic_control_numerator": "90",
              "basic_weighted_average_shares": "30",
              "earnings_scale": "1000000",
              "share_scale": "1000000",
              "preferred_dividend_adjustment_deducted_from_basic": "6",
              "other_pre_tax_income_adjustment_if_converted": "0",
              "income_tax_effect_of_other_adjustment_if_converted": "0"
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 45
            }
          }
        ],
        "output": {
          "metric": "if_converted_convertible_preference_dilution",
          "entity_id": "EXAMPLE-PLC",
          "instrument_id": "SERIES-A-CPS",
          "period_start": "2025-01-01",
          "period_end": "2025-12-31",
          "accounting_framework": "IFRS",
          "loss_control_rule": "candidate_comparison",
          "currency": "USD",
          "basic_control_numerator_base": "90000000",
          "basic_weighted_average_shares_base": "30000000",
          "preferred_dividend_addback_base": "6000000",
          "other_pre_tax_income_adjustment_base": "0",
          "income_tax_effect_of_other_adjustment_base": "0",
          "net_numerator_adjustment_base": "6000000"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 37
        },
        "outputShape": "object with 37 fields: metric, entity_id, instrument_id, period_start, period_end, accounting_framework, loss_control_rule, currency, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "preference-conversion-bridge.svg",
            "url": "https://thefintechbuilder.com/content/d46-f02-a02/static/preference-conversion-bridge.svg"
          }
        ],
        "mermaid": [
          {
            "file": "if-converted-preference-flow.md",
            "caption": "If-converted preference decision flow",
            "source": "flowchart TD\n    A[\"Receive one preferred series and Basic continuing-operations control\"] --> B{\"Basic, dividend, share basis, and terms complete?\"}\n    B -->|No| R[\"Reject incomplete contract\"]\n    B -->|Yes| P{\"Participating, partial, contingent-unresolved, or variable terms?\"}\n    P -->|Participating| T[\"Route to D46-F02-A05 two-class resolution\"]\n    P -->|Unresolved| U[\"Resolve framework, contingency, tranche, and holder-advantageous terms\"]\n    P -->|No| S[\"Exposure start = later of period start and issue date\"]\n    S --> E[\"Exposure end (exclusive) = earliest of period end + 1, conversion, or lapse\"]\n    E --> W[\"ΔD = fixed conversion shares × exposure days / period days\"]\n    W --> N[\"ΔN = Basic-basis dividend + other pre-tax effect + explicit tax effect\"]\n    N --> C[\"Candidate = (Basic numerator + ΔN) / (Basic shares + ΔD)\"]\n    C --> L{\"Declared rule excludes all shares for a control loss?\"}\n    L -->|Yes| X[\"Framework loss-control exclusion\"]\n    L -->|No| D{\"Exact candidate < exact Basic EPS?\"}\n    D -->|Yes| I[\"Dilutive: include in standalone candidate\"]\n    D -->|No or equal| X[\"Antidilutive: exclude\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R01",
          "title": "IAS 33 Earnings per Share",
          "author": null,
          "url": null
        },
        {
          "key": "R02",
          "title": "FASB Statement No. 128, Earnings per Share",
          "author": null,
          "url": null
        },
        {
          "key": "R03",
          "title": "ASU 2020-06, Debt—Debt with Conversion and Other Options and Derivatives and Hedging",
          "author": null,
          "url": null
        },
        {
          "key": "R04",
          "title": "Celsius Holdings, Inc. 2026 first-quarter EPS note",
          "author": null,
          "url": null
        },
        {
          "key": "Research reconciliation",
          "title": "Research reconciliation",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/earnings-and-per-share-analytics/basic-and-diluted-eps/if-converted-convertible-preference-dilution/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/earnings-and-per-share-analytics/basic-and-diluted-eps/if-converted-convertible-preference-dilution/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D46-F02-A03",
      "name": "Treasury-Share Method for Options/Warrants",
      "headline": null,
      "slug": "treasury-share-method-for-options-warrants",
      "path": "earnings-and-per-share-analytics/basic-and-diluted-eps/treasury-share-method-for-options-warrants",
      "taxonomy": {
        "domainId": "D46",
        "domain": "Earnings and Per-Share Analytics",
        "familyId": "D46-F02",
        "family": "Basic and Diluted EPS",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/earnings-and-per-share-analytics/basic-and-diluted-eps/treasury-share-method-for-options-warrants",
        "entry": "calculateTreasuryShareMethod",
        "params": [
          "input"
        ],
        "exports": [
          "calculateTreasuryShareMethod"
        ],
        "archetype": "record-transform",
        "signature": "calculateTreasuryShareMethod(input)"
      },
      "api": {
        "summary": "The treasury share method for options and warrants: assume exercise, assume the proceeds buy back shares at the average market price, count only the net new shares. Using the period-end price instead of the average is the standard error, and it changes the answer.",
        "params": [
          {
            "name": "input",
            "type": "TreasuryShareInput",
            "required": true,
            "description": "Instrument terms with `period_application` — instruments outstanding for part of the period are weighted for that part only, not counted in full.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ metric, instrument_type, incremental_shares, dilutive, diluted_eps, … }",
          "description": "The incremental share count and the dilution determination, with every intermediate the calculation passed through."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the average market price is missing or not positive",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculateTreasuryShareMethod({\"entity_id\":\"EXAMPLE-PLC\",\"instrument_id\":\"2024-WARRANTS\",\"instrument_type\":\"WARRANT\",\"period_start\":\"2025-01-01\",\"period_end\":\"2025-12-31\",\"as_of\":\"2026-02-20T16:30:00Z\",\"accounting_framework\":\"IFRS\",\"period_application\":\"IFRS_DIRECT_PERIOD\",\"currency\":\"USD\",\"basic_control_numerator\":\"120\",\"basic_weighted_average_shares\":\"50\",\"earnings_scale\":\"1000000\",\"share_scale\":\"1000000\",\"ordinary_shares_under_instrument\":\"10\"})",
        "args": [
          {
            "value": {
              "entity_id": "EXAMPLE-PLC",
              "instrument_id": "2024-WARRANTS",
              "instrument_type": "WARRANT",
              "period_start": "2025-01-01",
              "period_end": "2025-12-31",
              "as_of": "2026-02-20T16:30:00Z",
              "accounting_framework": "IFRS",
              "period_application": "IFRS_DIRECT_PERIOD",
              "currency": "USD",
              "basic_control_numerator": "120",
              "basic_weighted_average_shares": "50",
              "earnings_scale": "1000000",
              "share_scale": "1000000",
              "ordinary_shares_under_instrument": "10"
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 51
            }
          }
        ],
        "output": {
          "metric": "treasury_share_method_options_warrants",
          "entity_id": "EXAMPLE-PLC",
          "instrument_id": "2024-WARRANTS",
          "instrument_type": "WARRANT",
          "period_start": "2025-01-01",
          "period_end": "2025-12-31",
          "as_of": "2026-02-20T16:30:00Z",
          "accounting_framework": "IFRS",
          "period_application": "IFRS_DIRECT_PERIOD",
          "currency": "USD",
          "basic_control_numerator_base": "120000000",
          "basic_weighted_average_shares_base": "50000000",
          "shares_under_instrument_base": "10000000",
          "cash_exercise_price_per_share": "15"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 53
        },
        "outputShape": "object with 53 fields: metric, entity_id, instrument_id, instrument_type, period_start, period_end, as_of, accounting_framework, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "treasury-share-bridge.svg",
            "url": "https://thefintechbuilder.com/content/d46-f02-a03/static/treasury-share-bridge.svg"
          }
        ],
        "mermaid": [
          {
            "file": "treasury-share-flow.md",
            "caption": "Treasury-share method decision flow",
            "source": "flowchart TD\n    F{\"Which accounting framework?\"} -->|IAS 33| FI[\"Use IAS 33 assumed-proceeds treatment and IFRS 2 future-service value\"]\n    F -->|US GAAP| FG[\"Use treasury stock method and average unrecognized compensation; exclude excess tax benefits\"]\n    F -->|Declared local| FO[\"Load documented local proceeds and period policy\"]\n    FI --> A[\"Receive one fixed option or warrant series\"]\n    FG --> A\n    FO --> A\n    A --> B{\"One non-contingent series, unchanged terms, complete sources?\"}\n    B -->|No| R[\"Reject incomplete contract\"]\n    B -->|Yes| P{\"Framework and period application compatible?\"}\n    P -->|No| V[\"Route to required period aggregation variant\"]\n    P -->|Yes| T[\"Weight gross shares while instrument is outstanding\"]\n    T --> E[\"Effective price = cash + permitted service + permitted tax + declared-other proceeds\"]\n    E --> M{\"Average market price exceeds effective price?\"}\n    M -->|No| X[\"Zero incremental shares; exclude\"]\n    M -->|Yes| S[\"Repurchase shares = gross weighted shares × effective price / market price\"]\n    S --> I[\"Incremental shares = gross weighted shares − repurchase shares\"]\n    I --> C[\"Candidate EPS = unchanged Basic numerator / Basic shares + incremental shares\"]\n    C --> D{\"Exact candidate below exact Basic EPS?\"}\n    D -->|Yes| Y[\"Dilutive: include standalone series\"]\n    D -->|No or equal| N[\"Antidilutive: exclude\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R01 - IAS 33 Earnings per Share",
          "title": "R01 - IAS 33 Earnings per Share",
          "author": null,
          "url": null
        },
        {
          "key": "R02 - FASB ASU 2020-06, Debt with Conversion and Other Options",
          "title": "R02 - FASB ASU 2020-06, Debt with Conversion and Other Options",
          "author": null,
          "url": null
        },
        {
          "key": "R03 - FASB ASU 2016-09, Improvements to Employee Share-Based Payment Accounting",
          "title": "R03 - FASB ASU 2016-09, Improvements to Employee Share-Based Payment Accounting",
          "author": null,
          "url": null
        },
        {
          "key": "Research reconciliation",
          "title": "Research reconciliation",
          "author": null,
          "url": null
        },
        {
          "key": "Historical evidence status",
          "title": "Historical evidence status",
          "author": null,
          "url": null
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/earnings-and-per-share-analytics/basic-and-diluted-eps/treasury-share-method-for-options-warrants/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/earnings-and-per-share-analytics/basic-and-diluted-eps/treasury-share-method-for-options-warrants/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    },
    {
      "id": "D46-F02-A04",
      "name": "Contingently Issuable Shares",
      "headline": "Current-Conditions EPS Test",
      "slug": "contingently-issuable-share-inclusion",
      "path": "earnings-and-per-share-analytics/basic-and-diluted-eps/contingently-issuable-share-inclusion",
      "taxonomy": {
        "domainId": "D46",
        "domain": "Earnings and Per-Share Analytics",
        "familyId": "D46-F02",
        "family": "Basic and Diluted EPS",
        "difficulty": 3
      },
      "import": {
        "subpath": "fintech-algorithms/earnings-and-per-share-analytics/basic-and-diluted-eps/contingently-issuable-share-inclusion",
        "entry": "calculateContingentShareInclusion",
        "params": [
          "input"
        ],
        "exports": [
          "calculateContingentShareInclusion"
        ],
        "archetype": "record-transform",
        "signature": "calculateContingentShareInclusion(input)"
      },
      "api": {
        "summary": "Decides whether shares issuable on a condition count today. The rule is that they are included from the date the condition is *satisfied*, judged as at the reporting date — not when issue is merely likely, which is where judgement creeps in.",
        "params": [
          {
            "name": "input",
            "type": "ContingentShareInput",
            "required": true,
            "description": "Agreement terms with `period_application` and the `as_of` reporting date the condition is judged against.",
            "constraints": null,
            "nulls": null,
            "default": null
          }
        ],
        "returns": {
          "type": "{ metric, agreement_id, condition_satisfied, included_shares, diluted_eps, … }",
          "description": "The inclusion decision with the condition state that drove it — a judgement that is auditable rather than embedded."
        },
        "warmup": null,
        "errors": [
          {
            "when": "the contingency condition is unrecognised",
            "behaviour": "reported as a status rather than thrown"
          }
        ],
        "complexity": {
          "time": "O(1)",
          "space": "O(1)"
        }
      },
      "example": {
        "origin": "executed",
        "verified": false,
        "source": "executed against the catalog's own test input",
        "call": "calculateContingentShareInclusion({\"entity_id\":\"SYNTH-ENTITY\",\"agreement_id\":\"CSA-2025-01\",\"period_start\":\"2025-01-01\",\"period_end\":\"2025-12-31\",\"as_of\":\"2026-02-20T12:00:00Z\",\"accounting_framework\":\"IFRS\",\"period_application\":\"IFRS_DIRECT_PERIOD\",\"currency\":\"USD\",\"basic_control_numerator\":\"120\",\"basic_weighted_average_shares\":\"50\",\"earnings_scale\":\"1000000\",\"share_scale\":\"1000000\",\"fixed_contingent_shares\":\"5\",\"agreement_date\":\"2024-07-01\"})",
        "args": [
          {
            "value": {
              "entity_id": "SYNTH-ENTITY",
              "agreement_id": "CSA-2025-01",
              "period_start": "2025-01-01",
              "period_end": "2025-12-31",
              "as_of": "2026-02-20T12:00:00Z",
              "accounting_framework": "IFRS",
              "period_application": "IFRS_DIRECT_PERIOD",
              "currency": "USD",
              "basic_control_numerator": "120",
              "basic_weighted_average_shares": "50",
              "earnings_scale": "1000000",
              "share_scale": "1000000",
              "fixed_contingent_shares": "5",
              "agreement_date": "2024-07-01"
            },
            "elided": {
              "kind": "object",
              "shown": 14,
              "total": 43
            }
          }
        ],
        "output": {
          "metric": "contingently_issuable_share_inclusion",
          "entity_id": "SYNTH-ENTITY",
          "agreement_id": "CSA-2025-01",
          "period_start": "2025-01-01",
          "period_end": "2025-12-31",
          "accounting_framework": "IFRS",
          "period_application": "IFRS_DIRECT_PERIOD",
          "legal_status": "UNRESOLVED",
          "routing_decision": "DILUTED_CURRENT_STATUS_TEST",
          "terms_effective_date": "2024-07-01",
          "knowledge_cutoff": "2026-02-20T12:00:00Z",
          "currency": "USD",
          "basic_control_numerator_base": "120000000",
          "basic_weighted_average_shares_base": "50000000"
        },
        "outputElided": {
          "kind": "object",
          "shown": 14,
          "total": 41
        },
        "outputShape": "object with 41 fields: metric, entity_id, agreement_id, period_start, period_end, accounting_framework, period_application, legal_status, …"
      },
      "verification": {
        "tier": "contract",
        "via": null
      },
      "assets": {
        "diagrams": [
          {
            "file": "contingent-share-gates.svg",
            "url": "https://thefintechbuilder.com/content/d46-f02-a04/static/contingent-share-gates.svg"
          }
        ],
        "mermaid": [
          {
            "file": "contingent-share-flow.md",
            "caption": "Contingent-share inclusion flow",
            "source": "flowchart TD\n    A[\"Validated agreement, effective terms, and point-in-time inputs\"] --> R{\"Legal state at reporting date?\"}\n    R -->|Satisfied| C[\"Route shares to Basic EPS from satisfaction date\"]\n    R -->|Cancelled| X[\"Exclude and retain cancellation evidence\"]\n    R -->|Contingently returnable| Y[\"Route to reverse-contingency analysis\"]\n    R -->|Only time remains| T[\"Route to framework-specific time or service treatment\"]\n    R -->|Unresolved substantive condition| D{\"Would every current-status condition be met if period end were contingency end?\"}\n    D -->|No| E[\"Eligible contingent shares = 0\"]\n    D -->|Yes| F{\"Direct fixed shares for little or no cash?\"}\n    F -->|No| G[\"Apply relevant option, convertible, or settlement method\"]\n    F -->|Yes| H[\"Weight from later of period start, agreement date, and effective terms\"]\n    H --> I[\"Build exact candidate with unchanged numerator\"]\n    I --> J{\"Exact candidate below exact Basic EPS?\"}\n    J -->|Yes| K[\"Include in standalone diluted-EPS candidate\"]\n    J -->|No| L[\"Exclude as antidilutive\"]"
          }
        ]
      },
      "references": [
        {
          "key": "R01",
          "title": "IAS 33 Earnings per Share, current standard page",
          "author": "IFRS Foundation",
          "url": "https://www.ifrs.org/issued-standards/list-of-standards/ias-33-earnings-per-share.html/"
        },
        {
          "key": "R02",
          "title": "IAS 33 Earnings per Share, issued standard text",
          "author": "IFRS Foundation",
          "url": "https://www.ifrs.org/content/dam/ifrs/publications/pdf-standards/english/2022/issued/part-a/ias-33-earnings-per-share.pdf?bypass=on"
        },
        {
          "key": "R03",
          "title": "FASB Statement No. 128, Earnings per Share",
          "author": "Financial Accounting Standards Board",
          "url": "https://storage.fasb.org/fas128.pdf"
        },
        {
          "key": "R04",
          "title": "CVSL response to SEC comments on contingent shares",
          "author": "CVSL Inc.; filed through the U.S. Securities and Exchange Commission",
          "url": "https://www.sec.gov/Archives/edgar/data/1403085/000110465914072781/filename1.htm"
        },
        {
          "key": "R05",
          "title": "CVSL Third Amendment to Share Exchange Agreement",
          "author": "CVSL Inc. and Rochon Capital Partners, Ltd.",
          "url": "https://www.sec.gov/Archives/edgar/data/1403085/000110465914084657/a14-25446_1ex4d1.htm"
        },
        {
          "key": "R06",
          "title": "CVSL 2014 Form 10-K",
          "author": "CVSL Inc.",
          "url": "https://www.sec.gov/Archives/edgar/data/1403085/000114420415016468/v401786_10k.htm"
        },
        {
          "key": "R07",
          "title": "Applied performance-unit disclosure",
          "author": "DXP Enterprises, Inc.",
          "url": "https://www.sec.gov/Archives/edgar/data/896156/000143774926013892/R20.htm"
        },
        {
          "key": "R08",
          "title": "Applied loss-period and PSU disclosure",
          "author": "Affirm Holdings, Inc.",
          "url": "https://www.sec.gov/Archives/edgar/data/1411579/000141157926000051/R16.htm"
        }
      ],
      "links": {
        "article": "https://thefintechbuilder.com/earnings-and-per-share-analytics/basic-and-diluted-eps/contingently-issuable-share-inclusion/",
        "repo": null,
        "source": "https://github.com/IslamBaraka90/Fintech-Algorithms-Library/blob/main/src/earnings-and-per-share-analytics/basic-and-diluted-eps/contingently-issuable-share-inclusion/impl.ts",
        "npm": "https://www.npmjs.com/package/fintech-algorithms"
      },
      "catalogLanguages": [
        "python",
        "typescript"
      ]
    }
  ]
}
